Changeset 3453117
- Timestamp:
- 02/03/2026 05:26:51 PM (2 months ago)
- Location:
- better-wp-search/trunk
- Files:
-
- 2 edited
-
better-wp-search.php (modified) (1 diff)
-
readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
better-wp-search/trunk/better-wp-search.php
r1347902 r3453117 1 1 <?php 2 /* /*2 /** 3 3 * Plugin Name: Better WP Search 4 * Plugin URI: http ://www.himpfen.com/better-wp-search/5 * Description: Better WP Search improves the default WordPress search functionality.6 * Version: 1. 0.04 * Plugin URI: https://www.himpfen.com/better-wp-search/ 5 * Description: Improves default WordPress search by redirecting single-result searches and canonicalizing search URLs. 6 * Version: 1.1.0 7 7 * Author: Brandon Himpfen 8 * Author URI: http ://www.himpfen.com/8 * Author URI: https://www.himpfen.com/ 9 9 * License: GPL-2.0+ 10 * License URI: http://www.gnu.org/licenses/gpl-2.0.txt 10 * License URI: https://www.gnu.org/licenses/gpl-2.0.txt 11 * Text Domain: better-wp-search 11 12 */ 12 13 13 // If there is only one search result, redirect to that post 14 function bws_redirect_single_search() { 15 if (is_search() && is_main_query()) { 16 global $wp_query; 17 if ($wp_query->post_count == 1 && $wp_query->max_num_pages == 1) { 18 wp_redirect( get_permalink( $wp_query->posts['0']->ID ) ); 19 exit; 20 } 21 } 14 if ( ! defined( 'ABSPATH' ) ) { 15 exit; 22 16 } 23 add_action('template_redirect', 'bws_redirect_single_search' ); 24 25 // Nice Search 26 // Replaes /?s=query searches to /search/query and converts %20 to + 27 // Originally created by Mark Jaquith 28 // Plugin URI: https://wordpress.org/plugins/nice-search/ 29 function bws_nice_search() { 30 global $wp_rewrite; 31 if ( !isset( $wp_rewrite ) || !is_object( $wp_rewrite ) || !$wp_rewrite->using_permalinks() ) 32 return; 33 34 $search_base = $wp_rewrite->search_base; 35 if ( is_search() && !is_admin() && strpos( $_SERVER['REQUEST_URI'], "/{$search_base}/" ) === false ) { 36 wp_redirect( home_url( "/{$search_base}/" . urlencode( get_query_var( 's' ) ) ) ); 37 exit(); 17 18 final class Better_WP_Search { 19 20 /** @var Better_WP_Search|null */ 21 private static $instance = null; 22 23 /** 24 * Boot the plugin. 25 * 26 * @return Better_WP_Search 27 */ 28 public static function instance() { 29 if ( null === self::$instance ) { 30 self::$instance = new self(); 31 } 32 return self::$instance; 33 } 34 35 private function __construct() { 36 add_action( 'template_redirect', array( $this, 'maybe_redirect_single_result' ) ); 37 add_action( 'template_redirect', array( $this, 'maybe_redirect_pretty_search' ) ); 38 } 39 40 /** 41 * Common guards: avoid redirects in contexts where they are undesirable. 42 * 43 * @return bool True if redirects are allowed for this request. 44 */ 45 private function redirects_allowed() { 46 if ( is_admin() ) { 47 return false; 48 } 49 50 if ( function_exists( 'wp_doing_ajax' ) && wp_doing_ajax() ) { 51 return false; 52 } 53 54 if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) { 55 return false; 56 } 57 58 if ( defined( 'WP_CLI' ) && WP_CLI ) { 59 return false; 60 } 61 62 if ( is_feed() || is_preview() ) { 63 return false; 64 } 65 66 /** 67 * Filter whether Better WP Search is allowed to redirect on this request. 68 * 69 * @param bool $allowed 70 */ 71 return (bool) apply_filters( 'bws_redirects_allowed', true ); 72 } 73 74 /** 75 * If there is only one search result, redirect to that post. 76 */ 77 public function maybe_redirect_single_result() { 78 if ( ! $this->redirects_allowed() ) { 79 return; 80 } 81 82 if ( ! is_search() || ! is_main_query() ) { 83 return; 84 } 85 86 /** 87 * Filter whether single-result redirects are enabled. 88 * 89 * @param bool $enabled 90 */ 91 $enabled = (bool) apply_filters( 'bws_single_result_redirect_enabled', true ); 92 if ( ! $enabled ) { 93 return; 94 } 95 96 global $wp_query; 97 98 if ( ! isset( $wp_query ) || ! is_object( $wp_query ) ) { 99 return; 100 } 101 102 if ( (int) $wp_query->post_count !== 1 || (int) $wp_query->max_num_pages !== 1 ) { 103 return; 104 } 105 106 if ( empty( $wp_query->posts ) || ! isset( $wp_query->posts[0] ) || ! is_object( $wp_query->posts[0] ) ) { 107 return; 108 } 109 110 $post_id = (int) $wp_query->posts[0]->ID; 111 if ( $post_id <= 0 ) { 112 return; 113 } 114 115 $url = get_permalink( $post_id ); 116 if ( ! $url ) { 117 return; 118 } 119 120 /** 121 * Filter the destination URL for single-result redirects. 122 * 123 * @param string $url 124 * @param int $post_id 125 */ 126 $url = (string) apply_filters( 'bws_single_result_redirect_url', $url, $post_id ); 127 128 /** 129 * Filter the HTTP status code used for single-result redirects. 130 * 131 * @param int $status Default 302. 132 */ 133 $status = (int) apply_filters( 'bws_single_result_redirect_status', 302 ); 134 135 wp_safe_redirect( esc_url_raw( $url ), $status ); 136 exit; 137 } 138 139 /** 140 * Canonicalize search URLs from /?s=query to /search/query when permalinks are enabled. 141 * 142 * Inspired by the historical "Nice Search" approach. 143 */ 144 public function maybe_redirect_pretty_search() { 145 if ( ! $this->redirects_allowed() ) { 146 return; 147 } 148 149 if ( ! is_search() || ! is_main_query() ) { 150 return; 151 } 152 153 /** 154 * Filter whether pretty search redirects are enabled. 155 * 156 * @param bool $enabled 157 */ 158 $enabled = (bool) apply_filters( 'bws_pretty_search_enabled', true ); 159 if ( ! $enabled ) { 160 return; 161 } 162 163 $search_term = get_query_var( 's' ); 164 if ( ! is_string( $search_term ) || '' === trim( $search_term ) ) { 165 return; 166 } 167 168 global $wp_rewrite; 169 if ( ! isset( $wp_rewrite ) || ! is_object( $wp_rewrite ) || ! $wp_rewrite->using_permalinks() ) { 170 return; 171 } 172 173 $search_base = isset( $wp_rewrite->search_base ) && $wp_rewrite->search_base ? $wp_rewrite->search_base : 'search'; 174 175 // If already on /search/... do nothing. 176 $request_uri = isset( $_SERVER['REQUEST_URI'] ) ? (string) $_SERVER['REQUEST_URI'] : ''; 177 $path = wp_parse_url( $request_uri, PHP_URL_PATH ); 178 $path = is_string( $path ) ? $path : ''; 179 180 // Normalize: ensure single leading slash and compare. 181 $needle = '/' . trim( $search_base, '/' ) . '/'; 182 if ( false !== strpos( $path, $needle ) ) { 183 return; 184 } 185 186 $pretty = home_url( user_trailingslashit( $search_base . '/' . rawurlencode( $search_term ) ) ); 187 188 /** 189 * Filter the pretty search redirect URL. 190 * 191 * @param string $pretty 192 * @param string $search_term 193 * @param string $search_base 194 */ 195 $pretty = (string) apply_filters( 'bws_pretty_search_url', $pretty, $search_term, $search_base ); 196 197 /** 198 * Filter the HTTP status code used for pretty search redirects. 199 * 200 * @param int $status Default 301. 201 */ 202 $status = (int) apply_filters( 'bws_pretty_search_status', 301 ); 203 204 wp_safe_redirect( esc_url_raw( $pretty ), $status ); 205 exit; 38 206 } 39 207 } 40 208 41 add_action( 'template_redirect', 'bws_nice_search' ); 42 43 // Hotfix for http://core.trac.wordpress.org/ticket/13961 for WP versions less than 3.5 44 if ( version_compare( $wp_version, '3.5', '<=' ) ) { 45 function bws_nice_search_urldecode_hotfix( $q ) { 46 if ( $q->get( 's' ) && empty( $_GET['s'] ) && is_main_query() ) 47 $q->set( 's', urldecode( $q->get( 's' ) ) ); 48 } 49 add_action( 'pre_get_posts', 'bws_nice_search_urldecode_hotfix' ); 50 } 209 Better_WP_Search::instance(); -
better-wp-search/trunk/readme.txt
r2095343 r3453117 5 5 Requires at least: 3.5.0 6 6 Tested up to: 5.2.1 7 Stable tag: 5.27 Stable tag: 1.1.0 8 8 License: GPLv2 or later 9 9 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 35 35 == Changelog == 36 36 37 = 1.1.0 = 38 * Refactor to a class-based structure. 39 * Use wp_safe_redirect() and add safety guards. 40 * Add filters for enabling/disabling and customizing redirect URLs/status codes. 41 37 42 = 1.0.0 = 38 43 * Initial commit of files.
Note: See TracChangeset
for help on using the changeset viewer.