<?php if (!defined('ABSPATH')) die('No direct access allowed'); final class WOOF_EXT_TURBO_MODE extends WOOF_EXT { public $type = 'application'; public $folder_name = 'turbo_mode'; //should be defined!! //+++ public $cron = array(); public $cron_obj = null; protected $crone_hook = "woof_turbo_do_recreate_file"; protected $crone_filter = "woof_turbo_get_cron_ids"; protected $enable = 0; public $wp_cron_period = 'weekly'; //+++ public $tax_conditional = ''; public $tax_serch_data = array(); protected $dir_path = ""; public $dir_link = ""; protected $file = null; protected $storing = 0; protected $attr_taxonomies = array(); //+++ public function __construct() { parent::__construct(); require_once $this->get_ext_path() . DIRECTORY_SEPARATOR . "helpers" . DIRECTORY_SEPARATOR . "file_helper.php"; require_once $this->get_ext_path() . DIRECTORY_SEPARATOR . "helpers" . DIRECTORY_SEPARATOR . "cron_helper.php"; $path = ""; $path = $this->get_ext_path() . 'data' . DIRECTORY_SEPARATOR; $link = ""; $link = $this->get_ext_link() . 'data' . DIRECTORY_SEPARATOR; if (isset($this->woof_settings['woof_turbo_mode']['storing']) AND!empty($this->woof_settings['woof_turbo_mode']['storing'])) { $this->storing = $this->woof_settings['woof_turbo_mode']['storing']; } if ($this->storing == 0) { $path = WOOF_FILE_GENERATOR_HELPER::get_full_path_dir(); $link = WOOF_FILE_GENERATOR_HELPER::get_full_link_dir(); } $this->dir_path = $path; $this->dir_link = $link; //*** if (isset($this->woof_settings['woof_turbo_mode']['wp_cron_period']) AND!empty($this->woof_settings['woof_turbo_mode']['wp_cron_period'])) { $this->wp_cron_period = $this->woof_settings['woof_turbo_mode']['wp_cron_period']; } if (isset($this->woof_settings['woof_turbo_mode']['enable'])) { $this->enable = $this->woof_settings['woof_turbo_mode']['enable']; } if ($this->enable) { // reset standart woof setting To not show the counter twice update_option('woof_show_count', 0); update_option('woof_hide_dynamic_empty_pos', 0); update_option('woof_show_count_dynamic', 0); //activate ajax mode update_option('woof_try_ajax', 1); } add_action($this->crone_hook, array($this, 'do_recreate_file'), 10, 3); add_filter($this->crone_filter, array($this, 'get_cron_ids'), 10, 2); $this->cron_obj = new PN_WP_CRON_WOOF_TURBO_MODE('woof_turbo_init_wpcrone_', $this->crone_hook, $this->crone_filter); add_action('init', array($this, 'init_crone'), 100000); add_filter('woof_set_shortcode_taxonomyattr_behaviour', array($this, 'check_shortcode_att_taxonomies')); $this->init(); } public function get_ext_path() { return plugin_dir_path(__FILE__); } public function get_ext_override_path() { return get_stylesheet_directory() . DIRECTORY_SEPARATOR . "woof" . DIRECTORY_SEPARATOR . "ext" . DIRECTORY_SEPARATOR . $this->folder_name . DIRECTORY_SEPARATOR; } public function get_ext_link() { return plugin_dir_url(__FILE__); } public function init() { add_action('woof_print_applications_tabs_anvanced', array($this, 'woof_print_applications_tabs'), 10, 1); add_action('woof_print_applications_tabs_content_advanced', array($this, 'woof_print_applications_tabs_content'), 10, 1); if ($this->enable) { self::$includes['css']['woof_' . $this->folder_name . '_html_items'] = $this->get_ext_link() . 'css/' . $this->folder_name . '.css'; add_action('wp_footer', array($this, 'wp_footer'), 12); add_filter('woof_print_content_before_search_form', array($this, 'add_overlay_buffer')); add_filter('wc_settings_tab_woof_settings', array($this, 'change_options')); } //ajax add_action('wp_ajax_woof_turbo_mode_update_file', array($this, 'create_data_search_files')); add_action('wp_ajax_nopriv_woof_turbo_mode_update_file', array($this, 'create_data_search_files')); } public function create_data_search_files_when_init() { add_action('init', array($this, 'create_data_search_files')); } public function add_overlay_buffer($txt) { $txt = "<div class='woof_turbo_mode_overlay'></div>" . $txt; return $txt; } public function wp_footer() { wp_enqueue_script('woof_alasql', WOOF_LINK . "ext/quick_search/js/alasql/alasql.min.js", array(), WOOF_VERSION); wp_enqueue_script('woof_turbo_mode', $this->get_ext_link() . 'js/turbo_mode.js', array(), WOOF_VERSION); $link = ''; $curr_lang = 'xxx'; if (class_exists('SitePress')) { //$curr_lang = ICL_LANGUAGE_CODE; $curr_lang = apply_filters( 'wpml_current_language', NULL ); } $curr_tax = array(); $tax = woof()->get_really_current_term(); if ($tax) { $curr_tax = array( "tax" => $tax->taxonomy, "slug" => $tax->slug ); } $link = $this->dir_link . 'data_0000_' . $curr_lang . '.json'; $dynamic_recount = get_option('woof_show_count_dynamic_turbo_mode', 0); if ($dynamic_recount == 2 AND wp_is_mobile()) { $dynamic_recount = 0; } elseif ($dynamic_recount == 2 AND!wp_is_mobile()) { $dynamic_recount = 1; } $text_data = array( 'link' => $link, 'pre_load' => 1, 'sale_ids' => wc_get_product_ids_on_sale(), 'settings' => $this->woof_settings, 'current_tax' => $curr_tax, 'additional_tax' => $this->attr_taxonomies, 'show_count' => get_option('woof_show_count_turbo_mode', 0), 'hide_count' => isset($this->woof_settings['hide_terms_count_txt']) ? $this->woof_settings['hide_terms_count_txt'] : 0, 'hide_empty_term' => get_option('woof_hide_dynamic_empty_pos_turbo_mode', 0), 'dynamic_recount' => $dynamic_recount, ); wp_localize_script('woof_turbo_mode', 'woof_tm_data', $text_data); } public function woof_print_applications_tabs() { ?> <li> <a href="#tabs-turbo-mode"> <span class="icon-gauge"></span> <span><?php esc_html_e("Turbo mode", 'woocommerce-products-filter') ?></span> </a> </li> <?php } public function woof_print_applications_tabs_content() { $txt_js = ""; ob_start(); ?> var woof_turbo_creating = "<?php esc_html_e('Creating', 'woocommerce-products-filter') ?>"; var woof_turbo_products = "<?php esc_html_e('Products and Variants', 'woocommerce-products-filter') ?>"; <?php $txt_js = ob_get_clean(); wp_enqueue_script('woof_turbo_mode_admin_', $this->get_ext_link() . 'js/admin.js', array(), WOOF_VERSION); wp_enqueue_style('woof_turbo_mode_admin_css', $this->get_ext_link() . 'css/admin.css', array(), WOOF_VERSION); wp_add_inline_script('woof_turbo_mode_admin_', $txt_js, 'before'); //*** $data = array(); $data['woof_settings'] = $this->woof_settings; woof()->render_html_e($this->get_ext_path() . 'views/tabs_content.php', $data); } public function create_data_search_files() { $tax_query = array(); $start = 0; $step = 10; $do = true; $id = "0000"; if (isset($_POST['turbo_mode_start'])) { $start = intval($_POST['turbo_mode_start']); } if ($start == 0 OR $start == null) { if ($this->storing) { $this->delete_all_files(); } else { WOOF_FILE_GENERATOR_HELPER::delete_file_all_files(); } } $tax_query = $this->_expand_additional_taxes_string($this->tax_conditional, $tax_query); $tax_query = woof()->product_visibility_not_in($tax_query, woof()->generate_visibility_keys(true)); $args = array( 'post_type' => array('product', 'product_variation'), 'post_status' => 'publish', 'tax_query' => $tax_query, 'offset' => $start, 'posts_per_page' => $step, 'fields' => 'ids', 'cache_results' => false, //'no_found_rows'=>false, 'update_post_meta_cache' => false, 'update_post_term_cache' => false, 'orderby' => 'ID', 'order' => 'DESC', ); if (class_exists('SitePress')) { global $sitepress; $default_lang = $sitepress->get_default_language(); // Get WPML default language $current_lang = $sitepress->get_current_language(); //save current language $sitepress->switch_lang($default_lang); } $start += $step; $limit = apply_filters("woof_turbo_mode_products_limit", 15000); if ($start > $limit) { // limiting the number of products $do = false; } $product_ids = new WP_Query($args); if ($product_ids->found_posts < 1) { $do = false; } if ($do) { $this->push_products_data($product_ids, $id); } else { $start = -1; } $result = array('total' => $start, ); exit(json_encode($result)); } public function push_products_data($product_ids, $id) { $langs = $this->get_all_lang_wpml(); $posts = array(); $posts_data = array(); $ids = array(); if (is_object($product_ids)) { $ids = $product_ids->posts; } elseif (is_array($product_ids)) { $ids = $product_ids; } if ($langs) { foreach ($langs as $lang) { $posts_data = array(); foreach ($ids as $post) { $posts_lang = $this->get_post_id_by_lang($post, $lang['language_code']); if ($posts_lang) { $posts_data[] = $this->get_data_by_id($posts_lang, $lang['language_code']); } } $this->push_data_into_file($posts_data, $id, $lang['language_code']); } } else { foreach ($ids as $post) { //$posts[]=$post->ID; $posts_data[] = $this->get_data_by_id($post); } $this->push_data_into_file($posts_data, $id); } } public function get_data_by_id($id, $lang = 'xxx') { if (!$id OR $id < 1) { return array(); } if (class_exists('SitePress') AND $lang != 'xxx') { global $sitepress; $sitepress->switch_lang($lang ); } $product = wc_get_product($id); if (!$product) { return array(); } $author = 0; $post_data = get_post($id); if ($post_data) { $author = $post_data->post_author; } $data = array(); $data['id'] = $id; $data['title'] = $product->get_name(); $data['sku'] = $product->get_sku(); $data['price'] = $this->get_all_prices($product); $data['author'] = $author; $data['meta_data'] = array(); $data['taxonomies'] = array(); $data['parent'] = ""; $data['stock'] = $product->get_stock_status(); if ($product->get_type() == "variation") { $data['parent'] = $product->get_parent_id(); } else { $data['parent'] = -1; } $all_taxonomies = woof()->get_taxonomies(); if ($product->get_type() == "variation") { $var_attributes = $product->get_variation_attributes(); foreach ($var_attributes as $key_attr => $val) { $key = str_replace("attribute_", "", $key_attr); $data['taxonomies'][$key][] = html_entity_decode($val); } } else { if (true) { // if you want search in all taxonomies by additional filters( ignore $this->tax_serch_data ) foreach ($all_taxonomies as $key_slug => $val_tax) { $_terms = get_the_terms($id, $key_slug); if (!is_array($_terms)) { continue; } foreach ($_terms as $term) { $data['taxonomies'][$key_slug][] = html_entity_decode($term->slug); } } } } $data['meta_data'] = $this->get_meta_data_by_id($id); return $data; } public function get_meta_data_by_id($id) { $meta_data = array(); if (class_exists('WOOF_META_FILTER')) { $meta_fields = []; if (isset($this->woof_settings['meta_filter'])) { $meta_fields = $this->woof_settings['meta_filter']; } $meta_fields['_stock_status'] = array('meta_key' => '_stock_status'); $meta_fields['_wc_average_rating'] = array('meta_key' => '_wc_average_rating'); if (!empty($meta_fields)) { foreach ($meta_fields as $key => $meta) { if ($meta['meta_key'] == "__META_KEY__") { continue; } $meta = get_post_meta($id, $meta['meta_key'], true); if ($meta) { $meta_data[$key] = $meta; } } } } return $meta_data; } public function get_all_prices($product) { if (!$product) { return array(); } $include_tax = false; if (wc_tax_enabled() && 'incl' === get_option('woocommerce_tax_display_shop') && !wc_prices_include_tax()) { $include_tax = true; } if (class_exists('WOOCS')) { global $WOOCS; $def_currency = $WOOCS->default_currency; if ($def_currency != $WOOCS->current_currency) { $WOOCS->current_currency = $def_currency; $WOOCS->storage->set_val('woocs_current_currency', $def_currency); } } //$product = wc_get_product($id); $prices = array(); if ($product->is_type('variable')) { $available_variations = $product->get_children(); foreach ($available_variations as $var_id) { $var_product = wc_get_product($var_id); $regular_v = $var_product->get_regular_price(); $sale_v = $var_product->get_sale_price(); if ($include_tax) { $regular_v = wc_get_price_including_tax($var_product, array('price' => $regular_v)); $sale_v = wc_get_price_including_tax($var_product, array('price' => $sale_v)); } $prices[] = array( 'regular' => $regular_v, 'sale' => $sale_v, ); } } else { $regular = $product->get_regular_price(); $sale = $product->get_sale_price(); if ($include_tax) { $regular = wc_get_price_including_tax($product, array('price' => $regular)); $sale = wc_get_price_including_tax($product, array('price' => $sale)); } $prices[] = array( 'regular' => $regular, 'sale' => $sale, ); } return $prices; } // wpml compatibility public function get_all_lang_wpml() { if (class_exists('SitePress')) { return $langs = icl_get_languages('skip_missing=0&orderby=KEY&order=DIR&link_empty_to=str'); } return false; } public function check_shortcode_att_taxonomies($taxonomies) { $this->attr_taxonomies = array(); if (!empty($taxonomies)) { $t = explode('+', $taxonomies); if (!empty($t) AND is_array($t)) { foreach ($t as $string) { $tmp = explode(':', $string); $tax_slug = $tmp[0]; $tax_terms = explode(',', $tmp[1]); $slugs = array(); foreach ($tax_terms as $term_id) { $term = get_term(intval($term_id), $tax_slug); if (is_object($term)) { $slugs[] = $term->slug; } } //*** if (!empty($slugs)) { $this->attr_taxonomies[] = array( 'tax' => $tax_slug, 'terms' => implode(',', $slugs) ); } } } } return $taxonomies; } public function get_post_id_by_lang($post_id, $lang_code, $type = 'product') { if (class_exists('SitePress')) { return icl_object_id($post_id, $type, false, $lang_code); } return false; } // +++ public function woof_quick_wpcron_init($reset = false) { $hook = 'woof_quick_search_wpcron'; if ($reset) { $this->cron->remove($hook); return; } if ($this->cron_system === 0 AND $this->wp_cron_period != -1) {//wp cron if (!$this->cron->is_attached($hook, $this->get_woof_cron_schedules($this->wp_cron_period))) { $this->cron->attach($hook, time(), $this->get_woof_cron_schedules($this->wp_cron_period)); } $this->cron->process(); } } // File works private function delete_all_files() { $path = $this->dir_path . DIRECTORY_SEPARATOR; if ($handle = opendir($path)) { while (false !== ($file = readdir($handle))) if ($file != "." && $file != "..") unlink($path . $file); closedir($handle); } } private function push_data_into_file($data, $id = '0000', $lang = 'xxx') { $file = $this->dir_path . '/data_' . $id . '_' . $lang . '.json'; try { clearstatcache(true, $file); } catch (Exception $e) { } //*** if ($fh = fopen($file, 'a+')) { if ($fh) { $contents = ''; $file_size = filesize($file); if ($file_size > 0) { $contents = fread($fh, $file_size); } //*** if (!empty($contents)) { $contents = json_decode(trim($contents), true); if (json_last_error() === JSON_ERROR_NONE) { $data = array_merge($contents, $data); } } //*** ftruncate($fh, 0); fwrite($fh, json_encode($data)); fclose($fh); return true; } } return false; } private function _expand_additional_taxes_string($additional_taxes, $res = array()) { if (!empty($additional_taxes)) { $t = explode('+', $additional_taxes); if (!empty($t) AND is_array($t)) { foreach ($t as $string) { $tmp = explode(':', $string); $tax_slug = $tmp[0]; $tax_terms = explode(',', $tmp[1]); $slugs = array(); foreach ($tax_terms as $term_id) { $term = get_term(intval($term_id), $tax_slug); if (is_object($term)) { $slugs[] = $term->slug; } } //*** if (!empty($slugs)) { $res[] = array( 'taxonomy' => $tax_slug, 'field' => 'slug', //id 'terms' => $slugs ); } } } } return $res; } public function optimize_url($url) { $site_url = get_site_url(); return str_replace($site_url, "", $url); } public function change_options($options) { foreach ($options as &$item) { if (isset($item['id']) AND ( $item['id'] == "woof_show_count_dynamic" OR $item['id'] == "woof_show_count" OR $item['id'] == "woof_hide_dynamic_empty_pos")) { if ($item['id'] == "woof_show_count_dynamic") { $item["options"] = array( 0 => esc_html__('No', 'woocommerce-products-filter'), 1 => esc_html__('Yes, for all devices', 'woocommerce-products-filter'), 2 => esc_html__('Yes, only for PC', 'woocommerce-products-filter') ); } $item['id'] .= "_turbo_mode"; } } return $options; } // CRON public function get_woof_cron_schedules($key = '') { $schedules = array( 'daily' => DAY_IN_SECONDS, 'weekly' => WEEK_IN_SECONDS, 'twicemonthly' => WEEK_IN_SECONDS * 2, 'month' => WEEK_IN_SECONDS * 4, 'min1' => MINUTE_IN_SECONDS, 'no' => -1 ); if (empty($key)) { $key = 'weekly'; } if (isset($schedules[$key])) { return $schedules[$key]; } return -1; } public function init_crone() { $id = "0000"; $cron = $this->get_woof_cron_schedules($this->wp_cron_period); if ($cron != -1 AND $cron) { if (!$this->cron_obj->is_attached($id, $cron)) { $this->cron_obj->attach($id, time(), $cron); } } else { $this->cron_obj->remove($id); } $this->cron_obj->process(); } public function get_cron_ids($ids, $id) { $tax_query = array(); $tax_query = $this->_expand_additional_taxes_string($this->tax_conditional, $tax_query); $tax_query = woof()->product_visibility_not_in($tax_query, woof()->generate_visibility_keys(true)); $args = array( 'post_type' => array('product', 'product_variation'), 'post_status' => 'publish', 'tax_query' => $tax_query, 'posts_per_page' => -1, //'posts_per_page' => 12, 'fields' => 'ids', 'cache_results' => false, //'no_found_rows'=>false, 'update_post_meta_cache' => false, 'update_post_term_cache' => false, 'orderby' => 'ID', 'order' => 'DESC', ); if (class_exists('SitePress')) { global $sitepress; $default_lang = $sitepress->get_default_language(); // Get WPML default language $current_lang = $sitepress->get_current_language(); //save current language $sitepress->switch_lang($default_lang); } $product_ids = new WP_Query($args); if ($product_ids->found_posts > 0) { return array_unique($product_ids->posts); } else { return array(); } } public function do_recreate_file($id, $ids, $is_end) { if (count($ids) < 1 OR $is_end) { $dir_path = $this->dir_path; $langs = $this->get_all_lang_wpml(); if ($langs) { foreach ($langs as $lang) { if (file_exists($dir_path . 'data_' . $id . "_temp_" . $lang['language_code'] . ".json")) { rename($dir_path . 'data_' . $id . "_temp_" . $lang['language_code'] . ".json", $dir_path . 'data_' . $id . "_" . $lang['language_code'] . ".json"); } } } else { if (file_exists($dir_path . 'data_' . $id . "_temp_xxx.json")) { rename($dir_path . 'data_' . $id . "_temp_xxx.json", $dir_path . 'data_' . $id . "_xxx.json"); } } } else { $this->push_products_data($ids, $id . "_temp"); } } } WOOF_EXT::$includes['applications']['turbo_mode'] = new WOOF_EXT_TURBO_MODE();