Making WordPress.org

Ticket #1671: 1671.patch

File 1671.patch, 11.8 KB (added by keesiemeijer, 10 years ago)

Search with section specific post types

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

     
    7676require __DIR__ . '/inc/autocomplete.php';
    7777
    7878/**
     79 * Search query.
     80 */
     81require __DIR__ . '/inc/search.php';
     82
     83/**
    7984 * Set the content width based on the theme's design and stylesheet.
    8085 */
    8186if ( ! isset( $content_width ) ) {
     
    97102
    98103        add_filter( 'post_type_link', __NAMESPACE__ . '\\method_permalink', 10, 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' );
    104107        add_theme_support( 'post-thumbnails' );
     
    201204                $query->set( 'wp-parser-source-file', str_replace( array( '.php', '/' ), array( '-php', '_' ), $query->query['wp-parser-source-file'] ) );
    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         }
     207        // For search queries see DevHub_Search::pre_get_posts()
    217208}
    218209
    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;
    328 }
    329 
    330210function register_nav_menus() {
    331211
    332212        \register_nav_menus( array(
  • sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-developer/inc/template-tags.php

     
    380380        }
    381381
    382382        /**
     383         * Checks if the current page is a handbook page.
     384         *
     385         * @param  string  $post_type Optional. Handbook post type.
     386         * @return boolean            True if the current page is a handbook post type page.
     387         */
     388        function is_handbook( $post_type = '' ) {
     389                global $wp_rewrite;
     390
     391                $handbooks = get_handbook_post_types();
     392
     393                if ( is_admin() || empty( $handbooks ) ) {
     394                        return false;
     395                }
     396
     397                $path = trailingslashit( $_SERVER['REQUEST_URI'] );
     398
     399                foreach ( $handbooks as $handbook ) {
     400
     401                        if ( $wp_rewrite->using_permalinks() ) {
     402
     403                                // plugins or themes (plural)
     404                                $struct = str_replace( '-handbook' , 's', $handbook );
     405                                $struct = preg_quote( $struct, '/' );
     406
     407                                // match handbook. e.g. /plugins/ or /plugins? or /plugins#
     408                                if ( preg_match("/^\/{$struct}[\/|?|#]/", $path, $matches )  ) {
     409                                        if ( !$post_type || ( $handbook === $post_type ) ) {
     410                                                return true;
     411                                        }
     412                                }
     413                        } else {
     414                                $qv_post_type = get_query_var( 'post_type' );
     415                                if ( ( $qv_post_type === $handbook ) || ( $qv_post_type === $post_type ) ) {
     416                                        return true;
     417                                }
     418                        }
     419                }
     420
     421                return false;
     422        }
     423
     424        /**
     425         * Get the curent handbook post type.
     426         * 
     427         * @return string|bool Post type or false if current page is not a handbook page.
     428         */
     429        function get_current_handbook_post_type() {
     430                $handbooks = get_handbook_post_types();
     431                foreach ( $handbooks as $handbook ) {
     432                        if ( is_handbook( $handbook ) ) {
     433                                return $handbook;
     434                        }
     435                }
     436
     437                return false;
     438        }
     439
     440        /**
     441         * Get all handbook post types.
     442         *
     443         * @return array Array with handbook post type names.
     444         */
     445        function get_handbook_post_types() {
     446                if ( !class_exists( '\WPorg_Handbook_Init' ) ) {
     447                        return array();
     448                }
     449
     450                $post_types = \WPorg_Handbook_Init::get_post_types();
     451                $post_types = array_map( function( $value ) { return $value . '-handbook'; }, $post_types );
     452
     453                return $post_types;
     454        }
     455
     456        /**
     457         * Returns post types to search in depending on the site section.
     458         * Site sections used are handbooks or reference.
     459         *
     460         * @return array Array with post types.
     461         */
     462        function get_search_post_types() {
     463                if ( is_handbook() ) {
     464                        $post_types = get_current_handbook_post_type();
     465                } else {
     466                        $post_types = get_parsed_post_types();
     467                }
     468                return $post_types;
     469        }
     470
     471        /**
    383472         * Get site section root URL based on URL path.
    384473         *
    385474         * @return string
  • sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-developer/js/autocomplete.js

     
    1111                return;
    1212        }
    1313
    14         var form = $( '.searchform' ),
    15                 searchfield = $( '#search-field', form ),
     14        var form = $( '.searchform' ).not(".searchform-handbook");
     15        if( !form.length ) {
     16                return;
     17        }
     18       
     19        var     searchfield = $( '#search-field', form ),
    1620                processing = false,
    1721                search = '';
    1822
  • sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-developer/searchform.php

     
    3232        ?></div>
    3333
    3434<?php } ?>
    35 
    36         <form role="search" method="get" class="searchform" action="<?php echo esc_url( home_url( '/' ) ); ?>">
     35<?php
     36        $handbook = DevHub\get_current_handbook_post_type();
     37        $handbook = $handbook ? str_replace( '-handbook' , 's/', $handbook ) : '';
     38        $class    = $handbook ? ' searchform-handbook' : '';
     39?>
     40        <form role="search" method="get" class="searchform<?php echo $class ?>" action="<?php echo esc_url( home_url( "/$handbook" ) ); ?>">
    3741                <div>
    3842                <label>
    3943                        <label for="search-field" class="screen-reader-text"><?php _ex( 'Search for:', 'label', 'wporg' ); ?></label>
     
    4145                </label>
    4246                <input type="submit" class="shiny-blue search-submit" value="<?php echo esc_attr_x( 'Search', 'submit button', 'wporg' ); ?>">
    4347                </div>
     48                <?php if( !$handbook ) : ?>
     49                        <div class="search-post-type">
     50                                <span><?php _e( 'Filter by type:', 'wporg' ); ?></span>
     51                                <?php
     52                                        $search_post_types = array(
     53                                                'wp-parser-function' => __( 'Functions', 'wporg' ),
     54                                                'wp-parser-hook'     => __( 'Hooks',     'wporg' ),
     55                                                'wp-parser-class'    => __( 'Classes',   'wporg' ),
     56                                                'wp-parser-method'   => __( 'Methods',   'wporg' ),
     57                                        );
    4458
    45                 <div class="search-post-type">
    46                         <span><?php _e( 'Filter by type:', 'wporg' ); ?></span>
    47                         <?php
    48                                 $search_post_types = array(
    49                                         'wp-parser-function' => __( 'Functions', 'wporg' ),
    50                                         'wp-parser-hook'     => __( 'Hooks',     'wporg' ),
    51                                         'wp-parser-class'    => __( 'Classes',   'wporg' ),
    52                                         'wp-parser-method'   => __( 'Methods',   'wporg' ),
    53                                 );
    54                                
    55                                 $qv_post_type = array_filter( (array) get_query_var( 'post_type' ) );   
     59                                        $qv_post_type = array_filter( (array) get_query_var( 'post_type' ) );
     60                                        $no_filters = get_query_var('empty_post_type_search');
    5661
    57                                 if ( ! is_search() || in_array( 'any', $qv_post_type ) ) {
    58                                         // no filters used
    59                                         $qv_post_type = array();
    60                                 }
    61                                                
    62                                 foreach ( $search_post_types as $post_type => $label ) {
    63                                         $checked = checked( in_array( $post_type, $qv_post_type ), true, false );
    64                                 ?>
     62                                        if ( ! is_search() || in_array( 'any', $qv_post_type ) || $no_filters ) {
     63                                                // no filters used
     64                                                $qv_post_type = array();
     65                                        }
     66
     67                                        foreach ( $search_post_types as $post_type => $label ) {
     68                                                $checked = checked( in_array( $post_type, $qv_post_type ), true, false );
     69                                        ?>
    6570                                                <label><input type="checkbox" name="post_type[]" value="<?php echo esc_attr( $post_type ); ?>"
    6671                                                <?php echo $checked; ?> /> <?php echo $label; ?></label>
    67                         <?php } ?>
    68                 </div>
     72                                <?php } ?>
     73                        </div>
     74                <?php endif; ?>
    6975        </form>
    7076
    7177</div><!-- /search-guide -->