include_files(); $this->hooks(); } /** * Include files for admin * * @since 1.0.0 * @return void */ public function include_files() { if (!class_exists('\Codiepress\Suggested_Plugin')) { require_once ADVANCED_RULE_BASED_SHIPPING_PATH . 'inc/class-suggested-plugin.php'; } require_once ADVANCED_RULE_BASED_SHIPPING_PATH . 'inc/admin/class-shipping-rule-list.php'; require_once ADVANCED_RULE_BASED_SHIPPING_PATH . 'inc/admin/class-shipping-rule-table.php'; } /** * Include files for admin * * @since 1.0.0 * @return void */ public function hooks() { $this->shipping_list = new Admin\Shipping_Rule_List(); add_action('admin_menu', array($this, 'admin_menu')); add_action('admin_footer', array($this, 'add_component')); add_action('init', array($this, 'export_shipping_rules')); add_action('admin_enqueue_scripts', array($this, 'enqueue_scripts'), 100); add_action('admin_enqueue_scripts', array($this, 'register_scripts'), 1); add_action('wp_ajax_advanced_rule_based_shipping/get_select2_data', array($this, 'get_select2_data')); add_action('wp_ajax_advanced_rule_based_shipping/save_shipping_rule', array($this, 'save_shipping_rule')); add_action('wp_ajax_advanced_rule_based_shipping/import_shipping_rules', array($this, 'import_shipping_rules')); } /** * Add menu page for shipping rules * * @since 1.0.0 * @return void */ public function admin_menu() { add_menu_page( esc_html__('Shipping Rules', 'advanced-rule-based-shipping'), esc_html__('Shipping Rules', 'advanced-rule-based-shipping'), 'manage_options', 'advanced-rule-based-shipping', array($this, 'shipping_rules_screen'), "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHNoYXBlLXJlbmRlcmluZz0iZ2VvbWV0cmljUHJlY2lzaW9uIiB0ZXh0LXJlbmRlcmluZz0iZ2VvbWV0cmljUHJlY2lzaW9uIiBpbWFnZS1yZW5kZXJpbmc9Im9wdGltaXplUXVhbGl0eSIgZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIHZpZXdCb3g9IjAgMCA1MDUgNTExLjkiPjxwYXRoIGZpbGw9IiM5Y2EyYTciIGQ9Im0zMzYuMTEgMzkuODQtMTE1LjM4IDY4Ljk1IDEzNS4zOCAxOC4zOSAxMTEuMzItNjkuNDQtMTMxLjMyLTE3Ljl6bTI2LjcgMjA1LjA2YzczLjczIDAgMTMzLjUgNTkuNzcgMTMzLjUgMTMzLjUgMCA3My43My01OS43NyAxMzMuNS0xMzMuNSAxMzMuNS03My43MyAwLTEzMy40OS01OS43Ny0xMzMuNDktMTMzLjUgMC03My43MyA1OS43Ni0xMzMuNSAxMzMuNDktMTMzLjV6bS0xMS45MyA2OC41OGMtLjA1IDIuMjEuMzIgMy4yNyAyLjI0IDMuMjdoMjkuNjFjOC4zOC42NyAxNS44OSAyLjg5IDIyLjIzIDcuMTcgNC4zOSAyLjk5IDcuNjIgOC41NSAxMC4wNCAxMi40NyA0LjI5IDYuOTcgNi43MyAxNy4wNSA4LjA1IDI1LjE3LjU2IDMuNTEuODIgNi44MS4yMSA4LjMyLS4yNy43Mi0uNzIgMS4yMS0xLjI3IDEuNDMtMy4xOCAxLjI3LTYuNTYtMy4xLTguMzUtNS4yLTguNTMtOS45OC0yMC45NC0xNC4xMS0zNS41Ni0xNC44OWgtMjUuNjRjLTEuNTIuMjYtMi4wNiAxLjM4LTEuOSAzLjExdjExLjkxYy0uMDkgMy45Ny0yLjA5IDUuMzItNi4wNSAzLjk4bC0zNi40My0yOC41OS0zLjU5LTIuODItLjkyLS43MmMtMi45Mi0yLjYzLTEuNzItNy4wMi45MS05LjA5bDIuNzgtMi4xOCAzNC45Mi0yNy40OWM0LjI1LTMuMzUgOC43Mi00LjI2IDguNzIgMi45N3YxMS4xOHptMjMuODcgMTI5Ljg1Yy4wNC0yLjIyLS4zMi0zLjI5LTIuMjQtMy4yOWgtMjkuNjJjLTguMzgtLjY2LTE1Ljg5LTIuODgtMjIuMjItNy4xNy00LjQxLTIuOTktNy42Ni04LjU4LTEwLjA4LTEyLjUzLTQuMzgtNy4xNi03LjI3LTE4Ljg0LTguMzItMjcuMjEtLjMyLTIuNjYtLjM4LTUuMDEuMDgtNi4yMS4yOC0uNzEuNzQtMS4yMSAxLjMtMS40MyAzLjE3LTEuMjcgNi41NCAzLjExIDguMzMgNS4yIDguNTQgOS45OCAyMC45NSAxNC4xMSAzNS41NyAxNC44OWgyNS42NGMxLjUxLS4yNiAyLjA1LTEuMzggMS45LTMuMTF2LTExLjkxYy4wOS0zLjk2IDIuMDgtNS4zMSA2LjA1LTMuOThsMzYuNDMgMjguNTkgMy41OCAyLjgyLjkxLjcyYzIuOTQgMi42MyAxLjczIDcuMDItLjkgOS4wOWwtMi43OCAyLjE4LTM0LjkxIDI3LjQ5Yy00LjI2IDMuMzUtOC43MiA0LjI2LTguNzItMi45N3YtMTEuMTd6bS0xNjkuOTItMzE3LjItLjA5IDE0MS43MS01MS40NS0zNS4wNC01MS40NiAyOS4wNyA2LjEtMTQ4LjkxLTg4LjU0LTEyLjAzdjMxMi45OGwxNzguOTUgMjMuMTRjMi41MiA3LjA5IDUuNDcgMTMuOTggOC44NSAyMC42Mkw5LjMgNDMyLjA4Yy01LjE3LS4yMS05LjMtNC40OC05LjMtOS42OVY4OS44NmMuMjctNC4wNSAxLjg5LTYuODkgNS43Mi04LjgxTDE4Mi40Ny44NWMxLjU4LS43MiAzLjUzLTEuMDEgNS4yNi0uNzZsMzA4LjE4IDQyLjAzYzUuMDkuNTkgOC41OCA0Ljc3IDguNTggOS45OXYuMDJMNTA1IDI4MC45Yy01LjcyLTguNDYtMTUuNTctMjAuMjktMTkuOTMtMjcuNzdWNjkuNTZsLTExNS44MSA3NC45M3Y1OS44MWExNzQuNTc3IDE3NC41NzcgMCAwIDAtMTkuMzkuMzZ2LTU4LjgybC0xNDUuMDQtMTkuNzF6bS04MS41Mi0zMC41OCAxMTIuMTctNjkuNDMtNDcuNTgtNi40OUw0NC4yNCA4NC44bDc5LjA3IDEwLjc1eiIvPjwvc3ZnPg==", 55 ); $shipping_rule_menu = add_submenu_page( 'advanced-rule-based-shipping', esc_html__('Advanced Shipping Rules', 'advanced-rule-based-shipping'), esc_html__('All Rules', 'advanced-rule-based-shipping'), 'manage_options', 'advanced-rule-based-shipping', array($this, 'shipping_rules_screen'), ); if (!isset($_GET['id'])) { add_action("load-$shipping_rule_menu", array($this->shipping_list, 'screen_option')); } add_submenu_page( 'advanced-rule-based-shipping', esc_html__('Edit Shipping Rules', 'advanced-rule-based-shipping'), esc_html__('Add new rule', 'advanced-rule-based-shipping'), 'manage_options', 'advanced-rule-based-shipping&id=new', array($this, 'shipping_rules_screen'), ); } /** * Save shipping rule * * @since 1.0.0 * @return void */ public function save_shipping_rule() { check_ajax_referer('_nonce_shipping_rule_form'); $shipping_rule_id = 0; if (isset($_POST['id'])) { $shipping_rule_id = absint($_POST['id']); } $shipping_rule = Shipping_Rule::get($shipping_rule_id); if (isset($_POST['title'])) { $shipping_rule->title = wp_unslash($_POST['title']); } if (isset($_POST['rules'])) { $rules = json_decode(wp_unslash($_POST['rules']), true); if (is_array($rules)) { $shipping_rule->set_rules($rules); } } if (isset($_POST['settings'])) { $settings = json_decode(wp_unslash($_POST['settings']), true); if (is_array($settings)) { $shipping_rule->settings = $settings; } } $post_id = $shipping_rule->save(); if ($post_id > 0) { wp_send_json_success(array( 'redirect' => !$shipping_rule->exists(), 'redirect_url' => add_query_arg('id', $post_id, admin_url('admin.php?page=advanced-rule-based-shipping')) )); } wp_send_json_error(); } /** * Register styles and scripts * * @since 1.0.0 * @return void */ public function register_scripts() { if (defined('CODIEPRESS_DEVELOPMENT')) { wp_register_script('advanced-rule-based-shipping-vue', ADVANCED_RULE_BASED_SHIPPING_URI . 'assets/vue.js', [], '3.5.12', true); } else { wp_register_script('advanced-rule-based-shipping-vue', ADVANCED_RULE_BASED_SHIPPING_URI . 'assets/vue.min.js', [], '3.5.12', true); } } /** * Enqueue script on backend * * @since 1.0.0 * @return void */ public function enqueue_scripts() { if (get_current_screen()->id !== 'toplevel_page_advanced-rule-based-shipping') { return; } wp_register_script('sortable', ADVANCED_RULE_BASED_SHIPPING_URI . 'assets/sortable.min.js', [], '1.15.2', true); wp_register_script('vue-sortable', ADVANCED_RULE_BASED_SHIPPING_URI . 'assets/vue-sortable.js', ['advanced-rule-based-shipping-vue', 'sortable'], '1.0.7', true); $wc_countries = new \WC_Countries(); wp_register_style('select2', ADVANCED_RULE_BASED_SHIPPING_URI . 'assets/select2.min.css'); wp_enqueue_style('advanced-rule-based-shipping', ADVANCED_RULE_BASED_SHIPPING_URI . 'assets/admin.min.css', ['select2'], ADVANCED_RULE_BASED_SHIPPING_VERSION); do_action('advanced_rule_based_shipping/admin_enqueue_scripts'); wp_enqueue_script('advanced-rule-based-shipping', ADVANCED_RULE_BASED_SHIPPING_URI . 'assets/admin.min.js', ['jquery', 'advanced-rule-based-shipping-vue', 'select2', 'vue-sortable', 'wp-i18n'], ADVANCED_RULE_BASED_SHIPPING_VERSION, true); wp_localize_script('advanced-rule-based-shipping', 'advanced_rule_based_shipping_admin', array( 'ajax_url' => admin_url('admin-ajax.php'), 'countries' => $wc_countries->get_countries(), 'rule_values' => Utils::get_rule_values(), 'rule_helper_models' => Utils::rule_helper_models(), 'condition_values' => Utils::get_condition_values(), 'condition_ui_values' => Utils::get_condition_ui_values(), 'shipping_cost_types' => Utils::get_shipping_cost_types(), 'shipping_rule_settings' => Utils::get_shipping_rule_settings(), 'nonce_select2_data' => wp_create_nonce('_nonce_advanced_rule_based_shipping/get_select2_data'), )); } /** * Admin screen of plugin * * @since 1.0.0 * @return void */ public function shipping_rules_screen() { if (isset($_GET['id'])) { $shipping_rule = Shipping_Rule::get(absint($_GET['id'])); require_once ADVANCED_RULE_BASED_SHIPPING_PATH . 'templates/shipping-rules-edit.php'; } else { $this->shipping_list->list_page(); } } /** * Add vuejs component * * @since 1.0.0 * @return void */ public function add_component() { if (get_current_screen()->id !== 'toplevel_page_advanced-rule-based-shipping') { return; } echo ''; echo ''; } /** * Get select2 dropdown data * * @since 1.0.0 * @return void */ public function get_select2_data() { check_ajax_referer('_nonce_advanced_rule_based_shipping/get_select2_data', 'security'); $results = $search_args = array(); $search_term = !empty($_POST['term']) ? sanitize_text_field($_POST['term']) : ''; $query_type = !empty($_POST['type']) ? sanitize_text_field($_POST['type']) : ''; $query_type = explode(':', $query_type); $object_type = !empty($query_type[0]) ? $query_type[0] : ''; $object_slug = !empty($query_type[1]) ? $query_type[1] : ''; if ('taxonomy' == $object_type && !empty($object_slug)) { $object_slug = str_replace('___', '-', $object_slug); $search_args = array('hide_empty' => false, 'taxonomy' => $object_slug); if (!empty($search_term)) { $search_args['search'] = $search_term; } if (isset($_POST['ids']) && is_array($_POST['ids'])) { $search_args['include'] = array_map('absint', $_POST['ids']); } $terms = get_terms($search_args); $results = array_map(function ($term) { return array('id' => $term->term_id, 'name' => $term->name); }, $terms); } if ('users' == $object_type) { if (!empty($search_term)) { $search_args['search'] = $search_term; } if (isset($_POST['ids']) && is_array($_POST['ids'])) { $search_args['include'] = array_map('absint', $_POST['ids']); } $get_users = get_users($search_args); $results = array_map(function ($user) { return array('id' => $user->id, 'name' => $user->display_name); }, $get_users); } if ('states' == $object_type) { if (empty($_POST['country'])) { wp_send_json_error(array( 'error' => esc_html__('Country Missing', 'advanced-rule-based-shipping') )); } $wc_countries = new \WC_Countries(); $states = $wc_countries->get_states(sanitize_text_field($_POST['country'])); if (!empty($search_term)) { $states = array_filter($states, function ($state) use ($search_term) { return stripos($state, $search_term) !== false; }); } if (!is_array($states)) { $states = []; } $results = array_map(function ($state, $code) { return array('id' => $code, 'name' => html_entity_decode($state)); }, $states, array_keys($states)); } if ('post_type' == $object_type && !empty($object_slug)) { $search_args['post_type'] = $object_slug; if (!empty($search_term)) { $search_args['s'] = $search_term; } if (isset($_POST['ids']) && is_array($_POST['ids'])) { $search_args['post__in'] = array_map('absint', $_POST['ids']); } $posts = get_posts($search_args); $results = array_map(function ($item) { return array('id' => $item->ID, 'name' => $item->post_title); }, $posts); } do_action('advanced_rule_based_shipping/get_select2_data', $query_type, $search_term); wp_send_json_success($results); } /** * Export all shipping rules * * @since 1.1.1 * @return void */ public function export_shipping_rules() { if (!isset($_GET['export']) || !isset($_GET['nonce'])) { return; } if (!wp_verify_nonce(wp_unslash($_GET['nonce']), '_nonce_advanced_rule_based_shipping_rule_export')) { return; } $shipping_rules = get_posts(array( 'numberposts' => -1, 'post_status' => 'any', 'post_type' => Shipping_Rule::POST_TYPE, )); $shipping_rules = array_map(function ($item) { return (new Shipping_Rule($item))->get_export_data(); }, $shipping_rules); $json_data = wp_json_encode($shipping_rules, JSON_PRETTY_PRINT); header('Content-Type: application/json'); header('Content-Disposition: attachment; filename="shipping-rules-' . time() . '.json"'); header('Content-Length: ' . strlen($json_data)); header('Cache-Control: no-cache, must-revalidate'); header('Expires: 0'); echo $json_data; exit; } /** * Import shipping rules from json file * * @since 1.1.1 * @return void */ public function import_shipping_rules() { if (!isset($_POST['_wpnonce'])) { return; } if (!wp_verify_nonce(wp_unslash($_POST['_wpnonce']), '_nonce_advanced_rule_based_shipping_rules_import')) { return; } if (!isset($_FILES['rules_file'])) { wp_send_json_error(array('message' => esc_html__('Import failed. Please select a valid JSON file.', 'advanced-rule-based-shipping'))); } $file = $_FILES['rules_file']; if ('application/json' !== $file['type']) { wp_send_json_error(array('message' => esc_html__('Import failed. Please select a valid JSON file.', 'advanced-rule-based-shipping'))); } $shipping_rules = json_decode(file_get_contents($file['tmp_name']), true); if (!is_array($shipping_rules)) { wp_send_json_error(array('message' => esc_html__('No valid data found for shipping rules.', 'advanced-rule-based-shipping'))); } array_walk($shipping_rules, function ($shipping_rule) { $new_shipping_rule = new Shipping_Rule($shipping_rule); array_walk($new_shipping_rule->rules, function (&$rule) { $rule['conditions'] = array_map(function ($condition) { if (isset($condition['cart_product_shipping_class']) && is_array($condition['cart_product_shipping_class'])) { $shipping_class_ids = array(); foreach ($condition['cart_product_shipping_class'] as $shipping_class_slug) { $term = get_term_by('slug', $shipping_class_slug, 'product_shipping_class'); if (!is_wp_error($term)) { $shipping_class_ids[] = $term->term_id; } } $condition['cart_product_shipping_class'] = $shipping_class_ids; } if (isset($condition['cart_products_product_shipping_class']) && is_array($condition['cart_products_product_shipping_class'])) { $shipping_class_ids = array(); foreach ($condition['cart_products_product_shipping_class'] as $shipping_class_slug) { $term = get_term_by('slug', $shipping_class_slug, 'product_shipping_class'); if (!is_wp_error($term)) { $shipping_class_slugs[] = $term->term_id; } } $condition['cart_products_product_shipping_class'] = $shipping_class_slugs; } return $condition; }, $rule['conditions']); }); $rule_id = $new_shipping_rule->save(); if (isset($shipping_rule['meta_input']) && is_array($shipping_rule['meta_input']) && $rule_id) { foreach ($shipping_rule['meta_input'] as $meta_key => $value) { update_post_meta($rule_id, $meta_key, $value); } } }); wp_send_json_success(array('message' => esc_html__('All shipping rules have been successfully imported. Please wait while the page reloads.', 'advanced-rule-based-shipping'))); } }