<?php class WoofiltersControllerWpf extends ControllerWpf { protected $_code = 'woofilters'; protected function _prepareTextLikeSearch( $val ) { $query = '(title LIKE "%' . $val . '%"'; if (is_numeric($val)) { $query .= ' OR id LIKE "%' . (int) $val . '%"'; } $query .= ')'; return $query; } public function _prepareListForTbl( $data ) { foreach ($data as $key => $row) { $id = $row['id']; $shortcode = '[' . WPF_SHORTCODE . ' id=' . $id . ']'; $titleUrl = '<a href="' . esc_url($this->getModule()->getEditLink( $id )) . '">' . esc_html($row['title']) . ' <i class="fa fa-fw fa-pencil"></i></a> <a data-filter-id="' . $id . '" class="wpfDuplicateFilter" href="" title="' . esc_attr__('Duplicate filter', 'woo-product-filter') . '"><i class="fa fa-fw fa-clone"></i></a>'; $data[$key]['shortcode'] = $shortcode; $data[$key]['title'] = DispatcherWpf::applyFilters('prepareFilterListTitle', $titleUrl, $row); } return $data; } public function drawFilterAjax() { $res = new ResponseWpf(); $data = ReqWpf::get('post'); if (isset($data) && $data) { $isPro = FrameWpf::_()->isPro(); if (!empty($data['settings']['js_editor'])) { $data['settings']['js_editor'] = ''; } if (!empty($data['settings']['filters']['order'])) { $metaKeys = $this->getDataFilterMetaKeys(stripcslashes($data['settings']['filters']['order'])); if (count($metaKeys) > 0) { FrameWpf::_()->getModule('meta')->calcNeededMetaValues(); } } $html = FrameWpf::_()->getModule('woofilters')->getView()->renderHtml($data); $html .= '<script type="text/javascript">window.wpfFrontendPage.init();' . ( $isPro ? 'window.wpfFrontendPage.eventsFrontendPro();' : '' ) . '</script>'; $res->setHtml($html); } else { $res->pushError($this->getModule('woofilters')->getErrors()); } $res->ajaxExec(); } public function save() { if ( is_plugin_active( 'litespeed-cache/litespeed-cache.php' ) ) { do_action( 'litespeed_purge_all' ); } if ( is_plugin_active( 'wp-rocket/wp-rocket.php' ) && function_exists( 'rocket_clean_domain' ) ) { if (FrameWpf::_()->getModule( 'options' )->get( 'disable_clean_rocket_cache' ) != 1) { rocket_clean_domain(); } } check_ajax_referer('wpf-save-nonce', 'wpfNonce'); if (!current_user_can('manage_options')) { wp_die(); } $res = new ResponseWpf(); $id = $this->getModel('woofilters')->save(ReqWpf::get('post')); if ( false != $id ) { $res->addMessage(esc_html__('Done', 'woo-product-filter')); $res->addData('edit_link', $this->getModule()->getEditLink( $id )); $filter = $this->getModel('woofilters')->getById($id); $settings = unserialize($filter['setting_data']); $res->addData('filter', $filter); $res->addData('filterSettings', $settings); } else { $res->pushError ($this->getModel('woofilters')->getErrors()); } return $res->ajaxExec(); } public function deleteByID() { check_ajax_referer('wpf-save-nonce', 'wpfNonce'); if (!current_user_can('manage_options')) { wp_die(); } $res = new ResponseWpf(); if ($this->getModel('woofilters')->delete(ReqWpf::get('post')) != false) { $res->addMessage(esc_html__('Done', 'woo-product-filter')); } else { $res->pushError($this->getModel('woofilters')->getErrors()); } return $res->ajaxExec(); } public function createTable() { check_ajax_referer('wpf-save-nonce', 'wpfNonce'); if (!current_user_can('manage_options')) { wp_die(); } $res = new ResponseWpf(); $id = $this->getModel('woofilters')->save(ReqWpf::get('post')); if ( false != $id ) { $res->addMessage(esc_html__('Done', 'woo-product-filter')); $res->addData('edit_link', $this->getModule()->getEditLink( $id )); $filter = $this->getModel('woofilters')->getById($id); $settings = unserialize($filter['setting_data']); $res->addData('filter', $filter); $res->addData('filterSettings', $settings); } else { $res->pushError ($this->getModel('woofilters')->getErrors()); } return $res->ajaxExec(); } public function filtersFrontend() { $res = new ResponseWpf(); $params = ReqWpf::get('post'); $filtersDataBackend = UtilsWpf::jsonDecode(stripslashes($params['filtersDataBackend'])); $queryvars = UtilsWpf::jsonDecode(stripslashes($params['queryvars'])); $filterSettings = UtilsWpf::jsonDecode(stripslashes($params['filterSettings'])); $generalSettings = UtilsWpf::jsonDecode(stripslashes($params['generalSettings'])); $woocommerceSettings = UtilsWpf::jsonDecode(stripslashes($params['woocommerceSettings'])); $shortcodeAttr = isset($params['shortcodeAttr']) ? UtilsWpf::jsonDecode(stripslashes($params['shortcodeAttr'])) : array(); $curUrl = $params['currenturl']; $queryvars['posts_per_page'] = isset($filterSettings['count_product_shop']) && !empty($filterSettings['count_product_shop']) ? $filterSettings['count_product_shop'] : $queryvars['posts_per_page']; $use_category_filtration = isset($filterSettings['use_category_filtration']) ? $filterSettings['use_category_filtration'] : 1; $onlyStatistics = isset($params['only_statistics']); $onlyFilterRecount = $onlyStatistics || isset($params['only_recound']); $synchroFilterId = !empty($params['synchro_filter_id']) ? $params['synchro_filter_id'] : ''; if ($onlyStatistics) { $filterSettings['only_have_found'] = true; $filterSettings['filter_recount'] = 0; } foreach ($filtersDataBackend as $key => $filteringSettings) { if ('wpfCategory' == $filteringSettings['id']) { $filterOrder = array_search($filteringSettings['uniqId'], array_column($generalSettings, 'uniqId')); if (!empty($filterOrder)) { $logicHierarchical = $generalSettings[$filterOrder]['settings']['f_multi_logic_hierarchical']; $isHierarchical = $generalSettings[$filterOrder]['settings']['f_show_hierarchical']; $type = $generalSettings[$filterOrder]['settings']['f_frontend_type']; $isLogicHierarchical = ( $isHierarchical && in_array( $type, array( 'text', 'multi' ) ) ); if ($isLogicHierarchical && 'child' == $logicHierarchical) { $filtersDataBackend[$key]['settings'] = $this->getModule()->exludeParentTems($filtersDataBackend[$key]['settings'], 'product_cat'); } elseif ($isLogicHierarchical && 'parent' == $logicHierarchical) { $filtersDataBackend[$key]['settings'] = $this->getModule()->exludeChildTems($filtersDataBackend[$key]['settings'], 'product_cat'); } } } } if (!$onlyFilterRecount && class_exists( 'Astra_Theme_Options' ) && class_exists('WP')) { global $wp; if (is_object($wp)) { $wp->main(); } } $args = $this->createArgsForFilteringBySettings($filtersDataBackend, $queryvars, $filterSettings, $generalSettings, $woocommerceSettings, $shortcodeAttr); if ( isset( $args['posts_per_page'] ) && $args['posts_per_page'] > 0 ) { $queryvars['posts_per_page'] = $args['posts_per_page']; } $parts = parse_url($curUrl); $urlQuery = array(); if (!empty($parts['query'])) { parse_str($parts['query'], $urlQuery); if (!empty($urlQuery['s'])) { $args['s'] = $urlQuery['s']; } } if (isset($urlQuery['product_view'])) { $_GET['product_view'] = $urlQuery['product_view']; $_REQUEST['product_view'] = $urlQuery['product_view']; } $cacheArgs = $args; $categoryHtml = ''; $productsHtml = ''; $paginationHtml = ''; $paginationLeer = ''; $resultCountHtml = ''; $loopStart = ''; $jscript = ''; if (!$onlyFilterRecount) { DispatcherWpf::doAction('beforeFiltersFrontend', $filtersDataBackend); $paged = empty($queryvars['paged']) ? 1 : $queryvars['paged']; if (empty($params['runbyload']) && empty($queryvars['pagination'])) { $paged = 1; } if (!empty($queryvars['posts_per_row'])) { $customNums = $queryvars['posts_per_row']; global $woocommerce_loop; $woocommerce_loop['columns'] = $customNums; // needed for some themes, that check this property first add_filter('loop_shop_columns', function( $num ) use ( $customNums ) { return $customNums; }, 999); } $args['paged'] = $paged; // other plugin compatibility class_exists('WC_pif') && add_filter('post_class', array($this->getModule(), 'WC_pif_product_has_gallery')); class_exists('YITH_Request_Quote') && add_filter('woocommerce_loop_add_to_cart_link', array($this->getModule(), 'YITH_hide_add_to_cart_loop'), 10, 2); if (class_exists('Iconic_WSSV_Query')) { $args = $this->getModule()->Iconic_Wssv_Query_Args($args); } if (function_exists( 'kute_boutique_woocommerce_setup_loop' )) { kute_boutique_woocommerce_setup_loop(); } } //Prepare params for WooCommerce Shop and Category template variants. $shopPageId = wc_get_page_id('shop'); $currentPageId = isset($queryvars['page_id']) ? $queryvars['page_id'] : 0; $allProductsFiltering = isset($filterSettings['all_products_filtering']) && $filterSettings['all_products_filtering']; $categoryPageId = isset($queryvars['product_category_id']) && !$allProductsFiltering ? $queryvars['product_category_id'] : false; $calcParentCategory = null; $showProducts = true; if ( !isset($parts['query']) || '' === $parts['query'] || 'wpf_fbv=1' === $parts['query']) { if ( $shopPageId == $currentPageId ) { $pageDisplay = get_option( 'woocommerce_shop_page_display', '' ); if ( 'subcategories' == $pageDisplay || 'both' == $pageDisplay ) { $calcParentCategory = 0; if ( 'subcategories' == $pageDisplay ) { $showProducts = false; } } } elseif ( $categoryPageId ) { $archiveDisplay = get_term_meta( $categoryPageId, 'display_type', true ); if ( '' === $archiveDisplay ) { $archiveDisplay = get_option( 'woocommerce_category_archive_display', '' ); } $termProductCategory = get_term_by( 'id', $categoryPageId, 'product_cat' ); if ( $termProductCategory && ( 'subcategories' === $archiveDisplay || 'both' === $archiveDisplay ) ) { $calcParentCategory = $termProductCategory->term_id; if ( 'subcategories' === $archiveDisplay ) { $showProducts = false; } } } } $recount = isset($filterSettings['filter_recount']) && $filterSettings['filter_recount']; $removeActions = isset($filterSettings['remove_actions']) && $filterSettings['remove_actions']; $filteringVariations = isset($filterSettings['filtering_by_variations']) ? $filterSettings['filtering_by_variations'] : false; $displayProductVariations = $filteringVariations && isset($filterSettings['display_product_variations']) ? $filterSettings['display_product_variations'] : false; $wpfFId = !empty($filterSettings['wpf_fid']) ? $filterSettings['wpf_fid'] : ''; if ($removeActions) { remove_all_filters('posts_orderby'); remove_all_filters('pre_get_posts'); remove_all_filters('wpv_action_apply_archive_query_settings'); if ($onlyFilterRecount) { remove_all_filters('posts_clauses'); } } $module = $this->getModule(); $taxonomies = $module->getFilterTaxonomies($generalSettings, !is_null($calcParentCategory), $filterSettings, true, $urlQuery); if (!$recount) { $taxonomies['count'] = array(); } if (FrameWpf::_()->proVersionCompare('1.4.8')) { $args = $module->addBeforeFiltersFrontendArgs($args, $filterSettings, $urlQuery); } else { $args = DispatcherWpf::applyFilters('beforeFilterExistsTerms', $args, $filterSettings, $urlQuery); } $filterItems = $module->getFilterExistsItems($args, $taxonomies, $calcParentCategory, $categoryPageId, $generalSettings, true , $filterSettings, array(), $urlQuery); if ($onlyStatistics) { $isFound = empty($filterItems['have_posts']) ? 0 : 1; DispatcherWpf::doAction('saveStatistics', $isFound); return $res->ajaxExec(); } if (false !== $filterItems) { $jscript .= '<script type="text/javascript">wpfShowHideFiltersAtts(' . json_encode($filterItems['exists']) . ', ' . json_encode($filterItems['existsUsers']) . ', "' . $synchroFilterId . '");</script>'; if ($recount) { $jscript .= '<script type="text/javascript">wpfChangeFiltersCount(' . json_encode($filterItems['exists']) . ', "' . $synchroFilterId . '");</script>'; } } if (!empty($wpfFId)) { $jscript .= '<script type="text/javascript">wpfDoActionsAfterLoad(' . $wpfFId . ',' . ( empty($filterItems) || empty($filterItems['have_posts']) ? 0 : 1 ) . ');</script>'; } if (!$onlyFilterRecount) { if (class_exists('qib_settings')) { do_action('template_redirect'); } $categoryIn = isset($filterItems['categories']) ? $filterItems['categories'] : array(); if (count($categoryIn) > 0 && $use_category_filtration) { ob_start(); $catIds = array_keys($categoryIn); $cats = get_terms( array( 'taxonomy' => 'product_cat', 'include' => $catIds ) ); foreach ($cats as $category) { $cnt = $categoryIn[$category->term_id]; $category->count = $cnt; wc_get_template('content-product_cat.php', array('category' => $category)); } $categoryHtml .= ob_get_clean(); } $loopFoundPost = 0; if ( $showProducts || empty($categoryHtml) ) { //get products if (FrameWpf::_()->proVersionCompare('1.4.8')) { //$loop = new WP_Query($module->addBeforeFiltersFrontendArgs($args, $filterSettings)); $loop = new WP_Query($args); } else { $loop = new WP_Query(DispatcherWpf::applyFilters('beforeFiltersFrontendArgs', $args, $filterSettings)); } if ($displayProductVariations) { DispatcherWpf::doAction('beforeLoopVariations', $filterSettings); } $loopFoundPost = $loop->found_posts; if ($loop->have_posts()) { ob_start(); while ($loop->have_posts()) : $loop->the_post(); if ($displayProductVariations) { DispatcherWpf::doAction('beforeDisplayProduct', $args); } wc_get_template_part('content', 'product'); endwhile; $productsHtml = ob_get_clean(); if (empty($productsHtml)) { $productsHtml = __($filterSettings['text_no_products'], 'woo-product-filter'); } } else { $productsHtml = __($filterSettings['text_no_products'], 'woo-product-filter'); } } ob_start(); wc_get_template( 'loop/loop-start.php' ); $loopStart = ob_get_clean(); //get result count ob_start(); $args = array( 'total' => $loopFoundPost, 'per_page' => $queryvars['posts_per_page'], 'current' => $paged, ); wc_get_template( 'loop/result-count.php', $args ); $resultCountHtml = ob_get_clean(); //get pagination ob_start(); $base = $queryvars['base']; //get query params $curUrl = explode( '?', $curUrl ); $curUrl = isset($curUrl[1]) ? remove_query_arg('product-page', $curUrl[1]) : '';//wpf-page=1'; $format = isset($queryvars['format']) ? $queryvars['format'] : ''; //add quary params to base url $fullBaseUrl = $base . ( strpos($base, '?') === false ? '?wpf_filtered=1&' : '&' ) . $curUrl; // add pagination query to base url $paginateType = $queryvars['paginate_type']; $paginateBase = $queryvars['paginate_base']; if ( 'query' === $paginateType || ( 'shortcode' === $paginateType && strpos($fullBaseUrl, $paginateBase) === false ) ) { $fullBaseUrl .= ( strpos($fullBaseUrl, '?') === false ? '?' : '&' ) . $paginateBase . '=%#%'; } $total = ceil( $loopFoundPost / $queryvars['posts_per_page'] ) ; //after filtering we always start from 1 page $args = array( 'base' => $fullBaseUrl, 'format' => $format, 'add_args' => false, 'current' => $paged,//1,//$queryvars['paged'], 'total' => $total, 'prev_text' => '&larr;', 'next_text' => '&rarr;', 'type' => 'list', 'end_size' => 3, 'mid_size' => 3, ); $theme = wp_get_theme(); if ( $theme instanceof WP_Theme ) { $themeName = ( '' !== $theme['Parent Theme'] ) ? $theme['Parent Theme'] : $theme['Name']; switch ( $themeName ) { case 'Impreza': $args['before_page_number'] = '<span>'; $args['after_page_number'] = '</span>'; unset( $args['type'] ); $links = paginate_links( $args ); HtmlWpf::echoEscapedHtml( _navigation_markup( $links, 'pagination', '' ) ); break; case 'Themify Ultra': $args['before_page_number'] = '<span>'; $args['after_page_number'] = '</span>'; unset( $args['type'] ); $links = paginate_links( $args ); HtmlWpf::echoEscapedHtml( '<div class="pagenav tf_clear tf_box tf_textr tf_clearfix">' . $links . '</div>' ); break; default: wc_get_template( 'loop/pagination.php', $args ); break; } } $paginationHtml = ob_get_clean(); wp_reset_postdata(); add_filter('primer_wc_pagination_args', function( $arg ) use ( $fullBaseUrl ) { $arg['base'] = $fullBaseUrl; return $arg; }); if (empty($paginationHtml)) { ob_start(); $args['current'] = 1; $args['total'] = 2; wc_get_template( 'loop/pagination.php', $args); $paginationLeer = ob_get_clean(); wp_reset_postdata(); if (empty($paginationLeer)) { $args['current'] = $paged; $args['total'] = $total; ob_start(); global $wp_query; $wp_query->max_num_pages = $total; wc_get_template( 'loop/pagination.php', $args ); $paginationHtml = ob_get_clean(); wp_reset_postdata(); if (empty($paginationHtml)) { $args['current'] = 1; $args['total'] = 2; ob_start(); $wp_query->max_num_pages = 2; wc_get_template( 'loop/pagination.php', $args ); $paginationLeer = ob_get_clean(); } } } } $prices = array(); if ( isset( $filterItems['existsPrices'] ) ) { $filteredPrices = $filterItems['existsPrices']; $prices['wpf_max_price'] = $filteredPrices->wpfMaxPrice; $prices['wpf_min_price'] = $filteredPrices->wpfMinPrice; if ( ! empty( $prices['wpf_max_price'] ) ) { $jscript .= '<script type="text/javascript">wpfChangePriceFiltersCount(' . json_encode( $prices ) . ');</script>'; } } $beforeProductHtml = DispatcherWpf::applyFilters('productLoopStart', '', $generalSettings, $urlQuery); if ( '' !== $beforeProductHtml ) { $res->addData( 'beforeProductHtml', $beforeProductHtml ); } $res->addData('categoryHtml', $categoryHtml); $res->addData('productHtml', $productsHtml); $res->addData('paginationHtml', $paginationHtml); $res->addData('resultCountHtml', $resultCountHtml); $res->addData('loopStartHtml', $loopStart); $res->addData('paginationLeerHtml', $paginationLeer); $res->addData('prices', $prices); $res->addData('jscript', $jscript); $res->addData('fid', $wpfFId); return $res->ajaxExec(); } /** * Clone orderby new wp_query parametr. * * @deprecated 1.3.4 * @deprecated No longer used by internal code and not recommended. * * @param array $args * * @return array */ /*public function order_by_popularity_post_clauses_clone( $args ) { global $wpdb; $args['orderby'] = "$wpdb->postmeta.meta_value+0 DESC, $wpdb->posts.post_date DESC"; return $args; }*/ public function getTaxonomyTerms() { $res = new ResponseWpf(); $slug = ReqWpf::getVar('slug'); $terms = array(); $keys = array(); if (!is_null($slug)) { $terms = $this->getModule()->getAttributeTerms($slug); $keys = array_keys($terms); } $res->addData('terms', htmlentities(UtilsWpf::jsonEncode($terms), ENT_COMPAT)); $res->addData('keys', htmlentities(UtilsWpf::jsonEncode($keys), ENT_COMPAT)); return $res->ajaxExec(); } /** * Creat args for WP_Query * * @param array $filtersDataBackend Filters arranged with filtering order with some specific filtering data in it * @param array $queryvars Query fiiltering variables * @param array $filterSettings Some filter block settings * @param array $generalSettings Filters arranged with filtering order with all filter settings * @param array $woocommerceSettings If we do not have own filtering result we must take it from woocommerce if they are set * * @return array */ public function createArgsForFilteringBySettings( $filtersDataBackend, $queryvars, $filterSettings, $generalSettings, $woocommerceSettings, $shortcodeAttr ) { $queryvars['product_tag'] = isset($queryvars['product_tag']) ? $queryvars['product_tag'] : false; $queryvars['product_brand'] = isset($queryvars['product_brand']) ? $queryvars['product_brand'] : false; $queryvars['pwb-brand'] = isset($queryvars['pwb-brand']) ? $queryvars['pwb-brand'] : false; $queryvars['tax_page'] = isset($queryvars['tax_page']) ? $queryvars['tax_page'] : false; $queryvars['vendors'] = isset($queryvars['vendors']) ? $queryvars['vendors'] : false; $asDefaultCats = array(); $settingIds = array_column($filtersDataBackend, 'id'); $settingCats = array_keys($settingIds, 'wpfCategory'); $MultiLogic = isset( $filterSettings['f_multi_logic'] ) ? $filterSettings['f_multi_logic'] : 'and'; if (!count($settingCats)) { foreach ($generalSettings as $generalSingle) { if ( ( 'wpfCategory' == $generalSingle['id'] ) && $generalSingle['settings']['f_filtered_by_selected'] && !empty($generalSingle['settings']['f_mlist[]']) ) { $asDefaultCats = array_merge($asDefaultCats, explode(',', $generalSingle['settings']['f_mlist[]'])); break; } } } $module = $this->getModule(); $postStatus = ( isset( $filterSettings['display_status_private'] ) && $filterSettings['display_status_private'] ) ? array( 'publish', 'private' ) : 'publish'; $args = array( 'post_type' => 'product', 'post_status' => $postStatus, 'paged' => 1, 'posts_per_page' => $queryvars['posts_per_page'], 'ignore_sticky_posts' => true, 'wpf_query' => 1, 'tax_query' => array('wpf_tax' => 1) ); if (!empty($filterSettings['default_query'])) { $args = array_merge($args, $filterSettings['default_query']); } $args['tax_query'] = $module->addHiddenFilterQuery($args['tax_query']); $isAllProductsFiltering = $filterSettings['all_products_filtering'] && $filtersDataBackend; if (!$isAllProductsFiltering) { if ( ( isset($queryvars['product_category_id']) || $asDefaultCats ) && !$queryvars['product_tag'] && !$queryvars['product_brand'] && !$queryvars['pwb-brand'] ) { $args['tax_query'][] = array( 'taxonomy' => 'product_cat', 'field' => 'id', 'terms' => isset($queryvars['product_category_id']) ? $queryvars['product_category_id'] : $asDefaultCats, 'include_children' => true ); } elseif ($queryvars['product_tag']) { $args['tax_query'][] = array( 'taxonomy' => 'product_tag', 'field' => 'id', 'terms' => $queryvars['product_tag'], 'include_children' => true ); } elseif ($queryvars['product_brand']) { $args['tax_query'][] = array( 'taxonomy' => 'product_brand', 'field' => 'id', 'terms' => $queryvars['product_brand'], 'include_children' => true ); } elseif ($queryvars['pwb-brand']) { $args['tax_query'][] = array( 'taxonomy' => 'pwb-brand', 'field' => 'id', 'terms' => $queryvars['pwb-brand'], 'include_children' => true ); } elseif ($queryvars['vendors']) { if ( is_numeric( $queryvars['vendors'] ) ) { $args['author'] = $queryvars['vendors']; } else { $args['author_name'] = $queryvars['vendors']; } } elseif (is_array($queryvars['tax_page'])) { $args['tax_query'][] = array( 'taxonomy' => $queryvars['tax_page']['taxonomy'], 'field' => 'id', 'terms' => $queryvars['tax_page']['term'], 'include_children' => true ); } } if ( $shortcodeAttr ) { // first adds parameters from the shortcode new WC_Shortcode_Products( $shortcodeAttr ); } // set woocommerce sorting data if we do not have own sorting filtering $isWpfSortBy = array_search('wpfSortBy', array_column($filtersDataBackend, 'id')); if (!$isWpfSortBy && isset($woocommerceSettings['woocommercefSortBy'])) { $filtersDataBackend[] = array( 'id' => 'wpfSortBy', 'settings' => $woocommerceSettings['woocommercefSortBy'], ); } $temp = array(); foreach ($filtersDataBackend as $setting) { if (!empty($setting['settings'])) { $metaQuery = DispatcherWpf::applyFilters('addAjaxCustomMetaQueryPro', array(), $setting, $filterSettings); if (!empty($metaQuery)) { $args['meta_query'][] = $metaQuery; continue; } switch ($setting['id']) { case 'wpfPrice': $priceStr = $setting['settings'][0]; $priceVal = explode(',', $priceStr); if ( $priceVal[0] >= 0 && $priceVal[1] >= 0 ) { $temp['wpfPrice']['wpf_min_price'] = $priceVal[0]; $temp['wpfPrice']['wpf_max_price'] = $priceVal[1]; } break; case 'wpfPriceRange': $priceStr = $setting['settings'][0]; $priceVal = explode(',', $priceStr); if ( count($priceVal) == 2 && ( false !== $priceVal[0] ) ) { $temp['wpfPrice']['wpf_min_price'] = ( '' == $priceVal[0] ? null : $priceVal[0] ); $temp['wpfPrice']['wpf_max_price'] = ( '' == $priceVal[1] ? null : $priceVal[1] ); } break; case 'wpfSortBy': $sortBy = ( is_array($setting['settings']) ) ? $setting['settings'][0] : $setting['settings']; remove_all_filters('posts_clauses'); switch ($sortBy) { case 'title': $args['orderby'] = 'title'; $args['order'] = 'ASC'; break; case 'title-desc': $args['orderby'] = 'title'; $args['order'] = 'DESC'; break; case 'rand': $args['orderby'] = 'rand'; break; case 'date': $args['orderby'] = array( 'date' => 'DESC', 'ID' => 'ASC', ); $args['order'] = 'DESC'; break; case 'date-asc': $args['orderby'] = array( 'date' => 'ASC', 'ID' => 'ASC', ); $args['order'] = 'ASC'; break; case 'price': remove_all_filters('woocommerce_get_catalog_ordering_args'); $WC_Query = new WC_Query(); $vars = $WC_Query->get_catalog_ordering_args('price'); if (is_array($vars)) { $args = array_merge($args, $vars); } break; case 'price-desc': remove_all_filters('woocommerce_get_catalog_ordering_args'); $WC_Query = new WC_Query(); $vars = $WC_Query->get_catalog_ordering_args('price', 'DESC'); if (is_array($vars)) { $args = array_merge($args, $vars); } break; case 'popularity': $args['orderby'] = 'meta_value_num'; $args['order'] = 'DESC'; $args['meta_key'] = 'total_sales'; break; case 'rating': $args['meta_key'] = '_wc_average_rating'; // @codingStandardsIgnoreLine $args['orderby'] = array( 'meta_value_num' => 'DESC', 'ID' => 'ASC', ); break; case 'sku': add_filter( 'posts_clauses', array( FrameWpf::_()->getModule( 'woofilters' ), 'addSKUOrder' ) ); break; case 'sku-desc': add_filter( 'posts_clauses', array( FrameWpf::_()->getModule( 'woofilters' ), 'addSKUOrderDesc' ) ); break; } break; case 'wpfCategory': $categoryIds = $setting['settings']; $logic = isset($setting['logic']) ? $setting['logic'] : 'and'; $temp['wpfCategory'][] = array( 'taxonomy' => 'product_cat', 'field' => 'term_id', 'terms' => $categoryIds, 'operator' => 'not' == $logic ? 'NOT IN' : ( 'or' == $logic || count($categoryIds) <= 1 ? 'IN' : 'AND' ), 'include_children' => ( isset($setting['children']) && ( '1' == $setting['children'] ) ), ); break; case 'wpfPerfectBrand': $brandIds = $setting['settings']; $logic = isset($setting['logic']) ? $setting['logic'] : 'and'; $args['tax_query'][] = array( 'taxonomy' => 'pwb-brand', 'field' => 'term_id', 'terms' => $brandIds, 'operator' => 'not' == $logic ? 'NOT IN' : ( 'or' == $logic || count($brandIds) <= 1 ? 'IN' : 'AND' ), 'include_children' => ( isset($setting['children']) && ( '1' == $setting['children'] ) ), ); break; case 'wpfTags': $tagsIdStr = $setting['settings']; if ($tagsIdStr) { $logic = isset($setting['logic']) ? $setting['logic'] : 'and'; $temp['wpfTags'][] = array( 'taxonomy' => 'product_tag', 'field' => 'id', 'terms' => $tagsIdStr, 'operator' => 'not' == $logic ? 'NOT IN' : ( 'or' == $logic || count($tagsIdStr) <= 1 ? 'IN' : 'AND' ), ); } break; case 'wpfAttribute': $attrIds = $setting['settings']; $customPrefixes = DispatcherWpf::applyFilters('getCustomPrefixes', array(), false); $pos = strpos($setting['name'], '-'); if (!$pos || !in_array( substr($setting['name'], 0, $pos + 1), $customPrefixes )) { $taxonomy = ''; foreach ($attrIds as $attr) { $term = get_term( $attr ); if ($term && $term->taxonomy) { $taxonomy = $term->taxonomy; break; } } if ( '' !== $taxonomy ) { $logic = isset( $setting['logic'] ) ? $setting['logic'] : 'and'; $logics = $module->getAttrFilterLogic( 'loop' ); $operator = array_key_exists( $logic, $logics ) ? $logics[ $logic ] : ( 'not' == $logic ? 'NOT IN' : 'IN' ); $temp['wpfAttribute'][] = array( 'taxonomy' => $taxonomy, 'field' => 'id', 'terms' => $attrIds, 'operator' => $operator, ); } } break; case 'wpfAuthor': if ( isset( $setting['settings'][0] ) && '' !== $setting['settings'][0] ) { $args['author__in'] = $setting['settings']; } break; case 'wpfFeatured': $enable = $setting['settings'][0]; if ('1' === $enable) { $args['tax_query'][] = array( 'taxonomy' => 'product_visibility', 'field' => 'name', 'terms' => 'featured', 'operator' => 'IN', ); } break; case 'wpfOnSale': $enable = $setting['settings'][0]; if ('1' === $enable) { $args['post__in'] = array_merge(array(0), wc_get_product_ids_on_sale()); } break; case 'wpfInStock': $stockstatus = $setting['settings']; if ($stockstatus) { $metaKeyId = $module->getMetaKeyId('_stock_status'); if ( $metaKeyId ) { $values = FrameWpf::_()->getModule( 'meta' )->getModel( 'meta_values' )->getMetaValueIds( $metaKeyId, $stockstatus ); $module->addWpfMetaClauses( array( 'keyId' => $metaKeyId, 'isAnd' => false, 'values' => $values, 'field' => 'id', 'urlParam' => $setting['name'], ) ); } else { $metaQuery = array( 'key' => '_stock_status', 'value' => $stockstatus, 'compare' => 'IN' ); } $args['meta_query'][] = $metaQuery; } break; case 'wpfRating': $ratingRange = $setting['settings']; if (is_array($ratingRange)) { foreach ($ratingRange as $range) { $range = strpos($range, '-') !== false ? explode('-', $range) : array(intval($range)); break; } if (isset($range[1]) && intval($range[1]) !== 5) { $range[1] = $range[1] - 0.001; } if ($range[0]) { $isBetween = isset($range[1]) && $range[1]; $metaKeyId = $module->getMetaKeyId('_wc_average_rating'); if ( $metaKeyId ) { $module->addWpfMetaClauses( array( 'keyId' => $metaKeyId, 'isAnd' => ( $isBetween ? 'BETWEEN' : false ), 'values' => $range, 'field' => 'int', 'urlParam' => $setting['name'], ) ); } else { if ( $isBetween ) { $metaQuery = array( 'key' => '_wc_average_rating', 'value' => array( $range[0], $range[1] ), 'type' => 'DECIMAL', 'compare' => 'BETWEEN' ); $args['meta_query'][] = $metaQuery; } else { $metaQuery = array( 'key' => '_wc_average_rating', 'value' => $range[0], 'type' => 'DECIMAL', 'compare' => '=' ); $args['meta_query'][] = $metaQuery; } } } } break; case 'wpfBrand': $brandsIdStr = $setting['settings']; if ($brandsIdStr) { $args['tax_query'][] = array( 'taxonomy' => 'product_brand', 'field' => 'id', 'terms' => $brandsIdStr, 'operator' => ( isset($setting['logic']) && ( 'or' == $setting['logic'] ) ? 'IN' : 'AND' ) ); } break; case 'wpfVendors': $vendorIds = $setting['settings']; if (!empty($vendorIds)) { $args['author__in'] = $vendorIds; } break; case 'wpfSearchNumber': if (!empty($setting['settings']['value'])) { $args['tax_query'] = DispatcherWpf::applyFilters('addCustomTaxQueryPro', $args['tax_query'], array($setting['name'] => $setting['settings']['value']), 'url'); } break; } } } //DispatcherWpf::doAction('addArgsForFilteringBySettings', $filtersDataBackend); if (isset($temp['wpfCategory'])) { $temp['wpfCategory']['relation'] = strtoupper($MultiLogic); $args['tax_query'][] = $temp['wpfCategory']; } if (isset($temp['wpfAttribute'])) { $temp['wpfAttribute']['relation'] = strtoupper($MultiLogic); $args['tax_query'][] = $temp['wpfAttribute']; } if (isset($temp['wpfTags'])) { $temp['wpfTags']['relation'] = strtoupper($MultiLogic); $args['tax_query'][] = $temp['wpfTags']; } if ( isset($args['tax_query']) && !empty($args['tax_query']) ) { $args['tax_query']['relation'] = 'AND'; } if (isset($temp['wpfPrice'])) { $args['meta_query'][] = $module->preparePriceFilter($temp['wpfPrice']['wpf_min_price'], $temp['wpfPrice']['wpf_max_price']); } $sortByTitle = !empty( $filterSettings['sort_by_title'] ) ? $filterSettings['sort_by_title'] : false; if ( $sortByTitle ) { $args = $module->addCustomOrder($args, 'title'); } if (empty($args['orderby'])) { $WC_Query = new WC_Query(); $args['orderby'] = 'menu_order title'; $args['order'] = 'ASC'; if ( $shortcodeAttr ) { if ( isset( $shortcodeAttr['orderby'] ) && ''!==$shortcodeAttr['orderby'] ) { $args['orderby'] = ( 'price-desc' === $shortcodeAttr['orderby'] ) ? 'price' : $shortcodeAttr['orderby']; } if ( isset( $shortcodeAttr['order'] ) && ''!==$shortcodeAttr['order'] ) { $args['order'] = ( isset( $shortcodeAttr['orderby'] ) && 'price-desc' === $shortcodeAttr['orderby'] ) ? 'DESC' : $shortcodeAttr['order']; } } else { $vars = $WC_Query->get_catalog_ordering_args(); if ( is_array( $vars ) && ! empty( $vars['orderby'] ) ) { $args['orderby'] = $vars['orderby']; $args['order'] = empty( $vars['order'] ) ? 'ASC' : $vars['order']; if ( ! empty( $vars['meta_key'] ) ) { $args['meta_key'] = $vars['meta_key']; } } } } $args = $module->addWooOptions($args); if ($shortcodeAttr) { if (!isset($filterSettings['do_not_use_shortcut']) || !$filterSettings['do_not_use_shortcut']) { $args = $this->addShortcodeAttrToArgs($args, $shortcodeAttr, $filterSettings); } } return $args; } /** * Add shortcode adttributes to wp_query filtering args * * @param array $args * @param array $shortcodeAttr * @param array $filterSettings * * @return void */ public function addShortcodeAttrToArgs( $args, $shortcodeAttr, $filterSettings ) { if (!empty( $shortcodeAttr['rows'] && ! empty($shortcodeAttr['columns']) )) { $shortcodeAttr['limit'] = $shortcodeAttr['columns'] * $shortcodeAttr['rows']; $args['posts_per_page'] = intval( $shortcodeAttr['limit'] ); } $args = $this->setCategoriesQueryArgs($args, $shortcodeAttr); $args = $this->setTagsQueryArgs($args, $shortcodeAttr); $args = $this->setAttributesQueryArgs($args, $shortcodeAttr); return $args; } public function setCategoriesQueryArgs( $args, $shortcodeAttr ) { if ( ! empty( $shortcodeAttr['category'] ) ) { $categories = array_map( 'sanitize_title', explode( ',', $shortcodeAttr['category'] ) ); $field = 'slug'; if ( is_numeric( $categories[0] ) ) { $field = 'term_id'; $categories = array_map( 'absint', $categories ); // Check numeric slugs. foreach ( $categories as $cat ) { $the_cat = get_term_by( 'slug', $cat, 'product_cat' ); if ( false !== $the_cat ) { $categories[] = $the_cat->term_id; } } } $args['tax_query'][] = array( 'taxonomy' => 'product_cat', 'terms' => $categories, 'field' => $field, 'operator' => $shortcodeAttr['cat_operator'], /* * When cat_operator is AND, the children categories should be excluded, * as only products belonging to all the children categories would be selected. */ 'include_children' => 'AND' === $shortcodeAttr['cat_operator'] ? false : true, ); } return $args; } public function setTagsQueryArgs( $args, $shortcodeAttr ) { if ( ! empty( $shortcodeAttr['tag'] ) ) { $args['tax_query'][] = array( 'taxonomy' => 'product_tag', 'terms' => array_map( 'sanitize_title', explode( ',', $shortcodeAttr['tag'] ) ), 'field' => 'slug', 'operator' => $shortcodeAttr['tag_operator'], ); } return $args; } public function setAttributesQueryArgs( $args, $shortcodeAttr ) { if ( ! empty( $shortcodeAttr['attribute'] ) || ! empty( $shortcodeAttr['terms'] ) ) { $taxonomy = strstr( $shortcodeAttr['attribute'], 'pa_' ) ? sanitize_title( $shortcodeAttr['attribute'] ) : 'pa_' . sanitize_title( $shortcodeAttr['attribute'] ); $terms = $shortcodeAttr['terms'] ? array_map( 'sanitize_title', explode( ',', $shortcodeAttr['terms'] ) ) : array(); $field = 'slug'; if ( $terms && is_numeric( $terms[0] ) ) { $field = 'term_id'; $terms = array_map( 'absint', $terms ); // Check numeric slugs. foreach ( $terms as $term ) { $theTerm = get_term_by( 'slug', $term, $taxonomy ); if ( false !== $theTerm ) { $terms[] = $theTerm->term_id; } } } // If no terms were specified get all products that are in the attribute taxonomy. if ( ! $terms ) { $terms = get_terms( array( 'taxonomy' => $taxonomy, 'fields' => 'ids', ) ); $field = 'term_id'; } // We always need to search based on the slug as well, this is to accommodate numeric slugs. $args['tax_query'][] = array( 'taxonomy' => $taxonomy, 'terms' => $terms, 'field' => $field, 'operator' => $shortcodeAttr['terms_operator'], ); } return $args; } }