<?php namespace DgoraWcas\Engines\WordPressNative; use DgoraWcas\Analytics\Recorder; use DgoraWcas\Multilingual; use DgoraWcas\Product; use DgoraWcas\Helpers; // Exit if accessed directly if ( !defined( 'ABSPATH' ) ) { exit; } class Search { /** * Total autocomplete limit */ private $totalLimit; /** * Flexible lmits * bool */ private $flexibleLimits = true; /** * Show heading in autocomplete * bool */ private $showHeadings = false; /** * Autocomplete groups * array */ private $groups = array(); /** * Buffer for post IDs uses for search results page * @var null */ private $postsIDsBuffer = null; /** * List of fields in which the phrase is searched * @var array */ private $searchIn = array(); /** * @var bool Whether the search results have already been overwritten. */ private $hooked = false; public function __construct() { $this->searchIn = apply_filters( 'dgwt/wcas/native/search_in', array( 'title', 'content', 'excerpt', 'sku' ) ); add_filter( 'posts_search', array($this, 'searchFilters'), 501, 2 ); add_filter( 'posts_where', array($this, 'fixWooExcerptSearch'), 100, 2 ); add_filter( 'posts_distinct', array($this, 'searchDistinct'), 501, 2 ); add_filter( 'posts_join', array($this, 'searchFiltersJoin'), 501, 2 ); // Search results page add_action( 'init', function () { if ( apply_filters( 'dgwt/wcas/override_search_results_page', true ) ) { add_filter( 'pre_get_posts', array($this, 'overwriteSearchPage'), 900001 ); add_filter( 'posts_search', array('DgoraWcas\\Helpers', 'clearSearchQuery'), 1000, 2 ); add_filter( 'the_posts', array('DgoraWcas\\Helpers', 'rollbackSearchPhrase'), 1000, 2 ); add_filter( 'dgwt/wcas/search_page/result_post_ids', array($this, 'getProductIds'), 10, 2 ); } } ); // Search results ajax action if ( DGWT_WCAS_WC_AJAX_ENDPOINT ) { add_action( 'wc_ajax_' . DGWT_WCAS_SEARCH_ACTION, array($this, 'getSearchResults') ); } else { add_action( 'wp_ajax_nopriv_' . DGWT_WCAS_SEARCH_ACTION, array($this, 'getSearchResults') ); add_action( 'wp_ajax_' . DGWT_WCAS_SEARCH_ACTION, array($this, 'getSearchResults') ); } // Labels if ( !dgoraAsfwFs()->is_premium() ) { add_filter( 'dgwt/wcas/labels', array($this, 'setTaxonomiesLabels'), 5 ); add_filter( 'dgwt/wcas/labels', array($this, 'fixTaxonomiesLabels'), PHP_INT_MAX - 5 ); } // Fixes if "Polylang" is active but without "Polylang for WooCommerce" or "Hyyan WooCommerce Polylang Integration" if ( Multilingual::isPolylang() && !class_exists( 'Polylang_Woocommerce' ) && !defined( 'Hyyan_WPI_DIR' ) ) { add_filter( 'woocommerce_ajax_get_endpoint', array($this, 'fixPolylangWooEndpoint'), 10, 2 ); } // Add "No results" suggestion if all results have been removed in earlier filters. add_filter( 'dgwt/wcas/search_results/output', array('DgoraWcas\\Helpers', 'noResultsSuggestion'), PHP_INT_MAX - 10 ); // Init Search Analytics if ( DGWT_WCAS()->settings->getOption( 'analytics_enabled' ) === 'on' ) { $stats = new Recorder(); $stats->listen(); } } /** * Get search results via ajax * * @param string $phrase Search phrase. * @param bool $return Whether to return the results. * @param string $context Search context: 'autocomplete' or 'product-ids'. * * @return mixed|void */ public function getSearchResults( $phrase = '', $return = false, $context = 'autocomplete' ) { if ( $context === 'all-results' ) { $context = 'product-ids'; } $start = microtime( true ); $lang = ''; $hits = 0; if ( Multilingual::isMultilingual() ) { $lang = Multilingual::getCurrentLanguage(); } if ( !defined( 'DGWT_WCAS_AJAX' ) ) { define( 'DGWT_WCAS_AJAX', true ); } $this->groups = $this->searchResultsGroups(); $this->flexibleLimits = apply_filters( 'dgwt/wcas/flexible_limits', true ); $this->showHeadings = DGWT_WCAS()->settings->getOption( 'show_grouped_results' ) === 'on'; if ( $this->flexibleLimits ) { $totalLimit = DGWT_WCAS()->settings->getOption( 'suggestions_limit', 'int', 7 ); $this->totalLimit = ( $totalLimit === -1 ? $this->calcFreeSlots() : $totalLimit ); } $output = array(); $results = array(); $keyword = ''; if ( $return ) { $keyword = sanitize_text_field( $phrase ); } else { // Compatible with v1.1.7 if ( !empty( $_REQUEST['dgwt_wcas_keyword'] ) ) { $keyword = sanitize_text_field( $_REQUEST['dgwt_wcas_keyword'] ); } if ( !empty( $_REQUEST['s'] ) ) { $keyword = sanitize_text_field( $_REQUEST['s'] ); } } $keyword = apply_filters( 'dgwt/wcas/phrase', $keyword ); // Break early if keyword contains blacklisted phrase. if ( Helpers::phraseContainsBlacklistedTerm( $keyword ) ) { if ( $return ) { return $this->getEmptyOutput(); } else { echo json_encode( Helpers::noResultsSuggestion( $this->getEmptyOutput() ) ); die; } } /* SEARCH IN WOO CATEGORIES */ if ( $context === 'autocomplete' && array_key_exists( 'tax_product_cat', $this->groups ) ) { $limit = ( $this->flexibleLimits ? $this->totalLimit : $this->groups['tax_product_cat']['limit'] ); $categories = $this->getCategories( $keyword, $limit ); $this->groups['tax_product_cat']['results'] = $categories['items']; $hits += $categories['total']; } /* SEARCH IN WOO TAGS */ if ( $context === 'autocomplete' && array_key_exists( 'tax_product_tag', $this->groups ) ) { $limit = ( $this->flexibleLimits ? $this->totalLimit : $this->groups['tax_product_tag']['limit'] ); $tags = $this->getTags( $keyword, $limit ); $this->groups['tax_product_tag']['results'] = $tags['items']; $hits += $tags['total']; } /* SEARCH IN PRODUCTS */ $totalProducts = 0; if ( apply_filters( 'dgwt/wcas/search_in_products', true ) ) { $args = array( 's' => $keyword, 'posts_per_page' => -1, 'post_type' => 'product', 'post_status' => 'publish', 'ignore_sticky_posts' => 1, 'order' => 'DESC', 'suppress_filters' => false, ); // Backward compatibility WC < 3.0 if ( Helpers::compareWcVersion( '3.0', '<' ) ) { $args['meta_query'] = $this->getMetaQuery(); } else { $args['tax_query'] = $this->getTaxQuery(); } $args = apply_filters( 'dgwt/wcas/search_query/args', $args ); $products = get_posts( $args ); $products = apply_filters( 'dgwt/wcas/search_results/products_raw', $products ); $totalProducts = count( $products ); $hits += $totalProducts; do_action( 'dgwt/wcas/analytics/after_searching', $keyword, $hits, $lang ); if ( !empty( $products ) ) { $orderedProducts = array(); $i = 0; foreach ( $products as $post ) { if ( $context === 'product-ids' ) { $orderedProducts[$i] = new \stdClass(); $orderedProducts[$i]->ID = $post->ID; } else { $orderedProducts[$i] = $post; } $score = Helpers::calcScore( $keyword, $post->post_title ); $orderedProducts[$i]->score = apply_filters( 'dgwt/wcas/search_results/product/score', $score, $keyword, $post->ID, $post ); $i++; } // Sort by relevance usort( $orderedProducts, array('DgoraWcas\\Helpers', 'cmpSimilarity') ); // Response that returns all results. if ( $context === 'product-ids' ) { $output['suggestions'] = $orderedProducts; $output['time'] = number_format( microtime( true ) - $start, 2, '.', '' ) . ' sec'; $result = apply_filters( 'dgwt/wcas/page_search_results/output', $output ); if ( $return ) { return $result; } else { echo json_encode( $result ); die; } } $productsSlots = ( $this->flexibleLimits ? $this->totalLimit : $this->groups['product']['limit'] ); $fields = []; if ( DGWT_WCAS()->settings->getOption( 'show_product_image' ) === 'on' ) { $fields[] = 'thumb_html'; } if ( DGWT_WCAS()->settings->getOption( 'show_product_price' ) === 'on' ) { $fields[] = 'price'; } if ( DGWT_WCAS()->settings->getOption( 'show_product_sku' ) === 'on' ) { $fields[] = 'sku'; } $relevantProducts = $this->getProductsData( $orderedProducts, $productsSlots, $fields ); } wp_reset_postdata(); } /* END SEARCH IN PRODUCTS */ if ( !empty( $relevantProducts ) ) { $this->groups['product']['results'] = $relevantProducts; } if ( $this->hasResults() ) { if ( $this->flexibleLimits ) { $this->applyFlexibleLimits(); } $results = $this->convertGroupsToSuggestions(); // Show more if ( !empty( $this->groups['product']['results'] ) && count( $this->groups['product']['results'] ) < $totalProducts ) { $results[] = array( 'value' => '', 'total' => $totalProducts, 'url' => add_query_arg( array( 's' => $keyword, 'post_type' => 'product', 'dgwt_wcas' => '1', ), home_url() ), 'type' => 'more_products', ); } } else { if ( $context === 'product-ids' ) { $emptyResult = new \stdClass(); $emptyResult->ID = 0; $results[] = $emptyResult; } else { $results[] = array( 'value' => '', 'type' => 'no-results', ); } } $output['suggestions'] = $results; $output['total'] = $hits; $output['time'] = number_format( microtime( true ) - $start, 2, '.', '' ) . ' sec'; $output['engine'] = 'free'; $output['v'] = DGWT_WCAS_VERSION; $result = apply_filters( 'dgwt/wcas/search_results/output', $output ); if ( $return ) { return $result; } else { echo json_encode( $result ); die; } } public function getProductsData( $orderedProducts, $limit = -1, $fields = array() ) { $relevantProducts = array(); foreach ( $orderedProducts as $post ) { $product = new Product($post); if ( !$product->isCorrect() ) { continue; } // Strip <script> and <style> tags along with their contents. $value = preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $product->getName() ); // Strip remaining tags except those indicated. $value = html_entity_decode( wp_kses( $value, array( 'b' => array( 'class' => true, ), 'br' => array(), 'span' => array( 'class' => true, ), 'strong' => array( 'class' => true, ), 'sub' => array(), 'sup' => array(), ) ) ); $r = array( 'post_id' => $product->getID(), 'value' => $value, 'url' => $product->getPermalink(), 'type' => 'product', ); // Get thumb HTML if ( in_array( 'thumb_html', $fields, true ) ) { $r['thumb_html'] = $product->getThumbnail(); } // Get price if ( in_array( 'price', $fields, true ) ) { $r['price'] = $product->getPriceHTML(); } // Get description if ( DGWT_WCAS()->settings->getOption( 'show_product_desc' ) === 'on' ) { $wordsLimit = 0; if ( DGWT_WCAS()->settings->getOption( 'show_details_box' ) === 'on' ) { $wordsLimit = 15; } $r['desc'] = $product->getDescription( 'suggestions', $wordsLimit ); } // Get SKU if ( in_array( 'sku', $fields, true ) ) { $r['sku'] = $product->getSKU(); } // Is on sale // if ( DGWT_WCAS()->settings->getOption( 'show_sale_badge' ) === 'on' ) { // $r[ 'on_sale' ] = $product->is_on_sale(); // } // Is featured // if ( DGWT_WCAS()->settings->getOption( 'show_featured_badge' ) === 'on' ) { // $r[ 'featured' ] = $product->is_featured(); // } $relevantProducts[] = apply_filters( 'dgwt/wcas/search_results/products', $r, $product ); $limit--; if ( $limit === 0 ) { break; } } return $relevantProducts; } /** * Get meta query * For WooCommerce < 3.0 * * return array */ private function getMetaQuery() { $meta_query = array( 'relation' => 'AND', 1 => array( 'key' => '_visibility', 'value' => array('search', 'visible'), 'compare' => 'IN', ), 2 => array( 'relation' => 'OR', array( 'key' => '_visibility', 'value' => array('search', 'visible'), 'compare' => 'IN', ), ), ); // Exclude out of stock products from suggestions if ( DGWT_WCAS()->settings->getOption( 'exclude_out_of_stock' ) === 'on' ) { $meta_query[] = array( 'key' => '_stock_status', 'value' => 'outofstock', 'compare' => 'NOT IN', ); } return $meta_query; } /** * Get tax query * For WooCommerce >= 3.0 * * return array */ private function getTaxQuery() { $product_visibility_term_ids = wc_get_product_visibility_term_ids(); $tax_query = array( 'relation' => 'AND', ); $tax_query[] = array( 'taxonomy' => 'product_visibility', 'field' => 'term_taxonomy_id', 'terms' => $product_visibility_term_ids['exclude-from-search'], 'operator' => 'NOT IN', ); // Exclude out of stock products from suggestions if ( DGWT_WCAS()->settings->getOption( 'exclude_out_of_stock' ) === 'on' ) { $tax_query[] = array( 'taxonomy' => 'product_visibility', 'field' => 'term_taxonomy_id', 'terms' => $product_visibility_term_ids['outofstock'], 'operator' => 'NOT IN', ); } return $tax_query; } /** * Search for matching category * * @param string $keyword * @param int $limit * * @return array */ public function getCategories( $keyword, $limit = 3 ) { $results = array( 'total' => 0, 'items' => array(), ); $args = array( 'taxonomy' => 'product_cat', ); $productCategories = get_terms( 'product_cat', apply_filters( 'dgwt/wcas/search/product_cat/args', $args ) ); $keywordUnslashed = wp_unslash( $keyword ); // Compare keyword and term name $i = 0; foreach ( $productCategories as $cat ) { if ( $i < $limit ) { $catName = html_entity_decode( $cat->name ); $pos = strpos( mb_strtolower( remove_accents( Helpers::removeGreekAccents( $catName ) ) ), mb_strtolower( remove_accents( Helpers::removeGreekAccents( $keywordUnslashed ) ) ) ); if ( $pos !== false ) { $results['total']++; $termLang = Multilingual::getTermLang( $cat->term_id, 'product_cat' ); $results['items'][$i] = array( 'term_id' => $cat->term_id, 'taxonomy' => 'product_cat', 'value' => $catName, 'url' => get_term_link( $cat, 'product_cat' ), 'breadcrumbs' => Helpers::getTermBreadcrumbs( $cat->term_id, 'product_cat', array(), $termLang, array($cat->term_id) ), 'type' => 'taxonomy', ); // Fix: Remove last separator if ( !empty( $results['items'][$i]['breadcrumbs'] ) ) { $results['items'][$i]['breadcrumbs'] = mb_substr( $results['items'][$i]['breadcrumbs'], 0, -3 ); } $i++; } } } return $results; } /** * Extend research in the Woo tags * * @param strong $keyword * @param int $limit * * @return array */ public function getTags( $keyword, $limit = 3 ) { $results = array( 'total' => 0, 'items' => array(), ); $args = array( 'taxonomy' => 'product_tag', ); $productTags = get_terms( 'product_tag', apply_filters( 'dgwt/wcas/search/product_tag/args', $args ) ); $keywordUnslashed = wp_unslash( $keyword ); // Compare keyword and term name $i = 0; foreach ( $productTags as $tag ) { if ( $i < $limit ) { $tagName = html_entity_decode( $tag->name ); $pos = strpos( mb_strtolower( remove_accents( Helpers::removeGreekAccents( $tagName ) ) ), mb_strtolower( remove_accents( Helpers::removeGreekAccents( $keywordUnslashed ) ) ) ); if ( $pos !== false ) { $results['total']++; $results['items'][$i] = array( 'term_id' => $tag->term_id, 'taxonomy' => 'product_tag', 'value' => $tagName, 'url' => get_term_link( $tag, 'product_tag' ), 'parents' => '', 'type' => 'taxonomy', ); $i++; } } } return $results; } /** * Search in extra fields * * @param string $search SQL * * @return string prepared SQL */ public function searchFilters( $search, $wp_query ) { global $wpdb; if ( empty( $search ) ) { return $search; // skip processing - there is no keyword } if ( $this->isAjaxSearch() ) { $q = $wp_query->query_vars; if ( $q['post_type'] !== 'product' ) { return $search; // skip processing } $n = ( !empty( $q['exact'] ) ? '' : '%' ); $search = $searchand = ''; if ( !empty( $q['search_terms'] ) ) { foreach ( (array) $q['search_terms'] as $term ) { $like = $n . $wpdb->esc_like( $term ) . $n; $search .= "{$searchand} ("; // Search in title if ( in_array( 'title', $this->searchIn ) ) { $search .= $wpdb->prepare( "({$wpdb->posts}.post_title LIKE %s)", $like ); } else { $search .= "(0 = 1)"; } // Search in content if ( DGWT_WCAS()->settings->getOption( 'search_in_product_content' ) === 'on' && in_array( 'content', $this->searchIn ) ) { $search .= $wpdb->prepare( " OR ({$wpdb->posts}.post_content LIKE %s)", $like ); } // Search in excerpt if ( DGWT_WCAS()->settings->getOption( 'search_in_product_excerpt' ) === 'on' && in_array( 'excerpt', $this->searchIn ) ) { $search .= $wpdb->prepare( " OR ({$wpdb->posts}.post_excerpt LIKE %s)", $like ); } // Search in SKU if ( DGWT_WCAS()->settings->getOption( 'search_in_product_sku' ) === 'on' && in_array( 'sku', $this->searchIn ) ) { $search .= $wpdb->prepare( " OR (dgwt_wcasmsku.meta_key='_sku' AND dgwt_wcasmsku.meta_value LIKE %s)", $like ); } $search = apply_filters( 'dgwt/wcas/native/search_query/search_or', $search, $like, $this ); $search .= ")"; $searchand = ' AND '; } } if ( !empty( $search ) ) { $search = " AND ({$search}) "; if ( !is_user_logged_in() ) { $search .= " AND ({$wpdb->posts}.post_password = '') "; } } } return $search; } /** * @param $where * * @return string */ public function searchDistinct( $where ) { if ( $this->isAjaxSearch() ) { return 'DISTINCT'; } return $where; } /** * Join the postmeta column in the search posts SQL */ public function searchFiltersJoin( $join, $query ) { global $wpdb; if ( empty( $query->query_vars['post_type'] ) || $query->query_vars['post_type'] !== 'product' ) { return $join; // skip processing } if ( $this->isAjaxSearch() ) { if ( DGWT_WCAS()->settings->getOption( 'search_in_product_sku' ) === 'on' && in_array( 'sku', $this->searchIn ) ) { $join .= " INNER JOIN {$wpdb->postmeta} AS dgwt_wcasmsku ON ( {$wpdb->posts}.ID = dgwt_wcasmsku.post_id )"; } $join = apply_filters( 'dgwt/wcas/native/search_query/join', $join ); } return $join; } /** * Corrects the search by excerpt if necessary. * WooCommerce adds search in excerpt by defaults and this should be corrected. * * @param string $where * * @return string * @since 1.1.4 * */ public function fixWooExcerptSearch( $where ) { global $wp_the_query; // If this is not a WC Query, do not modify the query if ( empty( $wp_the_query->query_vars['wc_query'] ) || empty( $wp_the_query->query_vars['s'] ) ) { return $where; } if ( DGWT_WCAS()->settings->getOption( 'search_in_product_excerpt' ) !== 'on' && in_array( 'excerpt', $this->searchIn ) ) { $where = preg_replace( "/OR \\(post_excerpt\\s+LIKE\\s*(\\'\\%[^\\%]+\\%\\')\\)/", "", $where ); } return $where; } /** * Disable cache results and narrowing search results to those from our engine * * @param \WP_Query $query */ public function overwriteSearchPage( $query ) { if ( !Helpers::isSearchQuery( $query ) ) { return; } if ( $this->hooked ) { return; } /** * Allowing hook WP_Query more then once * * @since 1.26.0 */ if ( apply_filters( 'dgwt/wcas/native/hook_query_once', true ) ) { $this->hooked = true; } /** * Disable cache: `cache_results` defaults to false but can be enabled */ $query->set( 'cache_results', false ); if ( !empty( $query->query['cache_results'] ) ) { $query->set( 'cache_results', true ); } $query->set( 'dgwt_wcas', $query->query_vars['s'] ); $phrase = $query->query_vars['s']; // Break early if keyword contains blacklisted phrase. if ( Helpers::phraseContainsBlacklistedTerm( $phrase ) ) { header( 'X-Robots-Tag: noindex' ); http_response_code( 400 ); exit; } $orderby = 'post__in'; $order = 'desc'; if ( !empty( $query->query_vars['orderby'] ) ) { $orderby = ( $query->query_vars['orderby'] === 'relevance' ? 'post__in' : $query->query_vars['orderby'] ); } if ( !empty( $query->query_vars['order'] ) ) { $order = strtolower( $query->query_vars['order'] ); } $postIn = array(); $searchResults = $this->getSearchResults( $phrase, true, 'product-ids' ); foreach ( $searchResults['suggestions'] as $suggestion ) { $postIn[] = $suggestion->ID; } // Integration with FiboFilters. if ( $query->get( 'fibofilters' ) ) { $postIn = array_intersect( $query->get( 'post__in' ), $postIn ); } // Save for later use $this->postsIDsBuffer = $postIn; $query->set( 'orderby', $orderby ); $query->set( 'order', $order ); $query->set( 'post__in', $postIn ); // Resetting the key 's' to disable the default search logic. $query->set( 's', '' ); } /** * Check if is ajax search processing * * @return bool * @since 1.1.3 * */ public function isAjaxSearch() { if ( defined( 'DGWT_WCAS_AJAX' ) && DGWT_WCAS_AJAX ) { return true; } return false; } /** * Headline output structure * * @return array */ public function headlineBody( $headline ) { return array( 'value' => $headline, 'type' => 'headline', ); } /** * Check if the query retuns resutls * * @return bool */ public function hasResults() { $hasResults = false; foreach ( $this->groups as $group ) { if ( !empty( $group['results'] ) ) { $hasResults = true; break; } } return $hasResults; } /** * Calc free slots * * @return int */ public function calcFreeSlots() { $slots = 0; foreach ( $this->groups as $key => $group ) { if ( !empty( $group['limit'] ) ) { $slots = $slots + absint( $group['limit'] ); } } return $slots; } /** * Apply flexible limits * * @return void */ public function applyFlexibleLimits() { $slots = $this->totalLimit; $total = 0; $groups = 0; foreach ( $this->groups as $key => $group ) { if ( !empty( $this->groups[$key]['results'] ) ) { $total = $total + count( $this->groups[$key]['results'] ); $groups++; } } $toRemove = ( $total >= $slots ? $total - $slots : 0 ); if ( $toRemove > 0 ) { for ($i = 0; $i < $toRemove; $i++) { $largestGroupCount = 0; $largestGroupKey = 'product'; foreach ( $this->groups as $key => $group ) { if ( !empty( $this->groups[$key]['results'] ) ) { $thisGroupTotal = count( $this->groups[$key]['results'] ); if ( $thisGroupTotal > $largestGroupCount ) { $largestGroupCount = $thisGroupTotal; $largestGroupKey = $key; } } } $last = count( $this->groups[$largestGroupKey]['results'] ) - 1; if ( isset( $this->groups[$largestGroupKey]['results'][$last] ) ) { unset($this->groups[$largestGroupKey]['results'][$last]); } } } } /** * Prepare suggestions based on groups * * @return array */ public function convertGroupsToSuggestions() { $suggestions = array(); $totalHeadlines = 0; foreach ( $this->groups as $key => $group ) { if ( !empty( $group['results'] ) ) { if ( $this->showHeadings ) { $suggestions[] = $this->headlineBody( $key ); $totalHeadlines++; } foreach ( $group['results'] as $result ) { $suggestions[] = $result; } } } // Remove products headline when there are only product type suggestion if ( $totalHeadlines === 1 ) { $i = 0; $unset = false; foreach ( $suggestions as $key => $suggestion ) { if ( !empty( $suggestion['type'] ) && $suggestion['type'] === 'headline' && $suggestion['value'] === 'product' ) { unset($suggestions[$i]); $unset = true; break; } $i++; } if ( $unset ) { $suggestions = array_values( $suggestions ); } } return $suggestions; } /** * Order of the search resutls groups * * @return array */ public function searchResultsGroups() { $groups = array(); if ( DGWT_WCAS()->settings->getOption( 'show_product_tax_product_cat' ) === 'on' ) { $groups['tax_product_cat'] = array( 'limit' => 3, ); } if ( DGWT_WCAS()->settings->getOption( 'show_product_tax_product_tag' ) === 'on' ) { $groups['tax_product_tag'] = array( 'limit' => 3, ); } $groups['product'] = array( 'limit' => 7, ); return apply_filters( 'dgwt/wcas/search_groups', $groups ); } /** * Allow to get the ID of products that have been found * * @param integer[] $postsIDs * * @return mixed */ public function getProductIds( $postsIDs ) { if ( $this->postsIDsBuffer !== null ) { return $this->postsIDsBuffer; } return $postsIDs; } /** * Add taxonomies labels * * @param array $labels Labels used at frontend * * @return array */ public function setTaxonomiesLabels( $labels ) { $labels['tax_product_cat_plu'] = __( 'Categories', 'woocommerce' ); $labels['tax_product_cat'] = __( 'Category', 'woocommerce' ); $labels['tax_product_tag_plu'] = __( 'Tags' ); $labels['tax_product_tag'] = __( 'Tag' ); return $labels; } /** * Backward compatibility for labels * * Full taxonomy names for categories and tags. All with prefix 'tax_'. * * @param array $labels Labels used at frontend * * @return array */ public function fixTaxonomiesLabels( $labels ) { // Product category. Old: 'category', 'product_cat_plu'. if ( isset( $labels['category'] ) ) { $labels['tax_product_cat'] = $labels['category']; unset($labels['category']); } if ( isset( $labels['product_cat_plu'] ) ) { $labels['tax_product_cat_plu'] = $labels['product_cat_plu']; unset($labels['product_cat_plu']); } // Product tag. Old: 'tag', 'product_tag_plu'. if ( isset( $labels['tag'] ) ) { $labels['tax_product_tag'] = $labels['tag']; unset($labels['tag']); } if ( isset( $labels['product_tag_plu'] ) ) { $labels['tax_product_tag_plu'] = $labels['product_tag_plu']; unset($labels['product_tag_plu']); } return $labels; } /** * Add language to WC endpoint if Polylang is active * * @param $url * @param $request * * @return string * @see polylang-wc/frontend/frontend.php:306 */ public function fixPolylangWooEndpoint( $url, $request ) { if ( PLL() instanceof \PLL_Frontend ) { // Remove wc-ajax to avoid the value %%endpoint%% to be encoded by add_query_arg (used in plain permalinks). $url = remove_query_arg( 'wc-ajax', $url ); $url = PLL()->links_model->switch_language_in_link( $url, PLL()->curlang ); return add_query_arg( 'wc-ajax', $request, $url ); } return $url; } /** * Get empty search output * * @return array */ private function getEmptyOutput() { $output = array( 'engine' => 'free', 'suggestions' => array(), 'time' => '0 sec', 'total' => 0, 'v' => DGWT_WCAS_VERSION, ); return $output; } }