| 1 | <?php |
|---|
| 2 | /* |
|---|
| 3 | Plugin Name: Search Everything |
|---|
| 4 | Plugin URI: http://dancameron.org/wordpress/ |
|---|
| 5 | Description: Adds search functionality with little setup. Including options to search pages, excerpts, attachments, drafts, comments, tags and custom fields (metadata). Also offers the ability to exclude specific pages and posts. Does not search password-protected content. |
|---|
| 6 | Version: 4.7.6.2 |
|---|
| 7 | Author: Dan Cameron |
|---|
| 8 | Author URI: http://dancameron.org/ |
|---|
| 9 | */ |
|---|
| 10 | |
|---|
| 11 | /* |
|---|
| 12 | This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. |
|---|
| 13 | |
|---|
| 14 | This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
|---|
| 15 | */ |
|---|
| 16 | |
|---|
| 17 | if ( !defined('WP_CONTENT_DIR') ) |
|---|
| 18 | define( 'WP_CONTENT_DIR', ABSPATH . 'wp-content' ); |
|---|
| 19 | define('SE_ABSPATH', WP_CONTENT_DIR.'/plugins/' . dirname(plugin_basename(__FILE__)) . '/'); |
|---|
| 20 | |
|---|
| 21 | $SE = new SearchEverything(); |
|---|
| 22 | //add filters based upon option settings |
|---|
| 23 | |
|---|
| 24 | Class SearchEverything { |
|---|
| 25 | |
|---|
| 26 | var $login = false; |
|---|
| 27 | var $options; |
|---|
| 28 | var $wp_ver23; |
|---|
| 29 | var $wp_ver25; |
|---|
| 30 | |
|---|
| 31 | function SearchEverything(){ |
|---|
| 32 | global $wp_version; |
|---|
| 33 | $this->wp_ver23 = ($wp_version >= '2.3'); |
|---|
| 34 | $this->wp_ver25 = ($wp_version >= '2.5'); |
|---|
| 35 | $this->options = get_option('SE4_options'); |
|---|
| 36 | |
|---|
| 37 | if (is_admin()) { |
|---|
| 38 | include ( SE_ABSPATH . 'SE-Admin.php' ); |
|---|
| 39 | $SEAdmin = new SearchEverythingAdmin(); |
|---|
| 40 | } |
|---|
| 41 | |
|---|
| 42 | //add filters based upon option settings |
|---|
| 43 | if ("true" == $this->options['SE4_use_tag_search']) { |
|---|
| 44 | add_filter('posts_where', array(&$this, 'SE4_search_tags')); |
|---|
| 45 | add_filter('posts_join', array(&$this, 'SE4_terms_join')); |
|---|
| 46 | $this->SE4_log("searching tags"); |
|---|
| 47 | } |
|---|
| 48 | |
|---|
| 49 | if ("true" == $this->options['SE4_use_category_search']) { |
|---|
| 50 | add_filter('posts_where', array(&$this, 'SE4_search_categories')); |
|---|
| 51 | add_filter('posts_join', array(&$this, 'SE4_terms_join')); |
|---|
| 52 | $this->SE4_log("searching categories"); |
|---|
| 53 | } |
|---|
| 54 | |
|---|
| 55 | if ("true" == $this->options['SE4_use_page_search']) { |
|---|
| 56 | add_filter('posts_where', array(&$this, 'SE4_search_pages')); |
|---|
| 57 | $this->SE4_log("searching pages"); |
|---|
| 58 | } |
|---|
| 59 | |
|---|
| 60 | if ("true" == $this->options['SE4_use_excerpt_search']) { |
|---|
| 61 | add_filter('posts_where', array(&$this, 'SE4_search_excerpt')); |
|---|
| 62 | $this->SE4_log("searching excerpts"); |
|---|
| 63 | } |
|---|
| 64 | |
|---|
| 65 | if ("true" == $this->options['SE4_use_comment_search']) { |
|---|
| 66 | add_filter('posts_where', array(&$this, 'SE4_search_comments')); |
|---|
| 67 | add_filter('posts_join', array(&$this, 'SE4_comments_join')); |
|---|
| 68 | $this->SE4_log("searching comments"); |
|---|
| 69 | } |
|---|
| 70 | |
|---|
| 71 | if ("true" == $this->options['SE4_use_draft_search']) { |
|---|
| 72 | add_filter('posts_where', array(&$this, 'SE4_search_draft_posts')); |
|---|
| 73 | $this->SE4_log("searching drafts"); |
|---|
| 74 | } |
|---|
| 75 | |
|---|
| 76 | if ("true" == $this->options['SE4_use_attachment_search']) { |
|---|
| 77 | add_filter('posts_where', array(&$this, 'SE4_search_attachments')); |
|---|
| 78 | $this->SE4_log("searching attachments"); |
|---|
| 79 | } |
|---|
| 80 | |
|---|
| 81 | if ("true" == $this->options['SE4_use_metadata_search']) { |
|---|
| 82 | add_filter('posts_where', array(&$this, 'SE4_search_metadata')); |
|---|
| 83 | add_filter('posts_join', array(&$this, 'SE4_search_metadata_join')); |
|---|
| 84 | $this->SE4_log("searching metadata"); |
|---|
| 85 | } |
|---|
| 86 | |
|---|
| 87 | if ("true" == $this->options['SE4_exclude_posts']) { |
|---|
| 88 | add_filter('posts_where', array(&$this, 'SE4_exclude_posts')); |
|---|
| 89 | $this->SE4_log("searching excluding posts"); |
|---|
| 90 | } |
|---|
| 91 | |
|---|
| 92 | if ("true" == $this->options['SE4_exclude_categories']) { |
|---|
| 93 | add_filter('posts_where', array(&$this, 'SE4_exclude_categories')); |
|---|
| 94 | add_filter('posts_join', array(&$this, 'SE4_exclude_categories_join')); |
|---|
| 95 | $this->SE4_log("searching excluding categories"); |
|---|
| 96 | } |
|---|
| 97 | |
|---|
| 98 | |
|---|
| 99 | // Add registration of bo_revisions hook handler |
|---|
| 100 | // right before the following line already existant |
|---|
| 101 | add_filter('posts_where', array(&$this, 'SE4_no_revisions')); |
|---|
| 102 | |
|---|
| 103 | |
|---|
| 104 | //Duplicate fix provided by Tiago.Pocinho |
|---|
| 105 | add_filter('posts_request', array(&$this, 'SE4_distinct')); |
|---|
| 106 | } |
|---|
| 107 | |
|---|
| 108 | // Exclude post revisions |
|---|
| 109 | function SE4_no_revisions($where) { |
|---|
| 110 | global $wp_query; |
|---|
| 111 | if (!empty($wp_query->query_vars['s'])) { |
|---|
| 112 | $where = 'AND (' . substr($where, strpos($where, 'AND')+3) . ') AND post_type != \'revision\''; |
|---|
| 113 | } |
|---|
| 114 | return $where; |
|---|
| 115 | } |
|---|
| 116 | |
|---|
| 117 | // Logs search into a file |
|---|
| 118 | function SE4_log($msg) { |
|---|
| 119 | |
|---|
| 120 | if ($this->logging) { |
|---|
| 121 | $fp = fopen("logfile.log","a+"); |
|---|
| 122 | if ( !$fp ) { echo 'unable to write to log file!'; } |
|---|
| 123 | $date = date("Y-m-d H:i:s "); |
|---|
| 124 | $source = "search_everything plugin: "; |
|---|
| 125 | fwrite($fp, "\n\n".$date."\n".$source."\n".$msg); |
|---|
| 126 | fclose($fp); |
|---|
| 127 | } |
|---|
| 128 | return true; |
|---|
| 129 | } |
|---|
| 130 | |
|---|
| 131 | //Duplicate fix provided by Tiago.Pocinho |
|---|
| 132 | function SE4_distinct($query){ |
|---|
| 133 | global $wp_query; |
|---|
| 134 | if (!empty($wp_query->query_vars['s'])) { |
|---|
| 135 | if (strstr($where, 'DISTINCT')) { |
|---|
| 136 | } else { |
|---|
| 137 | $query = str_replace('SELECT', 'SELECT DISTINCT', $query); |
|---|
| 138 | } |
|---|
| 139 | } |
|---|
| 140 | return $query; |
|---|
| 141 | } |
|---|
| 142 | |
|---|
| 143 | function SE4_exclude_posts($where) { |
|---|
| 144 | global $wp_query; |
|---|
| 145 | if (!empty($wp_query->query_vars['s'])) { |
|---|
| 146 | $excl_list = implode(',', explode(',', trim($this->options['SE4_exclude_posts_list']))); |
|---|
| 147 | $where = str_replace('"', '\'', $where); |
|---|
| 148 | $where = 'AND ('.substr($where, strpos($where, 'AND')+3).' )'; |
|---|
| 149 | $where .= ' AND (ID NOT IN ( '.$excl_list.' ))'; |
|---|
| 150 | } |
|---|
| 151 | |
|---|
| 152 | $this->SE4_log("ex posts where: ".$where); |
|---|
| 153 | return $where; |
|---|
| 154 | } |
|---|
| 155 | |
|---|
| 156 | //search pages (except password protected pages provided by loops) |
|---|
| 157 | function SE4_search_pages($where) { |
|---|
| 158 | global $wp_query; |
|---|
| 159 | if (!empty($wp_query->query_vars['s'])) { |
|---|
| 160 | |
|---|
| 161 | $where = str_replace('"', '\'', $where); |
|---|
| 162 | if ('true' == $this->options['SE4_approved_pages_only']) { |
|---|
| 163 | $where = str_replace('post_type = \'post\' AND ', 'post_password = \'\' AND ', $where); |
|---|
| 164 | } |
|---|
| 165 | else { // < v 2.1 |
|---|
| 166 | $where = str_replace('post_type = \'post\' AND ', '', $where); |
|---|
| 167 | } |
|---|
| 168 | } |
|---|
| 169 | |
|---|
| 170 | $this->SE4_log("pages where: ".$where); |
|---|
| 171 | return $where; |
|---|
| 172 | } |
|---|
| 173 | |
|---|
| 174 | //search excerpts provided by Dennis Turner, fixed by GvA |
|---|
| 175 | function SE4_search_excerpt($where) { |
|---|
| 176 | global $wp_query; |
|---|
| 177 | if (!empty($wp_query->query_vars['s'])) { |
|---|
| 178 | $where = str_replace('"', '\'', $where); |
|---|
| 179 | $where = str_replace(' OR (wp_posts.post_content LIKE \'%' . |
|---|
| 180 | $wp_query->query_vars['s'] . '%\'', ' OR (wp_posts.post_content LIKE \'%' . |
|---|
| 181 | $wp_query->query_vars['s'] . '%\') OR (wp_posts.post_excerpt LIKE \'%' . |
|---|
| 182 | $wp_query->query_vars['s'] . '%\'', $where); |
|---|
| 183 | } |
|---|
| 184 | |
|---|
| 185 | $this->SE4_log("excerpts where: ".$where); |
|---|
| 186 | return $where; |
|---|
| 187 | } |
|---|
| 188 | |
|---|
| 189 | |
|---|
| 190 | //search drafts |
|---|
| 191 | function SE4_search_draft_posts($where) { |
|---|
| 192 | global $wp_query; |
|---|
| 193 | if (!empty($wp_query->query_vars['s'])) { |
|---|
| 194 | $where = str_replace('"', '\'', $where); |
|---|
| 195 | $where = str_replace(' AND (post_status = \'publish\'', ' AND (post_status = \'publish\' or post_status = \'draft\'', $where); |
|---|
| 196 | } |
|---|
| 197 | |
|---|
| 198 | $this->SE4_log("drafts where: ".$where); |
|---|
| 199 | return $where; |
|---|
| 200 | } |
|---|
| 201 | |
|---|
| 202 | //search attachments |
|---|
| 203 | function SE4_search_attachments($where) { |
|---|
| 204 | global $wp_query; |
|---|
| 205 | if (!empty($wp_query->query_vars['s'])) { |
|---|
| 206 | $where = str_replace('"', '\'', $where); |
|---|
| 207 | $where = str_replace(' AND (post_status = \'publish\'', ' AND (post_status = \'publish\' or post_status = \'attachment\'', $where); |
|---|
| 208 | $where = str_replace('AND post_status != \'attachment\'','',$where); |
|---|
| 209 | } |
|---|
| 210 | |
|---|
| 211 | $this->SE4_log("attachments where: ".$where); |
|---|
| 212 | return $where; |
|---|
| 213 | } |
|---|
| 214 | |
|---|
| 215 | //search comments |
|---|
| 216 | function SE4_search_comments($where) { |
|---|
| 217 | global $wp_query, $wpdb; |
|---|
| 218 | if (!empty($wp_query->query_vars['s'])) { |
|---|
| 219 | if ('true' == $this->options['SE4_approved_comments_only']) { |
|---|
| 220 | $comment_approved = " AND c.comment_approved = '1'"; |
|---|
| 221 | } else { |
|---|
| 222 | $comment_approved = ''; |
|---|
| 223 | } |
|---|
| 224 | |
|---|
| 225 | if ($this->wp_ver23) { |
|---|
| 226 | $where .= " OR ( c.comment_post_ID = ".$wpdb->posts . ".ID " . $comment_approved . " AND c.comment_content LIKE '%" . $wpdb->escape($wp_query->query_vars['s']) . "%') "; |
|---|
| 227 | } |
|---|
| 228 | } |
|---|
| 229 | |
|---|
| 230 | $this->SE4_log("comments where: ".$where); |
|---|
| 231 | |
|---|
| 232 | return $where; |
|---|
| 233 | } |
|---|
| 234 | |
|---|
| 235 | //search metadata |
|---|
| 236 | function SE4_search_metadata($where) { |
|---|
| 237 | global $wp_query, $wpdb; |
|---|
| 238 | if (!empty($wp_query->query_vars['s'])) { |
|---|
| 239 | if ($this->wp_ver23) |
|---|
| 240 | $where .= " OR (m.meta_value LIKE '%" . $wpdb->escape($wp_query->query_vars['s']) . "%') "; |
|---|
| 241 | else |
|---|
| 242 | $where .= " OR meta_value LIKE '%" . $wpdb->escape($wp_query->query_vars['s']) . "%' "; |
|---|
| 243 | } |
|---|
| 244 | |
|---|
| 245 | $this->SE4_log("metadata where: ".$where); |
|---|
| 246 | |
|---|
| 247 | return $where; |
|---|
| 248 | } |
|---|
| 249 | |
|---|
| 250 | //search tags |
|---|
| 251 | function SE4_search_tags($where) { |
|---|
| 252 | global $wp_query, $wpdb; |
|---|
| 253 | if (!empty($wp_query->query_vars['s'])) { |
|---|
| 254 | //$where .= " OR ( tter.slug LIKE '%" . $wpdb->escape($wp_query->query_vars['s']) . "%') "; |
|---|
| 255 | $where .= " OR ( tter.name LIKE '%" . str_replace(' ', '-',$wpdb->escape($wp_query->query_vars['s'])) . "%') "; |
|---|
| 256 | } |
|---|
| 257 | |
|---|
| 258 | $this->SE4_log("tags where: ".$where); |
|---|
| 259 | |
|---|
| 260 | return $where; |
|---|
| 261 | } |
|---|
| 262 | |
|---|
| 263 | //search categories |
|---|
| 264 | function SE4_search_categories ( $where ) { |
|---|
| 265 | |
|---|
| 266 | global $wp_query, $wpdb; |
|---|
| 267 | |
|---|
| 268 | if ( ! empty($wp_query->query_vars['s']) ) { |
|---|
| 269 | $where .= " OR ( tter.slug LIKE '%" . sanitize_title_with_dashes( $wp_query->query_vars['s'] ) . "%') "; |
|---|
| 270 | } |
|---|
| 271 | |
|---|
| 272 | $this->SE4_log("categories where: ".$where); |
|---|
| 273 | |
|---|
| 274 | return $where; |
|---|
| 275 | |
|---|
| 276 | } |
|---|
| 277 | |
|---|
| 278 | //exlude some categories from search |
|---|
| 279 | function SE4_exclude_categories($where) { |
|---|
| 280 | global $wp_query, $wpdb; |
|---|
| 281 | if (!empty($wp_query->query_vars['s'])) { |
|---|
| 282 | if (trim($this->options['SE4_exclude_categories_list']) != '') { |
|---|
| 283 | $excl_list = implode("','", explode(',', "'".trim($this->options['SE4_exclude_categories_list'])."'" )); |
|---|
| 284 | $where = str_replace('"', '\'', $where); |
|---|
| 285 | $where = 'AND ('.substr($where, strpos($where, 'AND')+3).' )'; |
|---|
| 286 | if ($this->wp_ver23) |
|---|
| 287 | $where .= " AND ( ctax.term_id NOT IN ( ".$excl_list." ))"; |
|---|
| 288 | else |
|---|
| 289 | $where .= ' AND (c.category_id NOT IN ( '.$excl_list.' ))'; |
|---|
| 290 | } |
|---|
| 291 | } |
|---|
| 292 | |
|---|
| 293 | $this->SE4_log("ex cats where: ".$where); |
|---|
| 294 | return $where; |
|---|
| 295 | } |
|---|
| 296 | |
|---|
| 297 | //join for excluding categories - Deprecated in 2.3 |
|---|
| 298 | function SE4_exclude_categories_join($join) { |
|---|
| 299 | global $wp_query, $wpdb; |
|---|
| 300 | |
|---|
| 301 | if (!empty($wp_query->query_vars['s'])) { |
|---|
| 302 | |
|---|
| 303 | if ($this->wp_ver23) { |
|---|
| 304 | $join .= " LEFT JOIN $wpdb->term_relationships AS crel ON ($wpdb->posts.ID = crel.object_id) LEFT JOIN $wpdb->term_taxonomy AS ctax ON (ctax.taxonomy = 'category' AND crel.term_taxonomy_id = ctax.term_taxonomy_id) LEFT JOIN $wpdb->terms AS cter ON (ctax.term_id = cter.term_id) "; |
|---|
| 305 | } else { |
|---|
| 306 | $join .= "LEFT JOIN $wpdb->post2cat AS c ON $wpdb->posts.ID = c.post_id"; |
|---|
| 307 | } |
|---|
| 308 | } |
|---|
| 309 | $this->SE4_log("category join: ".$join); |
|---|
| 310 | return $join; |
|---|
| 311 | } |
|---|
| 312 | |
|---|
| 313 | //join for searching comments |
|---|
| 314 | function SE4_comments_join($join) { |
|---|
| 315 | global $wp_query, $wpdb; |
|---|
| 316 | |
|---|
| 317 | if (!empty($wp_query->query_vars['s'])) { |
|---|
| 318 | |
|---|
| 319 | if ($this->wp_ver23) { |
|---|
| 320 | $join .= " LEFT JOIN $wpdb->comments AS c ON ( comment_post_ID = ID " . $comment_approved . ") "; |
|---|
| 321 | } else { |
|---|
| 322 | |
|---|
| 323 | if ('true' == $this->options['SE4_approved_comments_only']) { |
|---|
| 324 | $comment_approved = " AND comment_approved = '1'"; |
|---|
| 325 | } else { |
|---|
| 326 | $comment_approved = ''; |
|---|
| 327 | } |
|---|
| 328 | |
|---|
| 329 | $join .= "LEFT JOIN $wpdb->comments ON ( comment_post_ID = ID " . $comment_approved . ") "; |
|---|
| 330 | |
|---|
| 331 | } |
|---|
| 332 | } |
|---|
| 333 | |
|---|
| 334 | $this->SE4_log("comments join: ".$join); |
|---|
| 335 | return $join; |
|---|
| 336 | } |
|---|
| 337 | |
|---|
| 338 | //join for searching metadata |
|---|
| 339 | function SE4_search_metadata_join($join) { |
|---|
| 340 | global $wp_query, $wpdb; |
|---|
| 341 | |
|---|
| 342 | if (!empty($wp_query->query_vars['s'])) { |
|---|
| 343 | |
|---|
| 344 | if ($this->wp_ver23) |
|---|
| 345 | $join .= " LEFT JOIN $wpdb->postmeta AS m ON ($wpdb->posts.ID = m.post_id) "; |
|---|
| 346 | else |
|---|
| 347 | $join .= "LEFT JOIN $wpdb->postmeta ON $wpdb->posts.ID = $wpdb->postmeta.post_id "; |
|---|
| 348 | } |
|---|
| 349 | $this->SE4_log("metadata join: ".$join); |
|---|
| 350 | return $join; |
|---|
| 351 | } |
|---|
| 352 | |
|---|
| 353 | //join for searching tags |
|---|
| 354 | function SE4_terms_join($join) { |
|---|
| 355 | global $wp_query, $wpdb; |
|---|
| 356 | |
|---|
| 357 | if (!empty($wp_query->query_vars['s'])) { |
|---|
| 358 | |
|---|
| 359 | // if we're searching for categories |
|---|
| 360 | if ( $this->options['SE4_use_category_search'] ) { |
|---|
| 361 | $on[] = "ttax.taxonomy = 'category'"; |
|---|
| 362 | } |
|---|
| 363 | |
|---|
| 364 | // if we're searching for tags |
|---|
| 365 | if ( $this->options['SE4_use_tag_search'] ) { |
|---|
| 366 | $on[] = "ttax.taxonomy = 'post_tag'"; |
|---|
| 367 | } |
|---|
| 368 | |
|---|
| 369 | // build our final string |
|---|
| 370 | $on = ' ( ' . implode( ' OR ', $on ) . ' ) '; |
|---|
| 371 | |
|---|
| 372 | $join .= " LEFT JOIN $wpdb->term_relationships AS trel ON ($wpdb->posts.ID = trel.object_id) LEFT JOIN $wpdb->term_taxonomy AS ttax ON ( " . $on . " AND trel.term_taxonomy_id = ttax.term_taxonomy_id) LEFT JOIN $wpdb->terms AS tter ON (ttax.term_id = tter.term_id) "; |
|---|
| 373 | } |
|---|
| 374 | |
|---|
| 375 | $this->SE4_log("tags join: ".$join); |
|---|
| 376 | return $join; |
|---|
| 377 | } |
|---|
| 378 | } |
|---|
| 379 | |
|---|
| 380 | ?> |
|---|