) { 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; } }