Making WordPress.org

Changeset 3240


Ignore:
Timestamp:
05/24/2016 10:30:27 PM (10 years ago)
Author:
coffee2code
Message:

developer.wordpress.org: Add inc/search.php to house search-related functionality and move such functionality out of functions.php.

Props keesiemeijer.
See #1671.

Location:
sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-developer
Files:
1 added
1 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-developer/functions.php

    r3051 r3240  
    7575 */
    7676require __DIR__ . '/inc/autocomplete.php';
     77
     78/**
     79 * Search query.
     80 */
     81require __DIR__ . '/inc/search.php';
    7782
    7883/**
     
    98103    add_filter( 'post_type_link', __NAMESPACE__ . '\\method_permalink', 9, 2 );
    99104    add_filter( 'term_link', __NAMESPACE__ . '\\taxonomy_permalink', 10, 3 );
    100     add_filter( 'posts_orderby', __NAMESPACE__ . '\\search_posts_orderby', 10, 2 );
    101     add_filter( 'the_posts', __NAMESPACE__ . '\\rerun_empty_exact_search', 10, 2 );
    102105
    103106    add_theme_support( 'automatic-feed-links' );
     
    193196function pre_get_posts( $query ) {
    194197
    195     if ( $query->is_main_query() && ( $query->is_post_type_archive() || $query->is_search() ) ) {
     198    if ( $query->is_main_query() && $query->is_post_type_archive() ) {
    196199        $query->set( 'orderby', 'title' );
    197200        $query->set( 'order', 'ASC' );
     
    202205    }
    203206
    204     if ( $query->is_search() ) {
    205 
    206         // If user has '()' at end of a search string, assume they want a specific function/method.
    207         $s = htmlentities( $query->get( 's' ) );
    208         if ( '()' === substr( $s, -2 ) ) {
    209             // Enable exact search
    210             $query->set( 'exact',     true );
    211             // Modify the search query to omit the parentheses
    212             $query->set( 's',         substr( $s, 0, -2 ) ); // remove '()'
    213             // Restrict search to function-like content
    214             $query->set( 'post_type', array( 'wp-parser-function', 'wp-parser-method' ) );
    215         }
    216     }
    217 }
    218 
    219 /**
    220  * Filter the SQL for the ORDER BY clause for search queries.
    221  *
    222  * Adds ORDER BY condition with spaces replaced with underscores in 'post_title'.
    223  * Adds ORDER BY condition to order by title length.
    224  *
    225  * @param string   $orderby The ORDER BY clause of the query.
    226  * @param WP_Query $query   The WP_Query instance (passed by reference).
    227  * @return string  Filtered order by clause
    228  */
    229 function search_posts_orderby( $orderby, $query ) {
    230     global $wpdb;
    231 
    232     if ( $query->is_main_query() && is_search() && ! $query->get( 'exact' ) ) {
    233 
    234         $search_order_by_title = $query->get( 'search_orderby_title' );
    235 
    236         // Check if search_orderby_title is set by WP_Query::parse_search.
    237         if ( is_array( $search_order_by_title ) && $search_order_by_title ) {
    238 
    239             // Get search orderby query.
    240             $orderby = parse_search_order( $query->query_vars );
    241 
    242             // Add order by title length.
    243             $orderby .= " , CHAR_LENGTH( $wpdb->posts.post_title ) ASC, $wpdb->posts.post_title ASC";
    244         }
    245     }
    246 
    247     return $orderby;
    248 }
    249 
    250 /**
    251  * Generate SQL for the ORDER BY condition based on passed search terms.
    252  *
    253  * Similar to WP_Query::parse_search_order.
    254  * Adds ORDER BY condition with spaces replaced with underscores in 'post_title'.
    255  *
    256  * @global wpdb $wpdb WordPress database abstraction object.
    257  *
    258  * @param array   $q Query variables.
    259  * @return string ORDER BY clause.
    260  */
    261 function parse_search_order( $q ) {
    262     global $wpdb;
    263 
    264     if ( $q['search_terms_count'] > 1 ) {
    265         $num_terms = count( $q['search_orderby_title'] );
    266 
    267         // If the search terms contain negative queries, don't bother ordering by sentence matches.
    268         $like = $_like = '';
    269         if ( ! preg_match( '/(?:\s|^)\-/', $q['s'] ) ) {
    270             $like = '%' . $wpdb->esc_like( $q['s'] ) . '%';
    271         }
    272 
    273         $search_orderby = '';
    274 
    275         // Sentence match in 'post_title'.
    276         if ( $like ) {
    277             $search_orderby .= $wpdb->prepare( "WHEN $wpdb->posts.post_title LIKE %s THEN 1 ", $like );
    278             $_like =  str_replace( '-', '_', sanitize_title_with_dashes( $q['s'] ) );
    279             $_like = '%' . $wpdb->esc_like( $_like ) . '%';
    280             if ( $_like !== $like ) {
    281                 // Sentence match in 'post_title' with spaces replaced with underscores.
    282                 $search_orderby .= $wpdb->prepare( "WHEN $wpdb->posts.post_title LIKE %s THEN 2 ", $_like );
    283             }
    284         }
    285 
    286         // Sanity limit, sort as sentence when more than 6 terms.
    287         // (few searches are longer than 6 terms and most titles are not)
    288         if ( $num_terms < 7 ) {
    289             // all words in title
    290             $search_orderby .= 'WHEN ' . implode( ' AND ', $q['search_orderby_title'] ) . ' THEN 3 ';
    291             // any word in title, not needed when $num_terms == 1
    292             if ( $num_terms > 1 )
    293                 $search_orderby .= 'WHEN ' . implode( ' OR ', $q['search_orderby_title'] ) . ' THEN 4 ';
    294         }
    295 
    296         // Sentence match in 'post_content'.
    297         if ( $like ) {
    298             $search_orderby .= $wpdb->prepare( "WHEN $wpdb->posts.post_content LIKE %s THEN 5 ", $like );
    299         }
    300 
    301         if ( $search_orderby ) {
    302             $search_orderby = '(CASE ' . $search_orderby . 'ELSE 6 END)';
    303         }
    304     } else {
    305         // Single word or sentence search.
    306         $search_orderby = reset( $q['search_orderby_title'] ) . ' DESC';
    307     }
    308 
    309     return $search_orderby;
    310 }
    311 
    312 /**
    313  * Rerun an exact search with the same criteria except exactness if no posts
    314  * were found.
    315  *
    316  * @access public
    317  *
    318  * @param  array    $posts Array of posts after the main query
    319  * @param  WP_Query $query WP_Query object
    320  * @return array
    321  */
    322 function rerun_empty_exact_search( $posts, $query ) {
    323     if ( is_search() && true === $query->get( 'exact' ) && ! $query->found_posts ) {
    324         $query->set( 'exact', false );
    325         $posts = $query->get_posts();
    326     }
    327     return $posts;
     207    // For search query modifications see DevHub_Search.
    328208}
    329209
Note: See TracChangeset for help on using the changeset viewer.