Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save EricBusch/ea0dbbc6b77fef7f0cba3e523b4df021 to your computer and use it in GitHub Desktop.
Save EricBusch/ea0dbbc6b77fef7f0cba3e523b4df021 to your computer and use it in GitHub Desktop.
This code replaces the default functionality of the WordPress search form. If a search is entered into the WordPress search form, this "hijacks" the request and redirects the request to your custom search page. Then it takes the search query and passes it to the Datafeedr API. The results are returned and displayed.
<?php
/**
* THIS IS THE ONLY REQUIRED MODIFICATION!!!
*
* 1. GO HERE WordPress Admin Area > Pages > Add New
* 2. CREATE A NEW PAGE TO BE USED FOR DISPLAYING SEARCH RESULTS.
* 3. REPLACE "123" BELOW WITH THE ID OF YOUR NEW PAGE.
*
* Return the ID of the page to be used to display the search results.
*
* @return integer Page ID.
*/
function mycode_custom_search_results_page_id() {
return 123;
}
/**
* Redirects WordPress searches to our new Search Page.
*
* @see mycode_custom_search_results_page_id()
*/
add_action( 'template_redirect', 'mycode_custom_search_redirect' );
function mycode_custom_search_redirect() {
$page_id = mycode_custom_search_results_page_id();
if ( ! is_search() ) {
return;
}
if ( ! isset( $_GET['s'] ) || empty( $_GET['s'] ) ) {
return;
}
if ( ! function_exists( 'dfrapi_api' ) ) {
return;
}
if ( mycode_visitor_is_bot() ) {
return;
}
$url = add_query_arg( array(
'query' => urlencode( stripslashes_deep( $_GET['s'] ) ),
), get_permalink( $page_id ) );
wp_redirect( $url );
exit();
}
/**
* Replaces the $content on the Search Page with an WooCommerce search
* form and the results of our search.
*
* @see mycode_custom_search_results_page_id()
*
* @param string $content The content of the Search Page.
*
* @return string Updated page content.
*/
add_filter( 'the_content', 'mycode_custom_search_results' );
function mycode_custom_search_results( $content ) {
if ( mycode_visitor_is_bot() ) {
return $content;
}
$page_id = mycode_custom_search_results_page_id();
if ( ! is_page( $page_id ) ) {
return $content;
}
if ( ! in_the_loop() ) {
return $content;
}
if ( ! is_singular() ) {
return $content;
}
if ( ! is_main_query() ) {
return $content;
}
if ( ! function_exists( 'dfrapi_api' ) ) {
return $content;
}
$original_query = ( isset( $_GET['query'] ) ) ? stripslashes_deep( $_GET['query'] ) : '';
$filtered_query = mycode_custom_search_query_filter( $original_query );
$form = mycode_custom_search_form( $filtered_query ) . '<hr />';
remove_filter( current_filter(), __FUNCTION__ );
if ( empty( $filtered_query ) ) {
$content .= $form;
$content .= 'Please enter your search terms.';
return $content;
}
$products = mycode_custom_search_query( $filtered_query );
if ( is_wp_error( $products ) ) {
$content .= $form;
$content .= 'Error retrieving results from the product API. Please try again.';
return $content;
}
if ( empty( $products ) ) {
$content .= $form;
$content .= 'No results match your search.';
return $content;
}
$content .= $form . mycode_custom_search_output( $products );
return $content;
}
/**
* Add our current search query to the form's <input> value attribute.
*
* @see mycode_custom_search_query_filter(), get_product_search_form()
*
* @param string $query Query string.
*
* @return string Updated $form HTML.
*/
function mycode_custom_search_form( $query ) {
$form = get_search_form( false );
$form = str_replace( 'value=""', 'value="' . esc_attr( $query ) . '"', $form );
return $form;
}
/**
* Outputs an array of $products into HTML.
*
* @param array $products An array of $products returned by the Datafeedr API.
*
* @return string HTML of list of products.
*/
function mycode_custom_search_output( array $products ) {
$html = '';
foreach ( $products as $product ) {
$url = dfrapi_url( $product );
$name = ( isset( $product['name'] ) ) ? esc_html( $product['name'] ) : 'Product name currently not available';
$desc = ( isset( $product['description'] ) ) ? esc_html( $product['description'] ) : 'Product description currently not available';
$sale = ( '1' == $product['onsale'] ) ? true : false;
$img = ( isset( $product['image'] ) ) ? '<img src="' . $product['image'] . '" style="max-height:70px;float:left;margin: 0 10px 10px 0" />' : '';
$sign = ( isset( $product['currency'] ) ) ? dfrapi_currency_code_to_sign( $product['currency'] ) : '$';
$fprice = ( isset( $product['finalprice'] ) ) ? $sign . dfrapi_int_to_price( $product['finalprice'] ) : 'n/a';
$rprice = ( isset( $product['price'] ) ) ? $sign . dfrapi_int_to_price( $product['price'] ) : 'n/a';
$price = ( $sale ) ? '<del>' . $rprice . '</del> <strong>' . $fprice . '</strong>' : '<strong>' . $fprice . '</strong>';
$disc = ( $sale ) ? ' <span style="font-weight: bold; color: #FF8000">Save ' . $product['salediscount'] . '%</span>' : '';
$html .= '<p>';
$html .= '<a href="' . $url . '" target="_blank">' . $img . $name . '</a> ';
$html .= $price . $disc;
$html .= '<br />';
$html .= wp_trim_words( $desc, 15, '&hellip;' );
$html .= '</p>';
$html .= '<hr />';
}
return $html;
}
/**
* Queries the Datafeedr API for the given query.
*
* @see dfrapi_api()
*
* @param string $query Query string.
*
* @return array|WP_Error An array of $products or WP_Error if an error occurred.
*/
function mycode_custom_search_query( $query ) {
$api = dfrapi_api();
$merchants = (array) get_option( 'dfrapi_merchants' );
$merchant_ids = implode( ',', $merchants['ids'] );
try {
$search = $api->searchRequest();
$search->addFilter( 'any LIKE ' . $query );
$search->addFilter( 'merchant_id IN ' . $merchant_ids );
// $search->addFilter( 'onsale = 1' );
// $search->addSort( '+finalprice' );
// $search->excludeDuplicates( 'image|name merchant_id' );
$search->setLimit( '100' );
$products = $search->execute();
return $products;
} catch ( Exception $e ) {
return new WP_Error( 'failed_api_search', 'The search failed.', $e );
}
}
/**
* Modifies the search query to make it ready to be passed to the Datafeedr API "any" field.
*
* @param string $query Query string.
*
* @return string Filtered $query string.
*/
function mycode_custom_search_query_filter( $query ) {
return preg_replace( '/[^\s\d\|\"\=\-\p{L}]/u', '', trim( $query ) );
}
/**
* Returns true if current User Agent is in the $bots array. Else returns false.
*
* @link https://github.com/monperrus/crawler-user-agents/
*
* @return boolean True if visitor is bot. Else false.
*/
function mycode_visitor_is_bot() {
$user_agent = ( isset( $_SERVER['HTTP_USER_AGENT'] ) ) ? $_SERVER['HTTP_USER_AGENT'] : '';
$bots = array(
'360Spider',
'A6-Indexer',
'Aboundex',
'acoonbot',
'adbeat_bot',
'AddThis',
'Adidxbot',
'ADmantX',
'AdsBot',
'AdvBot',
'ahrefsbot',
'aihitbot',
'AISearchBot',
'antibot',
'Applebot',
'arabot',
'archive.org_bot',
'backlinkcrawler',
'baiduspider',
'betaBot',
'bibnum.bnf',
'biglotron',
'bingbot',
'BingPreview',
'binlar',
'blekkobot',
'blexbot',
'bnf.fr_bot',
'brainobot',
'BUbiNG',
'buzzbot',
'CapsuleChecker',
'careerbot',
'CC Metadata Scaper',
'ccbot',
'changedetection',
'citeseerxbot',
'Cliqzbot',
'coccoc',
'collection@infegy.com',
'content crawler spider',
'contxbot',
'convera',
'crawler4j',
'CrystalSemanticsBot',
'cXensebot',
'CyberPatrol',
'datagnionbot',
'deadlinkchecker',
'DeuSu',
'discobot',
'Domain Re-Animator Bot',
'domaincrawler',
'dotbot',
'drupact',
'DuckDuckBot',
'ec2linkfinder',
'edisterbot',
'elisabot',
'Embedly',
'europarchive.org',
'exabot',
'ezooms',
'facebook',
'facebookexternalhit',
'Facebot',
'FAST Enterprise Crawler',
'FAST-WebCrawler',
'findlink',
'findthatfile',
'findxbot',
'fluffy',
'fr-crawler',
'g00g1e.net',
'gigablast',
'gigabot',
'GingerCrawler',
'Gluten Free Crawler',
'gnam gnam spider',
'Google-Adwords-Instant',
'Googlebot',
'GrapeshotCrawler',
'grub.org',
'gslfbot',
'heritrix',
'httpunit',
'httrack',
'ia_archiver',
'ichiro',
'integromedb',
'intelium_bot',
'InterfaxScanBot',
'ip-web-crawler.com',
'ips-agent',
'iskanie',
'IstellaBot',
'it2media-domain-crawler',
'java',
'jyxobot',
'lb-spider',
'libwww',
'Linguee Bot',
'linkdex',
'linkdexbot',
'lipperhey',
'Livelapbot',
'lssbot',
'lssrocketcrawler',
'ltx71',
'Mediapartners-Google',
'MegaIndex',
'memorybot',
'MetaURI',
'MJ12bot',
'mlbot',
'MojeekBot',
'msnbot',
'msrbot',
'NerdByNature.Bot',
'nerdybot',
'netEstate NE Crawler',
'netresearchserver',
'ngbot',
'niki-bot',
'nutch',
'OpenHoseBot',
'openindexspider',
'OrangeBot',
'page2rss',
'panscient',
'phpcrawl',
'pinterest.com/bot',
'postrank',
'proximic',
'psbot',
'purebot',
'Python-urllib',
'Qwantify',
'RankActiveLinkBot',
'redditbot',
'RetrevoPageAnalyzer',
'rogerbot',
'RU_Bot',
'SafeDNSBot',
'SafeSearch microdata crawler',
'Scanbot',
'Scrapy',
'Screaming Frog SEO Spider',
'scribdbot',
'seekbot',
'SemanticScholarBot',
'SemrushBot',
'seokicks-robot',
'seznambot',
'SimpleCrawler',
'sistrix crawler',
'sitebot',
'siteexplorer.info',
'SkypeUriPreview',
'Slack-ImgProxy',
'Slackbot',
'slurp',
'smtbot',
'sogou',
'Sonic',
'spbot',
'speedy',
'summify',
'Sysomos',
'tagoobot',
'teoma',
'toplistbot',
'Trove',
'turnitinbot',
'TweetmemeBot',
'twengabot',
'Twitterbot',
'urlappendbot',
'UsineNouvelleCrawler',
'Veoozbot',
'voilabot',
'Voyager',
'wbsearchbot',
'web-archive-net.com.bot',
'webcompanycrawler',
'webcrawler',
'webmon',
'WeSEE:Search',
'WhatsApp',
'wocbot',
'woriobot',
'wotbox',
'xovibot',
'y!j-asr',
'yacybot',
'yandex.combots',
'yandexbot',
'yanga',
'yeti',
'yoozBot',
'ZoomBot',
);
foreach ( $bots as $bot ) {
if ( stripos( $user_agent, $bot ) !== false ) {
return true;
}
}
return false;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment