WordPress.org

Make WordPress Core

Ticket #10667: mysql.php

File mysql.php, 9.6 KB (added by jshreve, 6 years ago)

MySQL FullText Search Plugin (wp-plugins/). Changes to be compatible with the SearchAPI Core.

Line 
1<?php
2/**
3* The MySQL search plugin uses the WordPress "Search API" to enable basic MySQL fulltext searching.
4* @author Justin Shreve <jshreve4@kent.edu>
5* @version 1.1.0
6*/
7
8/*
9Plugin Name: MySQL FullText Search Plugin
10Plugin URI: http://wordpress.org/
11Description: MySQL FullText Search functionality for WordPress
12Author: Justin Shreve
13Version: 1.1.0
14*/
15
16/**
17* MySQL Search
18* Takes information from the search api and uses it to query the search index table.
19* @version 1.1.0
20*/
21class mysql_search
22{
23                /**
24                * Results
25                * Contains an array of MySQL results from a search
26                * @var array a list of results from a search
27                */
28                var $results = array();
29               
30                /**
31                * Flags
32                * An array of search parameters
33                * @var array search parameters
34                */
35                var $flags = array();
36               
37                /**
38                * Options
39                * Options specific to each search plugin. You can enable/disable advanced search, search page filters, pagination and search index support.
40                * @var array options to be used by the search api
41                */
42                var $options = array(
43                        'advanced' => 1,
44                        'filters' => 1,
45                        'pagination' => 1,
46                        'sort' => 1,
47                        'index' => 1,
48                );
49               
50                /**
51                * MySQL Search (Constructor)
52                * This function passes along the options array to the search api
53                */
54                function mysql_search() {
55                        $this->parent->options =& $this->options;
56                }
57
58                /**
59                * Search
60                * This function pulls everything from the API and database together. It loads the pagination function, the filter code, calls the results function and outputs the
61                * results.
62                * @return string Final search output
63                */
64                function search()
65                {
66                        // Query the database and format results
67                        $total = $this->find_results();
68                       
69                        if( $this->flags['page'] > 1 )
70                                $start = intval ( ( ( $this->flags['page'] - 1 ) * get_option( 'posts_per_page' ) ) + 1 );
71                        else
72                                $start = 1;
73                               
74                        // Return the results
75                        if( $total > 0 )
76                        {
77                                // FILTER: search_results_start Starts the results output
78                                $result_html = apply_filters( 'search_results_start', "<ol class=\"searchresults\" start=\"{$start}\">\n" );
79                               
80                                foreach( $this->results as $results ) {
81                                        // Result is a post
82                                        if( $results->type == "post" ) {
83                                                // FILTER: search_post_result Lets you change a single row for result output
84                                                $result_html .= apply_filters( 'search_post_result', "<li><strong class='result_type'>" . __( 'Post ' ) . "</strong>: <a href=\"" . get_permalink( $results->object ) . "\" class='result_title'>" . $results->title . "</a>\n<p class=\"result_summary\">". $this->parent->trim_excerpt( $results->content ) ."</p></li>" );
85                                        }
86                                        // Result is a page
87                                        elseif( $results->type == "page" ) {
88                                                // FILTER: search_page_result Lets you change a single row for result output
89                                                $result_html .= apply_filters( 'search_page_result', "<li><strong class='result_type'>" . __( 'Page ' ) . "</strong>: <a href=\"" . get_permalink ( $results->object ) . "\" class='result_title'>" . $results->title . "</a>\n<p class=\"result_summary\">". $this->parent->trim_excerpt( $results->content ) ."</p></li>" );
90                                        }
91                                        // Result is a comment
92                                        else {
93                                                // FILTER: search_comment_result Lets you change a single row for result output
94                                                $result_html .= apply_filters( 'search_comment_result', "<li><strong class='result_type'>" . __( 'Comment ' ) . "</strong>: <a href=\"" . get_comment_link( $results->object ) . "\" class='result_title'>" . get_the_title( $results->parent ) ."</a>\n<p class=\"result_summary\">" . $this->parent->trim_excerpt( $results->content ) ."</p></li>" );
95                                        }
96                                }
97                               
98                                // FILTER: search_results_start Ends the results output
99                                $result_html .= apply_filters( 'search_results_end', "</ol>\n" );
100                        }
101                       
102                        // No results error
103                        else {
104                                // FILTER: search_no_results Allows you to change the error message when no results are returned
105                                $result_html .= apply_filters( 'search_no_results', "<h2>" . __( ' There are no results for this seach.' ) . "</h2>" );
106                        }
107               
108                        // Return the search output
109                        // FILTER: search_results Allows you to edit the results
110                        return apply_filters( 'search_results', $this->parent->result_search_box() . $result_html . $this->parent->pagination( $total ) );
111                }
112               
113                /**
114                * Find Results
115                * This function is what physically queries the database and does the search using the flags given to us from the search API
116                * @global object WordPress Database Abstraction Layer
117                * @return int The number of results
118                */
119                function find_results()
120                {
121                        global $wpdb;                           
122                       
123                        // Start off our query and our counting of results query       
124                        $start = "SELECT *,MATCH( content,title ) AGAINST( '{$this->flags[string]}') as ranking FROM {$wpdb->prefix}search_index WHERE MATCH ( content,title ) AGAINST('{$this->flags[string]}' IN BOOLEAN MODE) AND protected = '0'";
125                        $cstart = "SELECT COUNT(*) as total FROM {$wpdb->prefix}search_index  WHERE MATCH ( content,title ) AGAINST('{$this->flags[string]}' IN BOOLEAN MODE) AND protected = '0'";
126                               
127                        // Add in any date flags
128                        if( !empty( $this->flags['startYear'] ) )
129                                $sql .= " AND YEAR(post_date) >= " . $this->flags['startYear'];
130                        if ( !empty( $this->flags['startMonth'] ) )
131                                $sql .= " AND MONTH(post_date) >= " . $this->flags['startMonth'];
132                        if ( !empty( $this->flags['startDay'] ) )
133                                $sql .= " AND DAYOFMONTH(post_date) >= " . $this->flags['startDay'];
134               
135                        if( !empty( $this->flags['endYear'] ) )
136                                $sql .= " AND YEAR(post_date) <= " . $this->flags['endYear'];           
137                        if ( !empty( $this->flags['endMonth'] ) )
138                                $sql .= " AND MONTH(post_date) <= " . $this->flags['endMonth'];
139                        if ( !empty( $this->flags['endDay'] ) )
140                                $sql .= " AND DAYOFMONTH(post_date) <= " . $this->flags['endDay'];
141               
142                        // add in the author flag
143                        if( !empty( $this->flags['author'] ) )
144                                $sql .= " AND author LIKE '%".$this->flags['author']."%'";
145                                               
146                        // keep going and do the category flags
147                        if( is_array( $this->flags['categories'] ) )
148                        {
149                                $sql .= " AND (";
150                                foreach( $this->flags['categories'] as $category )
151                                {
152                                        $sql .= " categories LIKE '%,{$category},%' OR ";
153                                }
154                                $sql = substr( $sql, 0, -3 ) . ")";
155                        }
156                       
157                       
158                        // keep going and do the category flags
159                        if( is_array( $this->flags['tags'] ) )
160                        {
161                                $sql .= " AND (";
162                                foreach( $this->flags['tags'] as $tag )
163                                {
164                                        $sql .= " tags LIKE '%,{$tag},%' OR ";
165                                }
166                                $sql = substr( $sql, 0, -3 ) . ")";
167                        }
168                       
169                       
170                       
171                        // Figure out what type of data we are looking for
172                        if( is_array( $this->flags['types'] ) ) {
173                                if( in_array( 'posts', $this->flags['types'] ) && !in_array( 'pages', $this->flags['types'] ) && !in_array( 'comments', $this->flags['types'] ) )
174                                        $sql .= " AND type = 'post'";
175                                elseif( in_array( 'pages', $this->flags['types'] ) && !in_array( 'posts', $this->flags['types'] ) && !in_array( 'comments', $this->flags['types'] ) )
176                                        $sql .= " AND type = 'page'";
177                                elseif( in_array( 'comments', $this->flags['types'] ) && !in_array( 'posts', $this->flags['types'] ) && !in_array( 'pages', $this->flags['types'] ) )
178                                        $sql .= " AND type = 'comment'";
179                                elseif( in_array( 'posts', $this->flags['types'] ) && in_array( 'pages', $this->flags['types'] ) && !in_array( 'comments', $this->flags['types'] ) )
180                                        $sql .= " AND (type = 'post' OR type = 'page')";
181                                elseif( in_array( 'posts', $this->flags['types'] ) && !in_array( 'pages', $this->flags['types'] ) && in_array( 'comments', $this->flags['types'] ) )
182                                        $sql .= " AND (type = 'post' OR type = 'comment')";
183                                elseif( !in_array( 'posts', $this->flags['types'] ) && in_array( 'pages', $this->flags['types'] ) && in_array( 'comments', $this->flags['types'] ) )
184                                        $sql .= " AND (type = 'page' OR type = 'comment')";
185                        }
186                       
187                        // How many results do we have total?
188                        // FILTER: search_count_find_results Allows you do manage the sql query
189                        $count = $wpdb->get_results( apply_filters( "search_count_find_results", $cstart . $sql ) );
190                       
191                        // how we are ordering the data
192                        if( $this->flags['sort'] == "alpha" )
193                                $sql .= " ORDER BY title ".$this->flags['sorttype'];
194                        elseif( $this->flags['sort'] == "date" )
195                                $sql .= " ORDER BY post_date ".$this->flags['sorttype'];
196                               
197                        // Add in the pagination data for the LIMIT part of the query
198                        $sql .= " LIMIT " . ( $this->flags['page'] - 1 ) * get_option( 'posts_per_page' ) . ",".get_option('posts_per_page').";";
199
200                        // store the results in an array
201                        // FILTER: search_find_results Allows you do manage the sql query
202                        $this->results = $wpdb->get_results( apply_filters( "search_find_results", $start . $sql ) );
203                       
204                        // return the total number of results
205                        return $count[0]->total;
206                }
207}
208       
209if( function_exists( "do_search_load" ) ) {
210        echo '<div id="message" class="updated fade"><p>';
211        _e('You may only have one search plugin using the search api enabled at a time. Please disable the active search plugin first.');
212        echo '</p>';
213        die;
214}
215else { 
216        /**
217        * Search Load
218        * This function is ran by a filter in the search API.
219        * @return object The search plugin object (the class in this file)
220        */
221        function do_search_load() {
222                return new mysql_search();
223        }
224}
225
226register_activation_hook( __FILE__, 'mysql_activate_self' );
227
228/**
229* Activate Self
230* This function refreshes the search index when the plugin is activated
231*/             
232function mysql_activate_self() {
233        global $index;
234        $index->all();
235        update_option( 'searchapi_custom_options', '' );
236        update_option( 'searchapi_help', '' );
237        update_option( 'searchapi_plugin', "search/mysql.php" );
238}
239
240// Tell the above function to run in the search api
241add_filter('search_load', 'do_search_load' );
242?>