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.