Ticket #1671: 1671.1.patch
| File 1671.1.patch, 18.0 KB (added by , 10 years ago) |
|---|
-
sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-developer/functions.php
76 76 require __DIR__ . '/inc/autocomplete.php'; 77 77 78 78 /** 79 * Search query. 80 */ 81 require __DIR__ . '/inc/search.php'; 82 83 /** 79 84 * Set the content width based on the theme's design and stylesheet. 80 85 */ 81 86 if ( ! isset( $content_width ) ) { … … 97 102 98 103 add_filter( 'post_type_link', __NAMESPACE__ . '\\method_permalink', 10, 2 ); 99 104 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 );102 105 103 106 add_theme_support( 'automatic-feed-links' ); 104 107 add_theme_support( 'post-thumbnails' ); … … 201 204 $query->set( 'wp-parser-source-file', str_replace( array( '.php', '/' ), array( '-php', '_' ), $query->query['wp-parser-source-file'] ) ); 202 205 } 203 206 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() 217 208 } 218 209 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 clause228 */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 title290 $search_orderby .= 'WHEN ' . implode( ' AND ', $q['search_orderby_title'] ) . ' THEN 3 ';291 // any word in title, not needed when $num_terms == 1292 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 posts314 * were found.315 *316 * @access public317 *318 * @param array $posts Array of posts after the main query319 * @param WP_Query $query WP_Query object320 * @return array321 */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 330 210 function register_nav_menus() { 331 211 332 212 \register_nav_menus( array( -
sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-developer/inc/search.php
1 <?php 2 /** 3 * Search query customization 4 * 5 * @package wporg-developer 6 */ 7 8 /** 9 * Class to handle search queries. 10 */ 11 class DevHub_Search { 12 13 14 public function __construct() { 15 $this->init(); 16 } 17 18 /** 19 * Initialization 20 * 21 * @access public 22 */ 23 public function init() { 24 add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ), 20 ); 25 add_filter( 'posts_orderby', array( $this, 'search_posts_orderby' ), 10, 2 ); 26 add_filter( 'the_posts', array( $this, 'rerun_empty_exact_search' ), 10, 2 ); 27 add_filter( 'query_vars', array( $this, 'search_post_types' ) ); 28 } 29 30 /** 31 * Add query var to determine if filters were used for a search. 32 * 33 * @param array $public_query_vars The array of whitelisted query variables. 34 * @return array [description] 35 */ 36 public function search_post_types( $public_query_vars ) { 37 $public_query_vars['empty_post_type_search'] = false; 38 return $public_query_vars; 39 } 40 41 42 /** 43 * 44 * 45 * @param \WP_Query $query 46 */ 47 function pre_get_posts( $query ) { 48 49 if ( !( !is_admin() && $query->is_main_query() && $query->is_search() ) ) { 50 return; 51 } 52 53 // If user has '()' at end of a search string, assume they want a specific function/method. 54 $s = htmlentities( $query->get( 's' ) ); 55 if ( '()' === substr( $s, -2 ) ) { 56 // Enable exact search 57 $query->set( 'exact', true ); 58 // Modify the search query to omit the parentheses 59 $query->set( 's', substr( $s, 0, -2 ) ); // remove '()' 60 // Restrict search to function-like content 61 $query->set( 'post_type', array( 'wp-parser-function', 'wp-parser-method' ) ); 62 } 63 64 // Get post types (if used) 65 $qv_post_types = array_filter( (array) $query->get( 'post_type' ) ); 66 $qv_post_types = array_map( 'sanitize_key', $qv_post_types ); 67 68 if ( empty( $qv_post_types ) ) { 69 $query->set( 'empty_post_type_search', true ); 70 // get post types to search in if none were used. 71 $qv_post_types = DevHub\get_search_post_types(); 72 } 73 74 if ( !empty( $qv_post_types ) ) { 75 $query->set( 'post_type', $qv_post_types ); 76 } 77 } 78 79 /** 80 * Filter the SQL for the ORDER BY clause for search queries. 81 * 82 * Adds ORDER BY condition with spaces replaced with underscores in 'post_title'. 83 * Adds ORDER BY condition to order by title length. 84 * 85 * @param string $orderby The ORDER BY clause of the query. 86 * @param WP_Query $query The WP_Query instance (passed by reference). 87 * @return string Filtered order by clause 88 */ 89 function search_posts_orderby( $orderby, $query ) { 90 global $wpdb; 91 92 if ( $query->is_main_query() && is_search() && ! $query->get( 'exact' ) ) { 93 94 $search_order_by_title = $query->get( 'search_orderby_title' ); 95 96 // Check if search_orderby_title is set by WP_Query::parse_search. 97 if ( is_array( $search_order_by_title ) && $search_order_by_title ) { 98 99 // Get search orderby query. 100 $orderby = $this->parse_search_order( $query->query_vars ); 101 102 // Add order by title length. 103 $orderby .= " , CHAR_LENGTH( $wpdb->posts.post_title ) ASC, $wpdb->posts.post_title ASC"; 104 } 105 } 106 107 return $orderby; 108 } 109 110 /** 111 * Generate SQL for the ORDER BY condition based on passed search terms. 112 * 113 * Similar to WP_Query::parse_search_order. 114 * Adds ORDER BY condition with spaces replaced with underscores in 'post_title'. 115 * 116 * @global wpdb $wpdb WordPress database abstraction object. 117 * 118 * @param array $q Query variables. 119 * @return string ORDER BY clause. 120 */ 121 function parse_search_order( $q ) { 122 global $wpdb; 123 124 if ( $q['search_terms_count'] > 1 ) { 125 $num_terms = count( $q['search_orderby_title'] ); 126 127 // If the search terms contain negative queries, don't bother ordering by sentence matches. 128 $like = $_like = ''; 129 if ( ! preg_match( '/(?:\s|^)\-/', $q['s'] ) ) { 130 $like = '%' . $wpdb->esc_like( $q['s'] ) . '%'; 131 } 132 133 $search_orderby = ''; 134 135 // Sentence match in 'post_title'. 136 if ( $like ) { 137 $search_orderby .= $wpdb->prepare( "WHEN $wpdb->posts.post_title LIKE %s THEN 1 ", $like ); 138 $_like = str_replace( '-', '_', sanitize_title_with_dashes( $q['s'] ) ); 139 $_like = '%' . $wpdb->esc_like( $_like ) . '%'; 140 if ( $_like !== $like ) { 141 // Sentence match in 'post_title' with spaces replaced with underscores. 142 $search_orderby .= $wpdb->prepare( "WHEN $wpdb->posts.post_title LIKE %s THEN 2 ", $_like ); 143 } 144 } 145 146 // Sanity limit, sort as sentence when more than 6 terms. 147 // (few searches are longer than 6 terms and most titles are not) 148 if ( $num_terms < 7 ) { 149 // all words in title 150 $search_orderby .= 'WHEN ' . implode( ' AND ', $q['search_orderby_title'] ) . ' THEN 3 '; 151 // any word in title, not needed when $num_terms == 1 152 if ( $num_terms > 1 ) 153 $search_orderby .= 'WHEN ' . implode( ' OR ', $q['search_orderby_title'] ) . ' THEN 4 '; 154 } 155 156 // Sentence match in 'post_content'. 157 if ( $like ) { 158 $search_orderby .= $wpdb->prepare( "WHEN $wpdb->posts.post_content LIKE %s THEN 5 ", $like ); 159 } 160 161 if ( $search_orderby ) { 162 $search_orderby = '(CASE ' . $search_orderby . 'ELSE 6 END)'; 163 } 164 } else { 165 // Single word or sentence search. 166 $search_orderby = reset( $q['search_orderby_title'] ) . ' DESC'; 167 } 168 169 return $search_orderby; 170 } 171 172 /** 173 * Rerun an exact search with the same criteria except exactness if no posts 174 * were found. 175 * 176 * @access public 177 * 178 * @param array $posts Array of posts after the main query 179 * @param WP_Query $query WP_Query object 180 * @return array 181 */ 182 function rerun_empty_exact_search( $posts, $query ) { 183 if ( is_search() && true === $query->get( 'exact' ) && ! $query->found_posts ) { 184 $query->set( 'exact', false ); 185 $posts = $query->get_posts(); 186 } 187 return $posts; 188 } 189 190 } 191 192 $search = new DevHub_Search(); -
sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-developer/inc/template-tags.php
380 380 } 381 381 382 382 /** 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 /** 383 472 * Get site section root URL based on URL path. 384 473 * 385 474 * @return string -
sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-developer/js/autocomplete.js
11 11 return; 12 12 } 13 13 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 ), 16 20 processing = false, 17 21 search = ''; 18 22 -
sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-developer/searchform.php
32 32 ?></div> 33 33 34 34 <?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" ) ); ?>"> 37 41 <div> 38 42 <label> 39 43 <label for="search-field" class="screen-reader-text"><?php _ex( 'Search for:', 'label', 'wporg' ); ?></label> … … 41 45 </label> 42 46 <input type="submit" class="shiny-blue search-submit" value="<?php echo esc_attr_x( 'Search', 'submit button', 'wporg' ); ?>"> 43 47 </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 ); 44 58 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'); 56 61 57 if ( ! is_search() || in_array( 'any', $qv_post_type )) {58 // no filters used59 $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 ?> 65 70 <label><input type="checkbox" name="post_type[]" value="<?php echo esc_attr( $post_type ); ?>" 66 71 <?php echo $checked; ?> /> <?php echo $label; ?></label> 67 <?php } ?> 68 </div> 72 <?php } ?> 73 </div> 74 <?php endif; ?> 69 75 </form> 70 76 71 77 </div><!-- /search-guide -->