Version Description
- New feature: You can now export the search log as a CSV file.
- New feature: Admin Search page allows you to perform searches in WP admin using Relevanssi.
- New filter:
relevanssi_admin_search_capability
can be used to adjust who sees the admin search page. - New filter:
relevanssi_entities_inside_pre
andrelevanssi_entities_inside_code
adjust how HTML entities are handled insidepre
andcode
tags. - Numeric meta values (
meta_value_num
) are now sorted as numbers and not strings. - Pinned posts have
$post->relevanssi_pinned
set to 1 for debugging purposes, but you can also use this for styling the posts in the search results templates. - The Did you mean feature has been toned down a bit, to make the suggestions slightly less weird in some cases.
- Post parent parameters now accept 0 as a value, making it easier to search for children of any post or posts without a parent.
- Polylang compatibility has been improved.
- Phrases with apostrophes inside work better.
- The
relevanssi_excerpt
filter hook got a second parameter that holds the post ID. - Custom field sorting actually works now.
- WP Search Suggest compatibility added.
Download this release
Release Info
Developer | msaari |
Plugin | Relevanssi – A Better Search |
Version | 4.1 |
Comparing to | |
See all releases |
Code changes from version 4.0.11 to 4.1
- changelog.txt +30 -0
- lib/admin-ajax.php +202 -0
- lib/admin_scripts.js +93 -2
- lib/admin_styles.css +9 -1
- lib/common.php +10 -6
- lib/compatibility/polylang.php +1 -1
- lib/compatibility/wp-search-suggest.php +25 -0
- lib/compatibility/wpml.php +3 -2
- lib/excerpts-highlights.php +24 -7
- lib/indexing.php +3 -0
- lib/init.php +36 -3
- lib/interface.php +32 -0
- lib/log.php +34 -0
- lib/search.php +168 -79
- lib/sorting.php +1 -5
- lib/tabs/excerpts-tab.php +8 -0
- lib/tabs/indexing-tab.php +15 -1
- lib/tabs/logging-tab.php +10 -0
- lib/tabs/overview-tab.php +3 -0
- lib/tabs/search-page.php +63 -0
- lib/tabs/searching-tab.php +2 -2
- readme.txt +20 -44
- relevanssi.php +10 -9
changelog.txt
CHANGED
@@ -1,3 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
= 4.0.4 =
|
2 |
* Fixed shortcode: `searchform` shortcode didn't work properly.
|
3 |
* Setting post type or post content weight to 0 didn't work.
|
1 |
+
= 4.0.9 =
|
2 |
+
* Fixes broken tag and category indexing and searching. If you use tags and categories, rebuild the index after updating.
|
3 |
+
* Phrases were not highlighted correctly on documents. This is now fixed.
|
4 |
+
* Shortcode fix: 'wp_show_posts' shouldn't cause problems anymore.
|
5 |
+
* New filter: `relevanssi_indexing_restriction` allows filtering posts before indexing.
|
6 |
+
* New WooCommerce product visibility filtering tool makes WooCommerce product indexing faster.
|
7 |
+
* MemberPress post controls were loose and showed drafts to searchers. That is now fixed.
|
8 |
+
* Highlighting was too loose, even if matching was set to whole words.
|
9 |
+
* Highlighting now works better in cases where there's a hyphen or an apostrophe inside a word.
|
10 |
+
|
11 |
+
= 4.0.8 =
|
12 |
+
* Fixed cases where Relevanssi added an ellipsis even if the excerpt was from the start of the post.
|
13 |
+
* Highlighting now works with numeric search strings.
|
14 |
+
* Improved highlighting for accented words. Thanks to Paul Ryan.
|
15 |
+
* A surplus comma at the end of post exclusion setting won't break the search anymore.
|
16 |
+
* Fixed instructions for adjusting the throttle limit.
|
17 |
+
|
18 |
+
= 4.0.7 =
|
19 |
+
* Recent post bonus is now applied to searches.
|
20 |
+
* Exact term setting can now be disabled.
|
21 |
+
* Users of Members plugin would have drafts appear in search results. This is now fixed.
|
22 |
+
|
23 |
+
= 4.0.6 =
|
24 |
+
* Indexing bugs squashed.
|
25 |
+
* Missing tag and category weight settings returned.
|
26 |
+
* Fusion builder shortcodes are removed from excerpts.
|
27 |
+
* MemberPress post control was backwards.
|
28 |
+
* User searches page reset buttons fixed.
|
29 |
+
* WPML language filter fix.
|
30 |
+
|
31 |
= 4.0.4 =
|
32 |
* Fixed shortcode: `searchform` shortcode didn't work properly.
|
33 |
* Setting post type or post content weight to 0 didn't work.
|
lib/admin-ajax.php
CHANGED
@@ -130,3 +130,205 @@ function relevanssi_list_categories() {
|
|
130 |
echo wp_json_encode( $categories );
|
131 |
wp_die();
|
132 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
130 |
echo wp_json_encode( $categories );
|
131 |
wp_die();
|
132 |
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* Performs an admin search.
|
136 |
+
*
|
137 |
+
* Performs an admin dashboard search.
|
138 |
+
*
|
139 |
+
* @since 2.2.0
|
140 |
+
*/
|
141 |
+
function relevanssi_admin_search() {
|
142 |
+
check_ajax_referer( 'relevanssi_admin_search_nonce', 'security' );
|
143 |
+
|
144 |
+
$args = array();
|
145 |
+
if ( isset( $_POST['args'] ) ) {
|
146 |
+
parse_str( $_POST['args'], $args );
|
147 |
+
}
|
148 |
+
if ( isset( $_POST['posts_per_page'] ) ) {
|
149 |
+
$posts_per_page = intval( $_POST['posts_per_page'] );
|
150 |
+
if ( $posts_per_page > 0 ) {
|
151 |
+
$args['posts_per_page'] = $posts_per_page;
|
152 |
+
}
|
153 |
+
}
|
154 |
+
if ( isset( $_POST['offset'] ) ) {
|
155 |
+
$offset = intval( $_POST['offset'] );
|
156 |
+
if ( $offset > 0 ) {
|
157 |
+
$args['offset'] = $offset;
|
158 |
+
}
|
159 |
+
}
|
160 |
+
if ( isset( $_POST['s'] ) ) {
|
161 |
+
$args['s'] = $_POST['s'];
|
162 |
+
}
|
163 |
+
|
164 |
+
$query = new WP_Query();
|
165 |
+
$query->parse_query( $args );
|
166 |
+
$query->set( 'relevanssi_admin_search', true );
|
167 |
+
relevanssi_do_query( $query );
|
168 |
+
|
169 |
+
$results = relevanssi_admin_search_debugging_info( $query );
|
170 |
+
|
171 |
+
// Take the posts array and create a string out of it.
|
172 |
+
$offset = 0;
|
173 |
+
if ( isset( $query->query_vars['offset'] ) ) {
|
174 |
+
$offset = $query->query_vars['offset'];
|
175 |
+
}
|
176 |
+
$results .= relevanssi_admin_search_format_posts( $query->posts, $query->found_posts, $offset );
|
177 |
+
|
178 |
+
echo wp_json_encode( $results );
|
179 |
+
wp_die();
|
180 |
+
}
|
181 |
+
|
182 |
+
/**
|
183 |
+
* Formats the posts for admin search.
|
184 |
+
*
|
185 |
+
* Results are presented as an ordered list of posts. The format is very basic, and
|
186 |
+
* can be modified with the 'relevanssi_admin_search_element' filter hook.
|
187 |
+
*
|
188 |
+
* @param array $posts The posts array.
|
189 |
+
* @param int $total The number of posts found in total.
|
190 |
+
* @param int $offset Offset value.
|
191 |
+
*
|
192 |
+
* @return string The formatted posts.
|
193 |
+
*
|
194 |
+
* @since 2.2.0
|
195 |
+
*/
|
196 |
+
function relevanssi_admin_search_format_posts( $posts, $total, $offset ) {
|
197 |
+
$result = '<h3>' . __( 'Results', 'relevanssi' ) . '</h3>';
|
198 |
+
// Translators: %1$d is the total number of posts found, %2$d is the current search result count, %3$d is the offset.
|
199 |
+
$result .= '<p>' . sprintf( __( 'Found a total of %1$d posts, showing %2$d posts from offset %3$s.', 'relevanssi' ), $total, count( $posts ), '<span id="offset">' . $offset . '</span>' ) . '</p>';
|
200 |
+
if ( $offset > 0 ) {
|
201 |
+
$result .= '<button type="button" id="prev_page">Previous page</button>';
|
202 |
+
}
|
203 |
+
if ( count( $posts ) + $offset < $total ) {
|
204 |
+
$result .= '<button type="button" id="next_page">Next page</button>';
|
205 |
+
}
|
206 |
+
$result .= '<ol>';
|
207 |
+
|
208 |
+
$score_label = __( 'Score:', 'relevanssi' );
|
209 |
+
|
210 |
+
foreach ( $posts as $post ) {
|
211 |
+
$blog_name = '';
|
212 |
+
if ( isset( $post->blog_id ) ) {
|
213 |
+
switch_to_blog( $post->blog_id );
|
214 |
+
$blog_name = get_bloginfo( 'name' ) . ': ';
|
215 |
+
}
|
216 |
+
$permalink = get_permalink( $post->ID );
|
217 |
+
$edit_link = get_edit_post_link( $post->ID );
|
218 |
+
$post_type = $post->post_type;
|
219 |
+
if ( isset( $post->relevanssi_link ) ) {
|
220 |
+
$permalink = $post->relevanssi_link;
|
221 |
+
}
|
222 |
+
if ( 'user' === $post->post_type ) {
|
223 |
+
$edit_link = get_edit_user_link( $post->ID );
|
224 |
+
}
|
225 |
+
if ( empty( $edit_link ) ) {
|
226 |
+
if ( isset( $post->term_id ) ) {
|
227 |
+
$edit_link = get_edit_term_link( $post->term_id, $post->post_type );
|
228 |
+
}
|
229 |
+
}
|
230 |
+
$pinned = '';
|
231 |
+
if ( isset( $post->relevanssi_pinned ) ) {
|
232 |
+
$pinned = '<strong>(pinned)</strong>';
|
233 |
+
}
|
234 |
+
$post_element = <<<EOH
|
235 |
+
<li>$blog_name <strong>$post->post_title</strong> (<a href="$permalink">View $post_type</a>) (<a href="$edit_link">Edit $post_type</a>) <br />
|
236 |
+
$post->post_excerpt<br />
|
237 |
+
$score_label $post->relevance_score $pinned</li>
|
238 |
+
EOH;
|
239 |
+
/**
|
240 |
+
* Filters the admin search results element.
|
241 |
+
*
|
242 |
+
* The post element is a <li> element. Feel free to edit the element any way you want to.
|
243 |
+
*
|
244 |
+
* @param string $post_element The post element.
|
245 |
+
*/
|
246 |
+
$result .= apply_filters( 'relevanssi_admin_search_element', $post_element );
|
247 |
+
if ( isset( $post->blog_id ) ) {
|
248 |
+
restore_current_blog();
|
249 |
+
}
|
250 |
+
}
|
251 |
+
$result .= '</ol>';
|
252 |
+
return $result;
|
253 |
+
}
|
254 |
+
|
255 |
+
/**
|
256 |
+
* Shows debugging information about the search.
|
257 |
+
*
|
258 |
+
* Formats the WP_Query parameters, looks at some filter hooks and presents the
|
259 |
+
* information in an easy-to-read format.
|
260 |
+
*
|
261 |
+
* @param array $query The WP_Query object.
|
262 |
+
*
|
263 |
+
* @return string The formatted debugging information.
|
264 |
+
*
|
265 |
+
* @since 2.2.0
|
266 |
+
*/
|
267 |
+
function relevanssi_admin_search_debugging_info( $query ) {
|
268 |
+
$result = '<h3>' . __( 'Query variables', 'relevanssi' ) . '</h3>';
|
269 |
+
$result .= '<ul style="list-style: disc; margin-left: 1.5em">';
|
270 |
+
foreach ( $query->query_vars as $key => $value ) {
|
271 |
+
if ( is_array( $value ) ) {
|
272 |
+
$value = implode( ', ', $value );
|
273 |
+
}
|
274 |
+
if ( empty( $value ) ) {
|
275 |
+
continue;
|
276 |
+
}
|
277 |
+
$result .= "<li>$key: $value</li>";
|
278 |
+
}
|
279 |
+
if ( ! empty( $query->tax_query ) ) {
|
280 |
+
$result .= '<li><strong>tax_query</strong>:<ul style="list-style: disc; margin-left: 1.5em">';
|
281 |
+
foreach ( $query->tax_query as $tax_query ) {
|
282 |
+
foreach ( $tax_query as $key => $value ) {
|
283 |
+
if ( is_array( $value ) ) {
|
284 |
+
$value = implode( ', ', $value );
|
285 |
+
}
|
286 |
+
$result .= "<li>$key: $value</li>";
|
287 |
+
}
|
288 |
+
}
|
289 |
+
$result .= '</ul></li>';
|
290 |
+
}
|
291 |
+
$result .= '</ul>';
|
292 |
+
|
293 |
+
global $wp_filter;
|
294 |
+
|
295 |
+
$filters = array(
|
296 |
+
'relevanssi_search_ok',
|
297 |
+
'relevanssi_modify_wp_query',
|
298 |
+
'relevanssi_search_filters',
|
299 |
+
'relevanssi_where',
|
300 |
+
'relevanssi_join',
|
301 |
+
'relevanssi_fuzzy_query',
|
302 |
+
'relevanssi_exact_match_bonus',
|
303 |
+
'relevanssi_query_filter',
|
304 |
+
'relevanssi_match',
|
305 |
+
'relevanssi_post_ok',
|
306 |
+
'relevanssi_search_again',
|
307 |
+
'relevanssi_results',
|
308 |
+
'relevanssi_orderby',
|
309 |
+
'relevanssi_order',
|
310 |
+
'relevanssi_default_tax_query_relation',
|
311 |
+
'relevanssi_default_meta_query_relation',
|
312 |
+
'relevanssi_hits_filter',
|
313 |
+
);
|
314 |
+
|
315 |
+
$result .= '<h3>' . __( 'Filters', 'relevanssi' ) . '</h3>';
|
316 |
+
$result .= '<button type="button" id="show_filters">' . __( 'show', 'relevanssi' ) . '</button>';
|
317 |
+
$result .= '<button type="button" id="hide_filters" style="display: none">' . __( 'hide', 'relevanssi' ) . '</button>';
|
318 |
+
$result .= '<div id="relevanssi_filter_list">';
|
319 |
+
foreach ( $filters as $filter ) {
|
320 |
+
if ( isset( $wp_filter[ $filter ] ) ) {
|
321 |
+
$result .= '<h4>' . $filter . '</h4>';
|
322 |
+
$result .= '<ul style="list-style: disc; margin-left: 1.5em">';
|
323 |
+
foreach ( $wp_filter[ $filter ] as $priority => $functions ) {
|
324 |
+
foreach ( $functions as $function ) {
|
325 |
+
$result .= "<li>$priority: " . $function['function'] . '</li>';
|
326 |
+
}
|
327 |
+
}
|
328 |
+
$result .= '</ul>';
|
329 |
+
}
|
330 |
+
}
|
331 |
+
$result .= '</div>';
|
332 |
+
|
333 |
+
return $result;
|
334 |
+
}
|
lib/admin_scripts.js
CHANGED
@@ -53,7 +53,12 @@ jQuery(document).ready(function($){
|
|
53 |
$("#relevanssi_index_taxonomies").click(function() {
|
54 |
taxonomies.toggleClass('screen-reader-text', !this.checked);
|
55 |
});
|
56 |
-
|
|
|
|
|
|
|
|
|
|
|
57 |
var fields_content = $("#index_field_input");
|
58 |
var fields_select = $("#relevanssi_index_fields_select");
|
59 |
fields_select.change(function() {
|
@@ -307,4 +312,90 @@ function rlv_format_approximate_time(total_seconds) {
|
|
307 |
if (minutes < 1) time = relevanssi.underminute;
|
308 |
|
309 |
return time;
|
310 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
$("#relevanssi_index_taxonomies").click(function() {
|
54 |
taxonomies.toggleClass('screen-reader-text', !this.checked);
|
55 |
});
|
56 |
+
|
57 |
+
var post_type_archives = $("#posttypearchives");
|
58 |
+
$("#relevanssi_index_post_type_archives").click(function() {
|
59 |
+
post_type_archives.toggleClass('screen-reader-text', !this.checked);
|
60 |
+
});
|
61 |
+
|
62 |
var fields_content = $("#index_field_input");
|
63 |
var fields_select = $("#relevanssi_index_fields_select");
|
64 |
fields_select.change(function() {
|
312 |
if (minutes < 1) time = relevanssi.underminute;
|
313 |
|
314 |
return time;
|
315 |
+
}
|
316 |
+
|
317 |
+
jQuery(document).ready(function($) {
|
318 |
+
$('#search').click(function(e) {
|
319 |
+
var results = document.getElementById("results");
|
320 |
+
results.innerHTML = 'Searching...';
|
321 |
+
e.preventDefault();
|
322 |
+
jQuery.ajax({
|
323 |
+
type: 'POST',
|
324 |
+
url: ajaxurl,
|
325 |
+
data: {
|
326 |
+
action: 'relevanssi_admin_search',
|
327 |
+
args: document.getElementById('args').value,
|
328 |
+
posts_per_page: document.getElementById('posts_per_page').value,
|
329 |
+
s: document.getElementById('s').value,
|
330 |
+
security : nonce.searching_nonce,
|
331 |
+
},
|
332 |
+
dataType: 'json',
|
333 |
+
success: function(response) {
|
334 |
+
results.innerHTML = response;
|
335 |
+
}
|
336 |
+
});
|
337 |
+
});
|
338 |
+
|
339 |
+
$(document).on('click', '#show_filters', function(e) {
|
340 |
+
$('#relevanssi_filter_list').toggle();
|
341 |
+
$('#show_filters').toggle();
|
342 |
+
$('#hide_filters').toggle();
|
343 |
+
});
|
344 |
+
|
345 |
+
$(document).on('click', '#hide_filters', function(e) {
|
346 |
+
$('#relevanssi_filter_list').toggle();
|
347 |
+
$('#show_filters').toggle();
|
348 |
+
$('#hide_filters').toggle();
|
349 |
+
});
|
350 |
+
|
351 |
+
$(document).on('click', '#next_page', function(e) {
|
352 |
+
var results = document.getElementById("results");
|
353 |
+
e.preventDefault();
|
354 |
+
var offset = parseInt(document.getElementById('offset').innerHTML);
|
355 |
+
var posts = parseInt(document.getElementById('posts_per_page').value);
|
356 |
+
offset = offset + posts;
|
357 |
+
results.innerHTML = 'Searching...';
|
358 |
+
jQuery.ajax({
|
359 |
+
type: 'POST',
|
360 |
+
url: ajaxurl,
|
361 |
+
data: {
|
362 |
+
action: 'relevanssi_admin_search',
|
363 |
+
args: document.getElementById('args').value,
|
364 |
+
posts_per_page: document.getElementById('posts_per_page').value,
|
365 |
+
s: document.getElementById('s').value,
|
366 |
+
offset: offset,
|
367 |
+
security : nonce.searching_nonce,
|
368 |
+
},
|
369 |
+
dataType: 'json',
|
370 |
+
success: function(response) {
|
371 |
+
results.innerHTML = response;
|
372 |
+
}
|
373 |
+
});
|
374 |
+
});
|
375 |
+
|
376 |
+
$(document).on('click', '#prev_page', function(e) {
|
377 |
+
var results = document.getElementById("results");
|
378 |
+
e.preventDefault();
|
379 |
+
var offset = parseInt(document.getElementById('offset').innerHTML);
|
380 |
+
var posts = parseInt(document.getElementById('posts_per_page').value);
|
381 |
+
offset = offset - posts;
|
382 |
+
if ( offset < 0 ) offset = 0;
|
383 |
+
results.innerHTML = 'Searching...';
|
384 |
+
jQuery.ajax({
|
385 |
+
type: 'POST',
|
386 |
+
url: ajaxurl,
|
387 |
+
data: {
|
388 |
+
action: 'relevanssi_admin_search',
|
389 |
+
args: document.getElementById('args').value,
|
390 |
+
posts_per_page: document.getElementById('posts_per_page').value,
|
391 |
+
s: document.getElementById('s').value,
|
392 |
+
offset: offset,
|
393 |
+
security : nonce.searching_nonce,
|
394 |
+
},
|
395 |
+
dataType: 'json',
|
396 |
+
success: function(response) {
|
397 |
+
results.innerHTML = response;
|
398 |
+
}
|
399 |
+
});
|
400 |
+
});
|
401 |
+
});
|
lib/admin_styles.css
CHANGED
@@ -95,4 +95,12 @@ table.form-table table.widefat th {
|
|
95 |
|
96 |
#relevanssi-timer {
|
97 |
display: none;
|
98 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
|
96 |
#relevanssi-timer {
|
97 |
display: none;
|
98 |
+
}
|
99 |
+
|
100 |
+
#category_inclusion_checklist ul.children, #category_exclusion_checklist ul.children {
|
101 |
+
margin-left: 1.5em;
|
102 |
+
}
|
103 |
+
|
104 |
+
#relevanssi_filter_list {
|
105 |
+
display: none;
|
106 |
+
}
|
lib/common.php
CHANGED
@@ -103,7 +103,6 @@ function relevanssi_show_matches( $data, $hit ) {
|
|
103 |
} else {
|
104 |
$term_hits_array = array();
|
105 |
}
|
106 |
-
|
107 |
$term_hits = '';
|
108 |
$total_hits = 0;
|
109 |
foreach ( $term_hits_array as $term => $hits ) {
|
@@ -197,7 +196,13 @@ function relevanssi_default_post_ok( $post_ok, $post_id ) {
|
|
197 |
// WP JV Post Reading Groups.
|
198 |
$post_ok = wp_jv_prg_user_can_see_a_post( get_current_user_id(), $post_id );
|
199 |
}
|
200 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
201 |
/**
|
202 |
* Filters statuses allowed in admin searches.
|
203 |
*
|
@@ -337,6 +342,7 @@ function relevanssi_recognize_phrases( $search_query ) {
|
|
337 |
if ( count( $phrases ) > 0 ) {
|
338 |
foreach ( $phrases as $phrase ) {
|
339 |
$queries = array();
|
|
|
340 |
$phrase = str_replace( '‘', '_', $phrase );
|
341 |
$phrase = str_replace( '’', '_', $phrase );
|
342 |
$phrase = str_replace( "'", '_', $phrase );
|
@@ -345,7 +351,6 @@ function relevanssi_recognize_phrases( $search_query ) {
|
|
345 |
$phrase = str_replace( '“', '_', $phrase );
|
346 |
$phrase = str_replace( '„', '_', $phrase );
|
347 |
$phrase = str_replace( '´', '_', $phrase );
|
348 |
-
$phrase = $wpdb->esc_like( $phrase );
|
349 |
$phrase = esc_sql( $phrase );
|
350 |
$excerpt = '';
|
351 |
if ( 'on' === get_option( 'relevanssi_index_excerpt' ) ) {
|
@@ -804,7 +809,7 @@ function relevanssi_tokenize( $string, $remove_stops = true, $min_word_length =
|
|
804 |
function relevanssi_get_post_status( $post_id ) {
|
805 |
global $relevanssi_post_array;
|
806 |
$type = substr( $post_id, 0, 2 );
|
807 |
-
if ( '**' === $type || 'u_' === $type ) {
|
808 |
// Taxonomy term or user (a Premium feature).
|
809 |
return 'publish';
|
810 |
}
|
@@ -1406,8 +1411,7 @@ function relevanssi_simple_generate_suggestion( $query ) {
|
|
1406 |
break;
|
1407 |
} else {
|
1408 |
$lev = levenshtein( $token, $row->query );
|
1409 |
-
|
1410 |
-
if ( $lev < $distance || $distance < 0 ) {
|
1411 |
if ( $row->a > 0 ) {
|
1412 |
$distance = $lev;
|
1413 |
$closest = $row->query;
|
103 |
} else {
|
104 |
$term_hits_array = array();
|
105 |
}
|
|
|
106 |
$term_hits = '';
|
107 |
$total_hits = 0;
|
108 |
foreach ( $term_hits_array as $term => $hits ) {
|
196 |
// WP JV Post Reading Groups.
|
197 |
$post_ok = wp_jv_prg_user_can_see_a_post( get_current_user_id(), $post_id );
|
198 |
}
|
199 |
+
if ( class_exists( 'AAM', false ) ) {
|
200 |
+
$object = AAM::api()->getUser()->getObject( 'post', $post_id );
|
201 |
+
if ( $object->has( 'frontend.read' ) ) {
|
202 |
+
// Current user is not allowed to see this post.
|
203 |
+
$post_ok = false;
|
204 |
+
}
|
205 |
+
}
|
206 |
/**
|
207 |
* Filters statuses allowed in admin searches.
|
208 |
*
|
342 |
if ( count( $phrases ) > 0 ) {
|
343 |
foreach ( $phrases as $phrase ) {
|
344 |
$queries = array();
|
345 |
+
$phrase = $wpdb->esc_like( $phrase );
|
346 |
$phrase = str_replace( '‘', '_', $phrase );
|
347 |
$phrase = str_replace( '’', '_', $phrase );
|
348 |
$phrase = str_replace( "'", '_', $phrase );
|
351 |
$phrase = str_replace( '“', '_', $phrase );
|
352 |
$phrase = str_replace( '„', '_', $phrase );
|
353 |
$phrase = str_replace( '´', '_', $phrase );
|
|
|
354 |
$phrase = esc_sql( $phrase );
|
355 |
$excerpt = '';
|
356 |
if ( 'on' === get_option( 'relevanssi_index_excerpt' ) ) {
|
809 |
function relevanssi_get_post_status( $post_id ) {
|
810 |
global $relevanssi_post_array;
|
811 |
$type = substr( $post_id, 0, 2 );
|
812 |
+
if ( '**' === $type || 'u_' === $type || 'p_' === $type ) {
|
813 |
// Taxonomy term or user (a Premium feature).
|
814 |
return 'publish';
|
815 |
}
|
1411 |
break;
|
1412 |
} else {
|
1413 |
$lev = levenshtein( $token, $row->query );
|
1414 |
+
if ( $lev < 3 && ( $lev < $distance || $distance < 0 ) ) {
|
|
|
1415 |
if ( $row->a > 0 ) {
|
1416 |
$distance = $lev;
|
1417 |
$closest = $row->query;
|
lib/compatibility/polylang.php
CHANGED
@@ -86,7 +86,7 @@ function relevanssi_polylang_where_include_terms( $where ) {
|
|
86 |
$languages = get_terms( array( 'taxonomy' => 'language' ) );
|
87 |
$language_id = 0;
|
88 |
foreach ( $languages as $language ) {
|
89 |
-
if ( $language->slug === $current_language ) {
|
90 |
$language_id = intval( $language->term_id );
|
91 |
break;
|
92 |
}
|
86 |
$languages = get_terms( array( 'taxonomy' => 'language' ) );
|
87 |
$language_id = 0;
|
88 |
foreach ( $languages as $language ) {
|
89 |
+
if ( ! is_wp_error( $language ) && $language instanceof WP_Term && $language->slug === $current_language ) {
|
90 |
$language_id = intval( $language->term_id );
|
91 |
break;
|
92 |
}
|
lib/compatibility/wp-search-suggest.php
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* /lib/compatibility/wp-search-suggest.php
|
4 |
+
*
|
5 |
+
* WP Search Suggest compatibility features.
|
6 |
+
*
|
7 |
+
* @package Relevanssi
|
8 |
+
* @author Mikko Saari
|
9 |
+
* @license https://wordpress.org/about/gpl/ GNU General Public License
|
10 |
+
* @see https://www.relevanssi.com/
|
11 |
+
*/
|
12 |
+
|
13 |
+
add_filter( 'wpss_search_results', 'relevanssi_wpss_support', 10, 2 );
|
14 |
+
/**
|
15 |
+
* Adds Relevanssi results to WP Search Suggest dropdown.
|
16 |
+
*
|
17 |
+
* @param array $list List of post titles.
|
18 |
+
* @param object $query The WP_Query object.
|
19 |
+
*
|
20 |
+
* @return array List of post titles.
|
21 |
+
*/
|
22 |
+
function relevanssi_wpss_support( $list, $query ) {
|
23 |
+
$query = relevanssi_do_query( $query );
|
24 |
+
return wp_list_pluck( $query->posts, 'post_title' );
|
25 |
+
}
|
lib/compatibility/wpml.php
CHANGED
@@ -84,8 +84,9 @@ function relevanssi_wpml_filter( $data ) {
|
|
84 |
return $data;
|
85 |
}
|
86 |
|
87 |
-
|
88 |
-
|
|
|
89 |
/**
|
90 |
* Removes WPML filters from get_term().
|
91 |
*
|
84 |
return $data;
|
85 |
}
|
86 |
|
87 |
+
add_action( 'wp_ajax_relevanssi_index_posts', 'relevanssi_wpml_remove_filters', 5 );
|
88 |
+
add_action( 'wp_ajax_relevanssi_index_taxonomies', 'relevanssi_wpml_remove_filters', 5 );
|
89 |
+
|
90 |
/**
|
91 |
* Removes WPML filters from get_term().
|
92 |
*
|
lib/excerpts-highlights.php
CHANGED
@@ -170,9 +170,10 @@ function relevanssi_do_excerpt( $t_post, $query ) {
|
|
170 |
* Filters the post excerpt generated by Relevanssi before the highlighting is
|
171 |
* applied.
|
172 |
*
|
173 |
-
* @param string $excerpt
|
|
|
174 |
*/
|
175 |
-
$excerpt = apply_filters( 'relevanssi_excerpt', $excerpt );
|
176 |
|
177 |
$whole_post_excerpted = false;
|
178 |
if ( $excerpt === $post->post_content ) {
|
@@ -535,7 +536,7 @@ function relevanssi_highlight_terms( $content, $query, $in_docs = false ) {
|
|
535 |
}
|
536 |
}
|
537 |
|
538 |
-
if ( preg_match_all( '/<(style|script|object|embed|pre|code)
|
539 |
// Remove highlights in style, object, embed, script and pre tags.
|
540 |
foreach ( $matches as $match ) {
|
541 |
$new_match = str_replace( $start_emp_token, '', $match );
|
@@ -638,10 +639,26 @@ function relevanssi_fix_entities( $excerpt, $in_docs ) {
|
|
638 |
$excerpt = str_replace( ''', "'", $excerpt );
|
639 |
} else {
|
640 |
// Running htmlentities() for whole posts tends to ruin things.
|
641 |
-
// However, we want to run htmlentities() for anything inside
|
642 |
// <pre> and <code> tags.
|
643 |
-
|
644 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
645 |
}
|
646 |
return $excerpt;
|
647 |
}
|
@@ -995,7 +1012,7 @@ function relevanssi_get_custom_field_content( $post_id ) {
|
|
995 |
$remove_underscore_fields = true;
|
996 |
}
|
997 |
/* Documented in lib/indexing.php. */
|
998 |
-
$custom_fields = apply_filters( 'relevanssi_index_custom_fields', $custom_fields );
|
999 |
|
1000 |
if ( function_exists( 'relevanssi_get_child_pdf_content' ) ) {
|
1001 |
$custom_field_content .= ' ' . relevanssi_get_child_pdf_content( $post_id );
|
170 |
* Filters the post excerpt generated by Relevanssi before the highlighting is
|
171 |
* applied.
|
172 |
*
|
173 |
+
* @param string $excerpt The excerpt.
|
174 |
+
* @param int $post->ID The post ID.
|
175 |
*/
|
176 |
+
$excerpt = apply_filters( 'relevanssi_excerpt', $excerpt, $post->ID );
|
177 |
|
178 |
$whole_post_excerpted = false;
|
179 |
if ( $excerpt === $post->post_content ) {
|
536 |
}
|
537 |
}
|
538 |
|
539 |
+
if ( preg_match_all( '/<(style|script|object|embed|pre|code).*<\/(style|script|object|embed|pre|code)>/U', $content, $matches ) > 0 ) {
|
540 |
// Remove highlights in style, object, embed, script and pre tags.
|
541 |
foreach ( $matches as $match ) {
|
542 |
$new_match = str_replace( $start_emp_token, '', $match );
|
639 |
$excerpt = str_replace( ''', "'", $excerpt );
|
640 |
} else {
|
641 |
// Running htmlentities() for whole posts tends to ruin things.
|
642 |
+
// However, we may want to run htmlentities() for anything inside
|
643 |
// <pre> and <code> tags.
|
644 |
+
/**
|
645 |
+
* Choose whether htmlentities() is run inside <pre> tags or not. If your
|
646 |
+
* pages have HTML code inside <pre> tags, set this to false.
|
647 |
+
*
|
648 |
+
* @param boolean If true, htmlentities() will be used inside <pre> tags.
|
649 |
+
*/
|
650 |
+
if ( apply_filters( 'relevanssi_entities_inside_pre', true ) ) {
|
651 |
+
$excerpt = relevanssi_entities_inside( $excerpt, 'pre' );
|
652 |
+
}
|
653 |
+
/**
|
654 |
+
* Choose whether htmlentities() is run inside <code> tags or not. If your
|
655 |
+
* pages have HTML code inside <code> tags, set this to false.
|
656 |
+
*
|
657 |
+
* @param boolean If true, htmlentities() will be used inside <code> tags.
|
658 |
+
*/
|
659 |
+
if ( apply_filters( 'relevanssi_entities_inside_code', true ) ) {
|
660 |
+
$excerpt = relevanssi_entities_inside( $excerpt, 'code' );
|
661 |
+
}
|
662 |
}
|
663 |
return $excerpt;
|
664 |
}
|
1012 |
$remove_underscore_fields = true;
|
1013 |
}
|
1014 |
/* Documented in lib/indexing.php. */
|
1015 |
+
$custom_fields = apply_filters( 'relevanssi_index_custom_fields', $custom_fields, $post_id );
|
1016 |
|
1017 |
if ( function_exists( 'relevanssi_get_child_pdf_content' ) ) {
|
1018 |
$custom_field_content .= ' ' . relevanssi_get_child_pdf_content( $post_id );
|
lib/indexing.php
CHANGED
@@ -179,6 +179,9 @@ function relevanssi_post_type_restriction() {
|
|
179 |
}
|
180 |
}
|
181 |
|
|
|
|
|
|
|
182 |
if ( count( $post_types ) > 0 ) {
|
183 |
$restriction = ' AND post.post_type IN (' . implode( ', ', $post_types ) . ') ';
|
184 |
}
|
179 |
}
|
180 |
}
|
181 |
|
182 |
+
if ( empty( $post_types ) ) {
|
183 |
+
$post_types[] = "'no_post_types_chosen_so_index_no_posts'";
|
184 |
+
}
|
185 |
if ( count( $post_types ) > 0 ) {
|
186 |
$restriction = ' AND post.post_type IN (' . implode( ', ', $post_types ) . ') ';
|
187 |
}
|
lib/init.php
CHANGED
@@ -52,6 +52,9 @@ add_filter( 'post_link', 'relevanssi_permalink', 10, 2 );
|
|
52 |
add_filter( 'page_link', 'relevanssi_permalink', 10, 2 );
|
53 |
add_filter( 'relevanssi_permalink', 'relevanssi_permalink' );
|
54 |
|
|
|
|
|
|
|
55 |
global $relevanssi_variables;
|
56 |
register_activation_hook( $relevanssi_variables['file'], 'relevanssi_install' );
|
57 |
|
@@ -121,17 +124,21 @@ function relevanssi_init() {
|
|
121 |
require_once 'compatibility/wpml.php';
|
122 |
}
|
123 |
|
124 |
-
if (
|
125 |
require_once 'compatibility/polylang.php';
|
126 |
}
|
127 |
|
128 |
-
if ( class_exists( 'WooCommerce' ) ) {
|
129 |
require_once 'compatibility/woocommerce.php';
|
130 |
}
|
131 |
|
132 |
-
if ( class_exists( 'acf' ) ) {
|
133 |
require_once 'compatibility/acf.php';
|
134 |
}
|
|
|
|
|
|
|
|
|
135 |
}
|
136 |
|
137 |
/**
|
@@ -183,6 +190,18 @@ function relevanssi_menu() {
|
|
183 |
$relevanssi_variables['file'],
|
184 |
'relevanssi_search_stats'
|
185 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
186 |
require_once 'contextual-help.php';
|
187 |
add_action( 'load-' . $plugin_page, 'relevanssi_admin_help' );
|
188 |
if ( function_exists( 'relevanssi_premium_plugin_page_actions' ) ) {
|
@@ -381,3 +400,17 @@ function relevanssi_rest_api_disable() {
|
|
381 |
remove_filter( 'posts_request', 'relevanssi_prevent_default_request' );
|
382 |
remove_filter( 'the_posts', 'relevanssi_query', 99 );
|
383 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
add_filter( 'page_link', 'relevanssi_permalink', 10, 2 );
|
53 |
add_filter( 'relevanssi_permalink', 'relevanssi_permalink' );
|
54 |
|
55 |
+
// Log exports.
|
56 |
+
add_action( 'plugins_loaded', 'relevanssi_export_log_check' );
|
57 |
+
|
58 |
global $relevanssi_variables;
|
59 |
register_activation_hook( $relevanssi_variables['file'], 'relevanssi_install' );
|
60 |
|
124 |
require_once 'compatibility/wpml.php';
|
125 |
}
|
126 |
|
127 |
+
if ( class_exists( 'Polylang', false ) ) {
|
128 |
require_once 'compatibility/polylang.php';
|
129 |
}
|
130 |
|
131 |
+
if ( class_exists( 'WooCommerce', false ) ) {
|
132 |
require_once 'compatibility/woocommerce.php';
|
133 |
}
|
134 |
|
135 |
+
if ( class_exists( 'acf', false ) ) {
|
136 |
require_once 'compatibility/acf.php';
|
137 |
}
|
138 |
+
|
139 |
+
if ( class_exists( 'Obenland_Wp_Search_Suggest', false ) ) {
|
140 |
+
require_once 'compatibility/wp-search-suggest.php';
|
141 |
+
}
|
142 |
}
|
143 |
|
144 |
/**
|
190 |
$relevanssi_variables['file'],
|
191 |
'relevanssi_search_stats'
|
192 |
);
|
193 |
+
add_dashboard_page(
|
194 |
+
__( 'Admin search', 'relevanssi' ),
|
195 |
+
__( 'Admin search', 'relevanssi' ),
|
196 |
+
/**
|
197 |
+
* Filters the capability required to access Relevanssi admin search page.
|
198 |
+
*
|
199 |
+
* @param string The capability required. Default 'edit_posts'.
|
200 |
+
*/
|
201 |
+
apply_filters( 'relevanssi_admin_search_capability', 'edit_posts' ),
|
202 |
+
'relevanssi_admin_search',
|
203 |
+
'relevanssi_admin_search_page'
|
204 |
+
);
|
205 |
require_once 'contextual-help.php';
|
206 |
add_action( 'load-' . $plugin_page, 'relevanssi_admin_help' );
|
207 |
if ( function_exists( 'relevanssi_premium_plugin_page_actions' ) ) {
|
400 |
remove_filter( 'posts_request', 'relevanssi_prevent_default_request' );
|
401 |
remove_filter( 'the_posts', 'relevanssi_query', 99 );
|
402 |
}
|
403 |
+
|
404 |
+
/**
|
405 |
+
* Checks if a log export is requested.
|
406 |
+
*
|
407 |
+
* If the 'relevanssi_export' query variable is set, a log export has been requested
|
408 |
+
* and one will be provided by relevanssi_export_log().
|
409 |
+
*
|
410 |
+
* @see relevanssi_export_log
|
411 |
+
*/
|
412 |
+
function relevanssi_export_log_check() {
|
413 |
+
if ( isset( $_REQUEST['relevanssi_export'] ) ) { // WPCS: CSRF ok, just checking the parameter exists.
|
414 |
+
relevanssi_export_log();
|
415 |
+
}
|
416 |
+
}
|
lib/interface.php
CHANGED
@@ -232,10 +232,19 @@ function update_relevanssi_options() {
|
|
232 |
if ( empty( $value ) ) {
|
233 |
$value = 0;
|
234 |
}
|
|
|
235 |
if ( 'relevanssi_weight_' === substr( $key, 0, strlen( 'relevanssi_weight_' ) ) ) {
|
236 |
$type = substr( $key, strlen( 'relevanssi_weight_' ) );
|
237 |
$post_type_weights[ $type ] = $value;
|
238 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
239 |
if ( 'relevanssi_index_type_' === substr( $key, 0, strlen( 'relevanssi_index_type_' ) ) ) {
|
240 |
$type = substr( $key, strlen( 'relevanssi_index_type_' ) );
|
241 |
if ( 'on' === $value ) {
|
@@ -456,6 +465,27 @@ function relevanssi_search_stats() {
|
|
456 |
}
|
457 |
}
|
458 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
459 |
/**
|
460 |
* Truncates the Relevanssi logs.
|
461 |
*
|
@@ -731,6 +761,7 @@ function relevanssi_options_form() {
|
|
731 |
<a href="<?php echo esc_attr( $this_page ); ?>&tab=stopwords" class="nav-tab <?php echo 'stopwords' === $active_tab ? 'nav-tab-active' : ''; ?>"><?php esc_html_e( 'Stopwords', 'relevanssi' ); ?></a>
|
732 |
<?php if ( RELEVANSSI_PREMIUM ) : ?>
|
733 |
<a href="<?php echo esc_attr( $this_page ); ?>&tab=importexport" class="nav-tab <?php echo 'importexport' === $active_tab ? 'nav-tab-active' : ''; ?>"><?php esc_html_e( 'Import / Export options', 'relevanssi' ); ?></a>
|
|
|
734 |
<?php endif; ?>
|
735 |
</h2>
|
736 |
|
@@ -816,6 +847,7 @@ function relevanssi_add_admin_scripts( $hook ) {
|
|
816 |
'settings_page_relevanssi-premium/relevanssi',
|
817 |
'toplevel_page_relevanssi/relevanssi',
|
818 |
'settings_page_relevanssi/relevanssi',
|
|
|
819 |
);
|
820 |
if ( ! in_array( $hook, $acceptable_hooks, true ) ) {
|
821 |
return;
|
232 |
if ( empty( $value ) ) {
|
233 |
$value = 0;
|
234 |
}
|
235 |
+
|
236 |
if ( 'relevanssi_weight_' === substr( $key, 0, strlen( 'relevanssi_weight_' ) ) ) {
|
237 |
$type = substr( $key, strlen( 'relevanssi_weight_' ) );
|
238 |
$post_type_weights[ $type ] = $value;
|
239 |
}
|
240 |
+
if ( 'relevanssi_taxonomy_weight_' === substr( $key, 0, strlen( 'relevanssi_taxonomy_weight_' ) ) ) {
|
241 |
+
$type = 'post_tagged_with_' . substr( $key, strlen( 'relevanssi_taxonomy_weight_' ) );
|
242 |
+
$post_type_weights[ $type ] = $value;
|
243 |
+
}
|
244 |
+
if ( 'relevanssi_term_weight_' === substr( $key, 0, strlen( 'relevanssi_term_weight_' ) ) ) {
|
245 |
+
$type = 'taxonomy_term_' . substr( $key, strlen( 'relevanssi_term_weight_' ) );
|
246 |
+
$post_type_weights[ $type ] = $value;
|
247 |
+
}
|
248 |
if ( 'relevanssi_index_type_' === substr( $key, 0, strlen( 'relevanssi_index_type_' ) ) ) {
|
249 |
$type = substr( $key, strlen( 'relevanssi_index_type_' ) );
|
250 |
if ( 'on' === $value ) {
|
465 |
}
|
466 |
}
|
467 |
|
468 |
+
/**
|
469 |
+
* Prints out the 'Admin search' page.
|
470 |
+
*/
|
471 |
+
function relevanssi_admin_search_page() {
|
472 |
+
global $relevanssi_variables;
|
473 |
+
|
474 |
+
$relevanssi_hide_branding = get_option( 'relevanssi_hide_branding' );
|
475 |
+
|
476 |
+
$options_txt = __( 'Admin Search', 'relevanssi' );
|
477 |
+
|
478 |
+
wp_enqueue_style( 'dashboard' );
|
479 |
+
wp_print_styles( 'dashboard' );
|
480 |
+
wp_enqueue_script( 'dashboard' );
|
481 |
+
wp_print_scripts( 'dashboard' );
|
482 |
+
|
483 |
+
printf( "<div class='wrap'><h2>%s</h2>", esc_html( $options_txt ) );
|
484 |
+
|
485 |
+
require_once dirname( $relevanssi_variables['file'] ) . '/lib/tabs/search-page.php';
|
486 |
+
relevanssi_search_tab();
|
487 |
+
}
|
488 |
+
|
489 |
/**
|
490 |
* Truncates the Relevanssi logs.
|
491 |
*
|
761 |
<a href="<?php echo esc_attr( $this_page ); ?>&tab=stopwords" class="nav-tab <?php echo 'stopwords' === $active_tab ? 'nav-tab-active' : ''; ?>"><?php esc_html_e( 'Stopwords', 'relevanssi' ); ?></a>
|
762 |
<?php if ( RELEVANSSI_PREMIUM ) : ?>
|
763 |
<a href="<?php echo esc_attr( $this_page ); ?>&tab=importexport" class="nav-tab <?php echo 'importexport' === $active_tab ? 'nav-tab-active' : ''; ?>"><?php esc_html_e( 'Import / Export options', 'relevanssi' ); ?></a>
|
764 |
+
<a href="<?php echo esc_attr( $this_page ); ?>&tab=search" class="nav-tab <?php echo 'search' === $active_tab ? 'nav-tab-active' : ''; ?>"><?php echo esc_html_x( 'Search', 'noun', 'relevanssi' ); ?></a>
|
765 |
<?php endif; ?>
|
766 |
</h2>
|
767 |
|
847 |
'settings_page_relevanssi-premium/relevanssi',
|
848 |
'toplevel_page_relevanssi/relevanssi',
|
849 |
'settings_page_relevanssi/relevanssi',
|
850 |
+
'dashboard_page_relevanssi_admin_search',
|
851 |
);
|
852 |
if ( ! in_array( $hook, $acceptable_hooks, true ) ) {
|
853 |
return;
|
lib/log.php
CHANGED
@@ -233,3 +233,37 @@ function relevanssi_erase_log_data( $user_id, $page ) {
|
|
233 |
'done' => $done,
|
234 |
);
|
235 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
233 |
'done' => $done,
|
234 |
);
|
235 |
}
|
236 |
+
|
237 |
+
/**
|
238 |
+
* Prints out the Relevanssi log as a CSV file.
|
239 |
+
*
|
240 |
+
* Exports the whole Relevanssi search log as a CSV file.
|
241 |
+
*
|
242 |
+
* @since 2.2
|
243 |
+
*/
|
244 |
+
function relevanssi_export_log() {
|
245 |
+
global $wpdb, $relevanssi_variables;
|
246 |
+
|
247 |
+
$now = gmdate( 'D, d M Y H:i:s' );
|
248 |
+
$filename = 'relevanssi_log.csv';
|
249 |
+
|
250 |
+
header( '"Expires: Tue, 03 Jul 2001 06:00:00 GMT' );
|
251 |
+
header( 'Cache-Control: max-age=0, no-cache, must-revalidate, proxy-revalidate' );
|
252 |
+
header( "Last-Modified: {$now} GMT" );
|
253 |
+
header( 'Content-Type: application/force-download' );
|
254 |
+
header( 'Content-Type: application/octet-stream' );
|
255 |
+
header( 'Content-Type: application/download' );
|
256 |
+
header( "Content-Disposition: attachment;filename={$filename}" );
|
257 |
+
header( 'Content-Transfer-Encoding: binary' );
|
258 |
+
|
259 |
+
$data = $wpdb->get_results( 'SELECT * FROM ' . $relevanssi_variables['log_table'], ARRAY_A ); // WPCS: unprepared SQL ok. Relevanssi table name.
|
260 |
+
ob_start();
|
261 |
+
$df = fopen( 'php://output', 'w' ); // phpcs:ignore WordPress.WP.AlternativeFunctions
|
262 |
+
fputcsv( $df, array_keys( reset( $data ) ) );
|
263 |
+
foreach ( $data as $row ) {
|
264 |
+
fputcsv( $df, $row );
|
265 |
+
}
|
266 |
+
fclose( $df ); // phpcs:ignore WordPress.WP.AlternativeFunctions
|
267 |
+
echo ob_get_clean(); // WPCS XSS ok.
|
268 |
+
die();
|
269 |
+
}
|
lib/search.php
CHANGED
@@ -21,12 +21,6 @@
|
|
21 |
* @param WP_Query $query The WP_Query object, default false.
|
22 |
*/
|
23 |
function relevanssi_query( $posts, $query = false ) {
|
24 |
-
$admin_search_option = get_option( 'relevanssi_admin_search' );
|
25 |
-
$admin_search = false;
|
26 |
-
if ( 'on' === $admin_search_option ) {
|
27 |
-
$admin_search = true;
|
28 |
-
}
|
29 |
-
|
30 |
global $relevanssi_active;
|
31 |
|
32 |
if ( ! $query ) {
|
@@ -45,8 +39,9 @@ function relevanssi_query( $posts, $query = false ) {
|
|
45 |
// use 'admin_ajax' hook (which sets is_admin() to true whether it's an admin search
|
46 |
// or not.
|
47 |
if ( $query->is_search() && $query->is_admin ) {
|
48 |
-
$search_ok
|
49 |
-
|
|
|
50 |
$search_ok = true; // Yes, we can search!
|
51 |
}
|
52 |
}
|
@@ -121,25 +116,27 @@ function relevanssi_search( $args ) {
|
|
121 |
*
|
122 |
* @param array The search parameters.
|
123 |
*/
|
124 |
-
$filtered_args
|
125 |
-
$q
|
126 |
-
$tax_query
|
127 |
-
$tax_query_relation
|
128 |
-
$post_query
|
129 |
-
$parent_query
|
130 |
-
$meta_query
|
131 |
-
$date_query
|
132 |
-
$expost
|
133 |
-
$post_type
|
134 |
-
$post_status
|
135 |
-
$operator
|
136 |
-
$search_blogs
|
137 |
-
$author
|
138 |
-
$orderby
|
139 |
-
$order
|
140 |
-
$fields
|
141 |
-
$sentence
|
142 |
-
$by_date
|
|
|
|
|
143 |
|
144 |
$hits = array();
|
145 |
$query_restrictions = '';
|
@@ -232,28 +229,28 @@ function relevanssi_search( $args ) {
|
|
232 |
}
|
233 |
|
234 |
if ( is_array( $parent_query ) ) {
|
235 |
-
if (
|
236 |
$valid_values = array();
|
237 |
foreach ( $parent_query['parent in'] as $post_in_id ) {
|
238 |
-
if (
|
239 |
$valid_values[] = $post_in_id;
|
240 |
}
|
241 |
}
|
242 |
$posts = implode( ',', $valid_values );
|
243 |
-
if (
|
244 |
$query_restrictions .= " AND relevanssi.doc IN (SELECT ID FROM $wpdb->posts WHERE post_parent IN ($posts))";
|
245 |
// Clean: $posts is checked to be integers.
|
246 |
}
|
247 |
}
|
248 |
-
if (
|
249 |
$valid_values = array();
|
250 |
foreach ( $parent_query['parent not in'] as $post_not_in_id ) {
|
251 |
-
if (
|
252 |
$valid_values[] = $post_not_in_id;
|
253 |
}
|
254 |
}
|
255 |
$posts = implode( ',', $valid_values );
|
256 |
-
if (
|
257 |
$query_restrictions .= " AND relevanssi.doc NOT IN (SELECT ID FROM $wpdb->posts WHERE post_parent IN ($posts))";
|
258 |
// Clean: $posts is checked to be integers.
|
259 |
}
|
@@ -289,8 +286,8 @@ function relevanssi_search( $args ) {
|
|
289 |
// If $post_type is not set, see if there are post types to exclude from the search.
|
290 |
// If $post_type is set, there's no need to exclude, as we only include.
|
291 |
$negative_post_type = null;
|
292 |
-
if ( ! $post_type ) {
|
293 |
-
$negative_post_type = relevanssi_get_negative_post_type();
|
294 |
}
|
295 |
|
296 |
$non_post_post_type = null;
|
@@ -612,13 +609,25 @@ function relevanssi_search( $args ) {
|
|
612 |
|
613 |
$tag = $relevanssi_variables['post_type_weight_defaults']['post_tag'];
|
614 |
$cat = $relevanssi_variables['post_type_weight_defaults']['category'];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
615 |
if ( ! empty( $post_type_weights['post_tag'] ) ) {
|
616 |
$tag = $post_type_weights['post_tag'];
|
617 |
}
|
618 |
if ( ! empty( $post_type_weights['category'] ) ) {
|
619 |
$cat = $post_type_weights['category'];
|
620 |
}
|
|
|
|
|
621 |
$include_these_posts = array();
|
|
|
622 |
$df_counts = array();
|
623 |
|
624 |
do {
|
@@ -700,6 +709,31 @@ function relevanssi_search( $args ) {
|
|
700 |
relevanssi.taxonomy + relevanssi.customfield + relevanssi.mysqlcolumn AS tf
|
701 |
FROM $relevanssi_table AS relevanssi WHERE relevanssi.doc IN ($post_ids_to_add)
|
702 |
AND relevanssi.doc NOT IN ($existing_ids) AND $term_cond";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
703 |
// Clean: no unescaped user inputs.
|
704 |
$matches_to_add = $wpdb->get_results( $query ); // WPCS: unprepared SQL ok.
|
705 |
$matches = array_merge( $matches, $matches_to_add );
|
@@ -719,6 +753,8 @@ function relevanssi_search( $args ) {
|
|
719 |
foreach ( $matches as $match ) {
|
720 |
if ( 'user' === $match->type ) {
|
721 |
$match->doc = 'u_' . $match->item;
|
|
|
|
|
722 |
} elseif ( ! in_array( $match->type, array( 'post', 'attachment' ), true ) ) {
|
723 |
$match->doc = '**' . $match->type . '**' . $match->item;
|
724 |
}
|
@@ -727,6 +763,16 @@ function relevanssi_search( $args ) {
|
|
727 |
relevanssi_taxonomy_score( $match, $post_type_weights );
|
728 |
} else {
|
729 |
$tag_weight = 1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
730 |
if ( isset( $post_type_weights['post_tag'] ) && is_numeric( $post_type_weights['post_tag'] ) ) {
|
731 |
$tag_weight = $post_type_weights['post_tag'];
|
732 |
}
|
@@ -735,6 +781,7 @@ function relevanssi_search( $args ) {
|
|
735 |
if ( isset( $post_type_weights['category'] ) && is_numeric( $post_type_weights['category'] ) ) {
|
736 |
$category_weight = $post_type_weights['category'];
|
737 |
}
|
|
|
738 |
|
739 |
$taxonomy_weight = 1;
|
740 |
|
@@ -817,6 +864,7 @@ function relevanssi_search( $args ) {
|
|
817 |
$taxonomy_matches[ $match->doc ] += $match->taxonomy;
|
818 |
$comment_matches[ $match->doc ] += $match->comment;
|
819 |
|
|
|
820 |
$type = null;
|
821 |
if ( isset( $relevanssi_post_types[ $match->doc ] ) ) {
|
822 |
$type = $relevanssi_post_types[ $match->doc ];
|
@@ -825,6 +873,11 @@ function relevanssi_search( $args ) {
|
|
825 |
$match->weight = $match->weight * $post_type_weights[ $type ];
|
826 |
}
|
827 |
|
|
|
|
|
|
|
|
|
|
|
828 |
/**
|
829 |
* Filters the hit.
|
830 |
*
|
@@ -868,6 +921,8 @@ function relevanssi_search( $args ) {
|
|
868 |
if ( is_numeric( $match->doc ) ) {
|
869 |
// This is to weed out taxonomies and users (t_XXX, u_XXX).
|
870 |
$include_these_posts[ $match->doc ] = true;
|
|
|
|
|
871 |
}
|
872 |
}
|
873 |
}
|
@@ -1214,6 +1269,11 @@ function relevanssi_do_query( &$query ) {
|
|
1214 |
}
|
1215 |
|
1216 |
$multi_args['meta_query'] = $meta_query;
|
|
|
|
|
|
|
|
|
|
|
1217 |
if ( function_exists( 'relevanssi_search_multi' ) ) {
|
1218 |
$return = relevanssi_search_multi( $multi_args );
|
1219 |
}
|
@@ -1367,14 +1427,6 @@ function relevanssi_do_query( &$query ) {
|
|
1367 |
'operator' => 'AND',
|
1368 |
);
|
1369 |
}
|
1370 |
-
if ( ! empty( $query->query_vars['tag__not_in'] ) ) {
|
1371 |
-
$tax_query[] = array(
|
1372 |
-
'taxonomy' => 'post_tag',
|
1373 |
-
'field' => 'id',
|
1374 |
-
'terms' => $query->query_vars['tag__not_in'],
|
1375 |
-
'operator' => 'NOT IN',
|
1376 |
-
);
|
1377 |
-
}
|
1378 |
if ( ! empty( $query->query_vars['tag_slug__in'] ) ) {
|
1379 |
$tax_query[] = array(
|
1380 |
'taxonomy' => 'post_tag',
|
@@ -1423,6 +1475,7 @@ function relevanssi_do_query( &$query ) {
|
|
1423 |
);
|
1424 |
}
|
1425 |
}
|
|
|
1426 |
}
|
1427 |
|
1428 |
$author = false;
|
@@ -1435,27 +1488,27 @@ function relevanssi_do_query( &$query ) {
|
|
1435 |
}
|
1436 |
|
1437 |
$post_query = array();
|
1438 |
-
if (
|
1439 |
$post_query = array( 'in' => array( $query->query_vars['p'] ) );
|
1440 |
}
|
1441 |
-
if (
|
1442 |
$post_query = array( 'in' => array( $query->query_vars['page_id'] ) );
|
1443 |
}
|
1444 |
-
if (
|
1445 |
$post_query = array( 'in' => $query->query_vars['post__in'] );
|
1446 |
}
|
1447 |
-
if (
|
1448 |
$post_query = array( 'not in' => $query->query_vars['post__not_in'] );
|
1449 |
}
|
1450 |
|
1451 |
$parent_query = array();
|
1452 |
-
if (
|
1453 |
$parent_query = array( 'parent in' => array( $query->query_vars['post_parent'] ) );
|
1454 |
}
|
1455 |
-
if ( ! empty( $query->query_vars['post_parent__in'] ) ) {
|
1456 |
$parent_query = array( 'parent in' => $query->query_vars['post_parent__in'] );
|
1457 |
}
|
1458 |
-
if ( ! empty( $query->query_vars['post_parent__not_in'] ) ) {
|
1459 |
$parent_query = array( 'parent not in' => $query->query_vars['post_parent__not_in'] );
|
1460 |
}
|
1461 |
|
@@ -1596,6 +1649,17 @@ function relevanssi_do_query( &$query ) {
|
|
1596 |
$by_date = $query->query_vars['by_date'];
|
1597 |
}
|
1598 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1599 |
// Add synonyms.
|
1600 |
// This is done here so the new terms will get highlighting.
|
1601 |
if ( 'OR' === $operator ) {
|
@@ -1604,24 +1668,26 @@ function relevanssi_do_query( &$query ) {
|
|
1604 |
}
|
1605 |
|
1606 |
$search_params = array(
|
1607 |
-
'q'
|
1608 |
-
'tax_query'
|
1609 |
-
'tax_query_relation'
|
1610 |
-
'post_query'
|
1611 |
-
'parent_query'
|
1612 |
-
'meta_query'
|
1613 |
-
'date_query'
|
1614 |
-
'expost'
|
1615 |
-
'post_type'
|
1616 |
-
'post_status'
|
1617 |
-
'operator'
|
1618 |
-
'search_blogs'
|
1619 |
-
'author'
|
1620 |
-
'orderby'
|
1621 |
-
'order'
|
1622 |
-
'fields'
|
1623 |
-
'sentence'
|
1624 |
-
'by_date'
|
|
|
|
|
1625 |
);
|
1626 |
|
1627 |
$return = relevanssi_search( $search_params );
|
@@ -1724,21 +1790,38 @@ function relevanssi_do_query( &$query ) {
|
|
1724 |
}
|
1725 |
|
1726 |
if ( 'on' === $make_excerpts && empty( $fields ) ) {
|
|
|
|
|
|
|
1727 |
$post->original_excerpt = $post->post_excerpt;
|
1728 |
$post->post_excerpt = relevanssi_do_excerpt( $post, $q );
|
|
|
|
|
|
|
1729 |
}
|
1730 |
if ( 'on' === get_option( 'relevanssi_show_matches' ) && empty( $fields ) ) {
|
1731 |
$post_id = $post->ID;
|
1732 |
if ( 'user' === $post->post_type ) {
|
1733 |
$post_id = 'u_' . $post->user_id;
|
|
|
|
|
1734 |
} elseif ( isset( $post->term_id ) ) {
|
1735 |
$post_id = '**' . $post->post_type . '**' . $post->term_id;
|
1736 |
}
|
|
|
|
|
|
|
1737 |
$post->post_excerpt .= relevanssi_show_matches( $return, $post_id );
|
1738 |
}
|
1739 |
|
1740 |
-
if ( empty( $fields )
|
1741 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
1742 |
}
|
1743 |
|
1744 |
$posts[] = $post;
|
@@ -1777,21 +1860,23 @@ function relevanssi_limit_filter( $query ) {
|
|
1777 |
*
|
1778 |
* Figures out the post types that are not included in the search.
|
1779 |
*
|
1780 |
-
* @
|
1781 |
*
|
1782 |
* @return string SQL escaped list of excluded post types.
|
1783 |
*/
|
1784 |
-
function relevanssi_get_negative_post_type() {
|
1785 |
-
global $wp_query;
|
1786 |
-
|
1787 |
$negative_post_type = null;
|
1788 |
$negative_post_type_list = array();
|
1789 |
|
1790 |
-
if ( isset( $
|
1791 |
$negative_post_type_list[] = 'attachment';
|
1792 |
}
|
1793 |
|
1794 |
-
|
|
|
|
|
|
|
|
|
1795 |
// If Relevanssi is set to respect exclude_from_search, find out which
|
1796 |
// post types should be excluded from search.
|
1797 |
$pt_1 = get_post_types( array( 'exclude_from_search' => '1' ) );
|
@@ -2158,10 +2243,14 @@ function relevanssi_taxonomy_score( &$match, $post_type_weights ) {
|
|
2158 |
$match->taxonomy_detail = json_decode( $match->taxonomy_detail );
|
2159 |
if ( is_object( $match->taxonomy_detail ) ) {
|
2160 |
foreach ( $match->taxonomy_detail as $tax => $count ) {
|
2161 |
-
if ( empty( $post_type_weights[ $tax ] ) ) {
|
2162 |
-
|
|
|
|
|
|
|
|
|
2163 |
} else {
|
2164 |
-
$match->taxonomy_score += $count * $post_type_weights[ $tax ];
|
2165 |
}
|
2166 |
}
|
2167 |
}
|
21 |
* @param WP_Query $query The WP_Query object, default false.
|
22 |
*/
|
23 |
function relevanssi_query( $posts, $query = false ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
global $relevanssi_active;
|
25 |
|
26 |
if ( ! $query ) {
|
39 |
// use 'admin_ajax' hook (which sets is_admin() to true whether it's an admin search
|
40 |
// or not.
|
41 |
if ( $query->is_search() && $query->is_admin ) {
|
42 |
+
$search_ok = false; // But if this is an admin search, reconsider.
|
43 |
+
$admin_search_option = get_option( 'relevanssi_admin_search' );
|
44 |
+
if ( 'on' === $admin_search_option ) {
|
45 |
$search_ok = true; // Yes, we can search!
|
46 |
}
|
47 |
}
|
116 |
*
|
117 |
* @param array The search parameters.
|
118 |
*/
|
119 |
+
$filtered_args = apply_filters( 'relevanssi_search_filters', $args );
|
120 |
+
$q = $filtered_args['q'];
|
121 |
+
$tax_query = $filtered_args['tax_query'];
|
122 |
+
$tax_query_relation = $filtered_args['tax_query_relation'];
|
123 |
+
$post_query = $filtered_args['post_query'];
|
124 |
+
$parent_query = $filtered_args['parent_query'];
|
125 |
+
$meta_query = $filtered_args['meta_query'];
|
126 |
+
$date_query = $filtered_args['date_query'];
|
127 |
+
$expost = $filtered_args['expost'];
|
128 |
+
$post_type = $filtered_args['post_type'];
|
129 |
+
$post_status = $filtered_args['post_status'];
|
130 |
+
$operator = $filtered_args['operator'];
|
131 |
+
$search_blogs = $filtered_args['search_blogs'];
|
132 |
+
$author = $filtered_args['author'];
|
133 |
+
$orderby = $filtered_args['orderby'];
|
134 |
+
$order = $filtered_args['order'];
|
135 |
+
$fields = $filtered_args['fields'];
|
136 |
+
$sentence = $filtered_args['sentence'];
|
137 |
+
$by_date = $filtered_args['by_date'];
|
138 |
+
$admin_search = $filtered_args['admin_search'];
|
139 |
+
$include_attachments = $filtered_args['include_attachments'];
|
140 |
|
141 |
$hits = array();
|
142 |
$query_restrictions = '';
|
229 |
}
|
230 |
|
231 |
if ( is_array( $parent_query ) ) {
|
232 |
+
if ( isset( $parent_query['parent in'] ) ) {
|
233 |
$valid_values = array();
|
234 |
foreach ( $parent_query['parent in'] as $post_in_id ) {
|
235 |
+
if ( is_int( $post_in_id ) ) {
|
236 |
$valid_values[] = $post_in_id;
|
237 |
}
|
238 |
}
|
239 |
$posts = implode( ',', $valid_values );
|
240 |
+
if ( strlen( $posts ) > 0 ) {
|
241 |
$query_restrictions .= " AND relevanssi.doc IN (SELECT ID FROM $wpdb->posts WHERE post_parent IN ($posts))";
|
242 |
// Clean: $posts is checked to be integers.
|
243 |
}
|
244 |
}
|
245 |
+
if ( isset( $parent_query['parent not in'] ) ) {
|
246 |
$valid_values = array();
|
247 |
foreach ( $parent_query['parent not in'] as $post_not_in_id ) {
|
248 |
+
if ( is_int( $post_not_in_id ) ) {
|
249 |
$valid_values[] = $post_not_in_id;
|
250 |
}
|
251 |
}
|
252 |
$posts = implode( ',', $valid_values );
|
253 |
+
if ( isset( $posts ) ) {
|
254 |
$query_restrictions .= " AND relevanssi.doc NOT IN (SELECT ID FROM $wpdb->posts WHERE post_parent IN ($posts))";
|
255 |
// Clean: $posts is checked to be integers.
|
256 |
}
|
286 |
// If $post_type is not set, see if there are post types to exclude from the search.
|
287 |
// If $post_type is set, there's no need to exclude, as we only include.
|
288 |
$negative_post_type = null;
|
289 |
+
if ( ! $post_type && ! $admin_search ) {
|
290 |
+
$negative_post_type = relevanssi_get_negative_post_type( $include_attachments );
|
291 |
}
|
292 |
|
293 |
$non_post_post_type = null;
|
609 |
|
610 |
$tag = $relevanssi_variables['post_type_weight_defaults']['post_tag'];
|
611 |
$cat = $relevanssi_variables['post_type_weight_defaults']['category'];
|
612 |
+
|
613 |
+
if ( ! empty( $post_type_weights['post_tagged_with_post_tag'] ) ) {
|
614 |
+
$tag = $post_type_weights['post_tagged_with_post_tag'];
|
615 |
+
}
|
616 |
+
if ( ! empty( $post_type_weights['post_tagged_with_category'] ) ) {
|
617 |
+
$cat = $post_type_weights['post_tagged_with_category'];
|
618 |
+
}
|
619 |
+
|
620 |
+
/* Legacy code, improvement introduced in 2.1.8, remove at some point. */
|
621 |
if ( ! empty( $post_type_weights['post_tag'] ) ) {
|
622 |
$tag = $post_type_weights['post_tag'];
|
623 |
}
|
624 |
if ( ! empty( $post_type_weights['category'] ) ) {
|
625 |
$cat = $post_type_weights['category'];
|
626 |
}
|
627 |
+
/* End legacy code. */
|
628 |
+
|
629 |
$include_these_posts = array();
|
630 |
+
$include_these_items = array();
|
631 |
$df_counts = array();
|
632 |
|
633 |
do {
|
709 |
relevanssi.taxonomy + relevanssi.customfield + relevanssi.mysqlcolumn AS tf
|
710 |
FROM $relevanssi_table AS relevanssi WHERE relevanssi.doc IN ($post_ids_to_add)
|
711 |
AND relevanssi.doc NOT IN ($existing_ids) AND $term_cond";
|
712 |
+
|
713 |
+
// Clean: no unescaped user inputs.
|
714 |
+
$matches_to_add = $wpdb->get_results( $query ); // WPCS: unprepared SQL ok.
|
715 |
+
$matches = array_merge( $matches, $matches_to_add );
|
716 |
+
}
|
717 |
+
if ( count( $include_these_items ) > 0 ) {
|
718 |
+
$items_to_add = implode( ',', array_keys( $include_these_items ) );
|
719 |
+
$existing_items = array();
|
720 |
+
foreach ( $matches as $match ) {
|
721 |
+
if ( 0 !== intval( $match->item ) ) {
|
722 |
+
$existing_items[] = $match->item;
|
723 |
+
}
|
724 |
+
}
|
725 |
+
$existing_items = implode( ',', $existing_items );
|
726 |
+
if ( ! empty( $existing_items ) ) {
|
727 |
+
$existing_items = "AND relevanssi.item NOT IN ($existing_items) ";
|
728 |
+
}
|
729 |
+
$query = "SELECT relevanssi.*, relevanssi.title * $title_boost +
|
730 |
+
relevanssi.content * $content_boost + relevanssi.comment * $comment_boost +
|
731 |
+
relevanssi.tag * $tag + relevanssi.link * $link_boost +
|
732 |
+
relevanssi.author + relevanssi.category * $cat + relevanssi.excerpt +
|
733 |
+
relevanssi.taxonomy + relevanssi.customfield + relevanssi.mysqlcolumn AS tf
|
734 |
+
FROM $relevanssi_table AS relevanssi WHERE relevanssi.item IN ($items_to_add)
|
735 |
+
$existing_items AND $term_cond";
|
736 |
+
|
737 |
// Clean: no unescaped user inputs.
|
738 |
$matches_to_add = $wpdb->get_results( $query ); // WPCS: unprepared SQL ok.
|
739 |
$matches = array_merge( $matches, $matches_to_add );
|
753 |
foreach ( $matches as $match ) {
|
754 |
if ( 'user' === $match->type ) {
|
755 |
$match->doc = 'u_' . $match->item;
|
756 |
+
} elseif ( 'post_type' === $match->type ) {
|
757 |
+
$match->doc = 'p_' . $match->item;
|
758 |
} elseif ( ! in_array( $match->type, array( 'post', 'attachment' ), true ) ) {
|
759 |
$match->doc = '**' . $match->type . '**' . $match->item;
|
760 |
}
|
763 |
relevanssi_taxonomy_score( $match, $post_type_weights );
|
764 |
} else {
|
765 |
$tag_weight = 1;
|
766 |
+
if ( isset( $post_type_weights['post_tagged_with_post_tag'] ) && is_numeric( $post_type_weights['post_tagged_with_post_tag'] ) ) {
|
767 |
+
$tag_weight = $post_type_weights['post_tagged_with_post_tag'];
|
768 |
+
}
|
769 |
+
|
770 |
+
$category_weight = 1;
|
771 |
+
if ( isset( $post_type_weights['post_tagged_with_category'] ) && is_numeric( $post_type_weights['post_tagged_with_category'] ) ) {
|
772 |
+
$category_weight = $post_type_weights['post_tagged_with_category'];
|
773 |
+
}
|
774 |
+
|
775 |
+
/* Legacy code from 2.1.8. Remove at some point. */
|
776 |
if ( isset( $post_type_weights['post_tag'] ) && is_numeric( $post_type_weights['post_tag'] ) ) {
|
777 |
$tag_weight = $post_type_weights['post_tag'];
|
778 |
}
|
781 |
if ( isset( $post_type_weights['category'] ) && is_numeric( $post_type_weights['category'] ) ) {
|
782 |
$category_weight = $post_type_weights['category'];
|
783 |
}
|
784 |
+
/* End legacy code. */
|
785 |
|
786 |
$taxonomy_weight = 1;
|
787 |
|
864 |
$taxonomy_matches[ $match->doc ] += $match->taxonomy;
|
865 |
$comment_matches[ $match->doc ] += $match->comment;
|
866 |
|
867 |
+
/* Post type weights. */
|
868 |
$type = null;
|
869 |
if ( isset( $relevanssi_post_types[ $match->doc ] ) ) {
|
870 |
$type = $relevanssi_post_types[ $match->doc ];
|
873 |
$match->weight = $match->weight * $post_type_weights[ $type ];
|
874 |
}
|
875 |
|
876 |
+
/* Weight boost for taxonomy terms based on taxonomy. */
|
877 |
+
if ( ! empty( $post_type_weights[ 'taxonomy_term_' . $match->type ] ) ) {
|
878 |
+
$match->weight = $match->weight * $post_type_weights[ 'taxonomy_term_' . $match->type ];
|
879 |
+
}
|
880 |
+
|
881 |
/**
|
882 |
* Filters the hit.
|
883 |
*
|
921 |
if ( is_numeric( $match->doc ) ) {
|
922 |
// This is to weed out taxonomies and users (t_XXX, u_XXX).
|
923 |
$include_these_posts[ $match->doc ] = true;
|
924 |
+
} elseif ( 0 !== intval( $match->item ) ) {
|
925 |
+
$include_these_items[ $match->item ] = true;
|
926 |
}
|
927 |
}
|
928 |
}
|
1269 |
}
|
1270 |
|
1271 |
$multi_args['meta_query'] = $meta_query;
|
1272 |
+
|
1273 |
+
if ( isset( $query->query_vars['include_attachments'] ) ) {
|
1274 |
+
$multi_args['include_attachments'] = $query->query_vars['include_attachments'];
|
1275 |
+
}
|
1276 |
+
|
1277 |
if ( function_exists( 'relevanssi_search_multi' ) ) {
|
1278 |
$return = relevanssi_search_multi( $multi_args );
|
1279 |
}
|
1427 |
'operator' => 'AND',
|
1428 |
);
|
1429 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1430 |
if ( ! empty( $query->query_vars['tag_slug__in'] ) ) {
|
1431 |
$tax_query[] = array(
|
1432 |
'taxonomy' => 'post_tag',
|
1475 |
);
|
1476 |
}
|
1477 |
}
|
1478 |
+
$query->tax_query = $tax_query;
|
1479 |
}
|
1480 |
|
1481 |
$author = false;
|
1488 |
}
|
1489 |
|
1490 |
$post_query = array();
|
1491 |
+
if ( isset( $query->query_vars['p'] ) ) {
|
1492 |
$post_query = array( 'in' => array( $query->query_vars['p'] ) );
|
1493 |
}
|
1494 |
+
if ( isset( $query->query_vars['page_id'] ) ) {
|
1495 |
$post_query = array( 'in' => array( $query->query_vars['page_id'] ) );
|
1496 |
}
|
1497 |
+
if ( isset( $query->query_vars['post__in'] ) ) {
|
1498 |
$post_query = array( 'in' => $query->query_vars['post__in'] );
|
1499 |
}
|
1500 |
+
if ( isset( $query->query_vars['post__not_in'] ) ) {
|
1501 |
$post_query = array( 'not in' => $query->query_vars['post__not_in'] );
|
1502 |
}
|
1503 |
|
1504 |
$parent_query = array();
|
1505 |
+
if ( isset( $query->query_vars['post_parent'] ) ) {
|
1506 |
$parent_query = array( 'parent in' => array( $query->query_vars['post_parent'] ) );
|
1507 |
}
|
1508 |
+
if ( is_array( $query->query_vars['post_parent__in'] ) && ! empty( $query->query_vars['post_parent__in'] ) ) {
|
1509 |
$parent_query = array( 'parent in' => $query->query_vars['post_parent__in'] );
|
1510 |
}
|
1511 |
+
if ( is_array( $query->query_vars['post_parent__not_in'] ) && ! empty( $query->query_vars['post_parent__not_in'] ) ) {
|
1512 |
$parent_query = array( 'parent not in' => $query->query_vars['post_parent__not_in'] );
|
1513 |
}
|
1514 |
|
1649 |
$by_date = $query->query_vars['by_date'];
|
1650 |
}
|
1651 |
}
|
1652 |
+
|
1653 |
+
$admin_search = false;
|
1654 |
+
if ( isset( $query->query_vars['relevanssi_admin_search'] ) ) {
|
1655 |
+
$admin_search = true;
|
1656 |
+
}
|
1657 |
+
|
1658 |
+
$include_attachments = '';
|
1659 |
+
if ( isset( $query->query_vars['include_attachments'] ) ) {
|
1660 |
+
$include_attachments = $query->query_vars['include_attachments'];
|
1661 |
+
}
|
1662 |
+
|
1663 |
// Add synonyms.
|
1664 |
// This is done here so the new terms will get highlighting.
|
1665 |
if ( 'OR' === $operator ) {
|
1668 |
}
|
1669 |
|
1670 |
$search_params = array(
|
1671 |
+
'q' => $q,
|
1672 |
+
'tax_query' => $tax_query,
|
1673 |
+
'tax_query_relation' => $tax_query_relation,
|
1674 |
+
'post_query' => $post_query,
|
1675 |
+
'parent_query' => $parent_query,
|
1676 |
+
'meta_query' => $meta_query,
|
1677 |
+
'date_query' => $date_query,
|
1678 |
+
'expost' => $expost,
|
1679 |
+
'post_type' => $post_type,
|
1680 |
+
'post_status' => $post_status,
|
1681 |
+
'operator' => $operator,
|
1682 |
+
'search_blogs' => $search_blogs,
|
1683 |
+
'author' => $author,
|
1684 |
+
'orderby' => $orderby,
|
1685 |
+
'order' => $order,
|
1686 |
+
'fields' => $fields,
|
1687 |
+
'sentence' => $sentence,
|
1688 |
+
'by_date' => $by_date,
|
1689 |
+
'admin_search' => $admin_search,
|
1690 |
+
'include_attachments' => $include_attachments,
|
1691 |
);
|
1692 |
|
1693 |
$return = relevanssi_search( $search_params );
|
1790 |
}
|
1791 |
|
1792 |
if ( 'on' === $make_excerpts && empty( $fields ) ) {
|
1793 |
+
if ( isset( $post->blog_id ) ) {
|
1794 |
+
switch_to_blog( $post->blog_id );
|
1795 |
+
}
|
1796 |
$post->original_excerpt = $post->post_excerpt;
|
1797 |
$post->post_excerpt = relevanssi_do_excerpt( $post, $q );
|
1798 |
+
if ( isset( $post->blog_id ) ) {
|
1799 |
+
restore_current_blog();
|
1800 |
+
}
|
1801 |
}
|
1802 |
if ( 'on' === get_option( 'relevanssi_show_matches' ) && empty( $fields ) ) {
|
1803 |
$post_id = $post->ID;
|
1804 |
if ( 'user' === $post->post_type ) {
|
1805 |
$post_id = 'u_' . $post->user_id;
|
1806 |
+
} elseif ( 'post_type' === $post->post_type ) {
|
1807 |
+
$post_id = 'p_' . $post->ID;
|
1808 |
} elseif ( isset( $post->term_id ) ) {
|
1809 |
$post_id = '**' . $post->post_type . '**' . $post->term_id;
|
1810 |
}
|
1811 |
+
if ( isset( $post->blog_id ) ) {
|
1812 |
+
$post_id = $post->blog_id . '|' . $post->ID;
|
1813 |
+
}
|
1814 |
$post->post_excerpt .= relevanssi_show_matches( $return, $post_id );
|
1815 |
}
|
1816 |
|
1817 |
+
if ( empty( $fields ) ) {
|
1818 |
+
$post_id = $post->ID;
|
1819 |
+
if ( isset( $post->blog_id ) ) {
|
1820 |
+
$post_id = $post->blog_id . '|' . $post->ID;
|
1821 |
+
}
|
1822 |
+
if ( isset( $return['scores'][ $post_id ] ) ) {
|
1823 |
+
$post->relevance_score = round( $return['scores'][ $post_id ], 2 );
|
1824 |
+
}
|
1825 |
}
|
1826 |
|
1827 |
$posts[] = $post;
|
1860 |
*
|
1861 |
* Figures out the post types that are not included in the search.
|
1862 |
*
|
1863 |
+
* @param string $include_attachments Whether to include attachments or not.
|
1864 |
*
|
1865 |
* @return string SQL escaped list of excluded post types.
|
1866 |
*/
|
1867 |
+
function relevanssi_get_negative_post_type( $include_attachments ) {
|
|
|
|
|
1868 |
$negative_post_type = null;
|
1869 |
$negative_post_type_list = array();
|
1870 |
|
1871 |
+
if ( isset( $include_attachments ) && in_array( $include_attachments, array( '0', 'off', 'false' ), true ) ) {
|
1872 |
$negative_post_type_list[] = 'attachment';
|
1873 |
}
|
1874 |
|
1875 |
+
$front_end = true;
|
1876 |
+
if ( is_admin() && ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) ) {
|
1877 |
+
$front_end = false;
|
1878 |
+
}
|
1879 |
+
if ( 'on' === get_option( 'relevanssi_respect_exclude' ) && $front_end ) {
|
1880 |
// If Relevanssi is set to respect exclude_from_search, find out which
|
1881 |
// post types should be excluded from search.
|
1882 |
$pt_1 = get_post_types( array( 'exclude_from_search' => '1' ) );
|
2243 |
$match->taxonomy_detail = json_decode( $match->taxonomy_detail );
|
2244 |
if ( is_object( $match->taxonomy_detail ) ) {
|
2245 |
foreach ( $match->taxonomy_detail as $tax => $count ) {
|
2246 |
+
if ( empty( $post_type_weights[ 'post_tagged_with_' . $tax ] ) ) {
|
2247 |
+
if ( ! empty( $post_type_weights[ $tax ] ) ) { // Legacy code, needed for 2.1.8, remove later.
|
2248 |
+
$match->taxonomy_score += $count * $post_type_weights[ $tax ];
|
2249 |
+
} else {
|
2250 |
+
$match->taxonomy_score += $count * 1;
|
2251 |
+
}
|
2252 |
} else {
|
2253 |
+
$match->taxonomy_score += $count * $post_type_weights[ 'post_tagged_with_' . $tax ];
|
2254 |
}
|
2255 |
}
|
2256 |
}
|
lib/sorting.php
CHANGED
@@ -70,7 +70,7 @@ function relevanssi_get_next_key( &$orderby ) {
|
|
70 |
break;
|
71 |
}
|
72 |
|
73 |
-
$numeric_keys = array( 'menu_order', 'ID', 'post_parent', 'post_author', 'comment_count', 'relevance_score' );
|
74 |
$date_keys = array( 'post_date', 'post_date_gmt', 'post_modified', 'post_modified_gmt' );
|
75 |
|
76 |
$compare = 'string';
|
@@ -301,10 +301,6 @@ function relevanssi_object_sort( &$data, $orderby ) {
|
|
301 |
} while ( ! empty( $values['key'] ) );
|
302 |
|
303 |
$primary_key = $relevanssi_keys[0];
|
304 |
-
if ( 'rand' !== $primary_key && ! isset( $data[0]->$primary_key ) ) {
|
305 |
-
// Trying to sort by a non-existent key.
|
306 |
-
return;
|
307 |
-
}
|
308 |
|
309 |
usort( $data, 'relevanssi_cmp_function' );
|
310 |
}
|
70 |
break;
|
71 |
}
|
72 |
|
73 |
+
$numeric_keys = array( 'meta_value_num', 'menu_order', 'ID', 'post_parent', 'post_author', 'comment_count', 'relevance_score' );
|
74 |
$date_keys = array( 'post_date', 'post_date_gmt', 'post_modified', 'post_modified_gmt' );
|
75 |
|
76 |
$compare = 'string';
|
301 |
} while ( ! empty( $values['key'] ) );
|
302 |
|
303 |
$primary_key = $relevanssi_keys[0];
|
|
|
|
|
|
|
|
|
304 |
|
305 |
usort( $data, 'relevanssi_cmp_function' );
|
306 |
}
|
lib/tabs/excerpts-tab.php
CHANGED
@@ -97,6 +97,14 @@ function relevanssi_excerpts_tab() {
|
|
97 |
</label>
|
98 |
</fieldset>
|
99 |
<p class="description"><?php esc_html_e( 'Only enable this if you actually use the custom excerpts.', 'relevanssi' ); ?></p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
</td>
|
101 |
</tr>
|
102 |
<tr id="tr_excerpt_length"
|
97 |
</label>
|
98 |
</fieldset>
|
99 |
<p class="description"><?php esc_html_e( 'Only enable this if you actually use the custom excerpts.', 'relevanssi' ); ?></p>
|
100 |
+
<?php
|
101 |
+
$theme = wp_get_theme();
|
102 |
+
$template = $theme->get( 'Template' );
|
103 |
+
if ( 'divi' === strtolower( $template ) ) :
|
104 |
+
?>
|
105 |
+
<?php // Translators: %1$s opens the link, %2$s closes it. ?>
|
106 |
+
<p class="important"><?php printf( esc_html__( 'Looks like you are using Divi. In order to use custom excerpts with Divi, you need to make some changes to your templates. %1$sSee instructions here%2$s.', 'relevanssi' ), '<a href="https://www.relevanssi.com/knowledge-base/divi-page-builder-and-cleaner-excerpts/">', '</a>' ); ?></p>
|
107 |
+
<?php endif; ?>
|
108 |
</td>
|
109 |
</tr>
|
110 |
<tr id="tr_excerpt_length"
|
lib/tabs/indexing-tab.php
CHANGED
@@ -143,7 +143,11 @@ function relevanssi_indexing_tab() {
|
|
143 |
|
144 |
<?php
|
145 |
if ( count( $index_post_types ) < 2 ) {
|
146 |
-
|
|
|
|
|
|
|
|
|
147 |
}
|
148 |
?>
|
149 |
|
@@ -280,6 +284,13 @@ function relevanssi_indexing_tab() {
|
|
280 |
esc_html_e( "'Some' lets you choose individual custom fields to index.", 'relevanssi' );
|
281 |
?>
|
282 |
</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
283 |
<div id="index_field_input"
|
284 |
<?php
|
285 |
if ( empty( $fields_select_some ) ) {
|
@@ -376,6 +387,9 @@ function relevanssi_indexing_tab() {
|
|
376 |
if ( function_exists( 'relevanssi_form_index_taxonomies' ) ) {
|
377 |
relevanssi_form_index_taxonomies();
|
378 |
}
|
|
|
|
|
|
|
379 |
if ( function_exists( 'relevanssi_form_index_pdf_parent' ) ) {
|
380 |
relevanssi_form_index_pdf_parent();
|
381 |
}
|
143 |
|
144 |
<?php
|
145 |
if ( count( $index_post_types ) < 2 ) {
|
146 |
+
$index_users = get_option( 'relevanssi_index_users', 'off' );
|
147 |
+
$index_taxonomies = get_option( 'relevanssi_index_taxonomies', 'off' );
|
148 |
+
if ( 'off' === $index_users && 'off' === $index_taxonomies ) {
|
149 |
+
printf( '<p><strong>%s</strong></p>', esc_html__( "WARNING: You've chosen no post types to index. Nothing will be indexed. Choose some post types to index.", 'relevanssi' ) );
|
150 |
+
}
|
151 |
}
|
152 |
?>
|
153 |
|
284 |
esc_html_e( "'Some' lets you choose individual custom fields to index.", 'relevanssi' );
|
285 |
?>
|
286 |
</p>
|
287 |
+
<?php
|
288 |
+
if ( class_exists( 'acf' ) && $fields_select_all ) {
|
289 |
+
echo "<p class='description important'>";
|
290 |
+
esc_html_e( 'Advanced Custom Fields has lots of invisible custom fields with meta data. Selecting "all" will include lots of garbage in the index and excerpts. "Visible" is usually a better option with ACF.' );
|
291 |
+
echo '</p>';
|
292 |
+
}
|
293 |
+
?>
|
294 |
<div id="index_field_input"
|
295 |
<?php
|
296 |
if ( empty( $fields_select_some ) ) {
|
387 |
if ( function_exists( 'relevanssi_form_index_taxonomies' ) ) {
|
388 |
relevanssi_form_index_taxonomies();
|
389 |
}
|
390 |
+
if ( function_exists( 'relevanssi_form_index_post_type_archives' ) ) {
|
391 |
+
relevanssi_form_index_post_type_archives();
|
392 |
+
}
|
393 |
if ( function_exists( 'relevanssi_form_index_pdf_parent' ) ) {
|
394 |
relevanssi_form_index_pdf_parent();
|
395 |
}
|
lib/tabs/logging-tab.php
CHANGED
@@ -90,6 +90,16 @@ function relevanssi_logging_tab() {
|
|
90 |
</td>
|
91 |
</tr>
|
92 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
</table>
|
94 |
<?php
|
95 |
}
|
90 |
</td>
|
91 |
</tr>
|
92 |
|
93 |
+
<tr>
|
94 |
+
<th scope="row">
|
95 |
+
<label for='relevanssi_export_logs'><?php esc_html_e( 'Export logs', 'relevanssi' ); ?></label>
|
96 |
+
</th>
|
97 |
+
<td>
|
98 |
+
<?php submit_button( __( 'Export the log as a CSV file', 'relevanssi' ), 'secondary', 'relevanssi_export' ); ?>
|
99 |
+
<p class="description"><?php esc_html_e( 'Push the button to export the search log as a CSV file.', 'relevanssi' ); ?></p>
|
100 |
+
</td>
|
101 |
+
</tr>
|
102 |
+
|
103 |
</table>
|
104 |
<?php
|
105 |
}
|
lib/tabs/overview-tab.php
CHANGED
@@ -30,6 +30,9 @@ function relevanssi_overview_tab() {
|
|
30 |
if ( function_exists( 'relevanssi_form_hide_post_controls' ) ) {
|
31 |
relevanssi_form_hide_post_controls();
|
32 |
}
|
|
|
|
|
|
|
33 |
?>
|
34 |
<tr>
|
35 |
<th scope="row"><?php esc_html_e( 'Getting started', 'relevanssi' ); ?></th>
|
30 |
if ( function_exists( 'relevanssi_form_hide_post_controls' ) ) {
|
31 |
relevanssi_form_hide_post_controls();
|
32 |
}
|
33 |
+
if ( function_exists( 'relevanssi_form_do_not_call_home' ) ) {
|
34 |
+
relevanssi_form_do_not_call_home();
|
35 |
+
}
|
36 |
?>
|
37 |
<tr>
|
38 |
<th scope="row"><?php esc_html_e( 'Getting started', 'relevanssi' ); ?></th>
|
lib/tabs/search-page.php
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* /premium/tabs/search-tab.php
|
4 |
+
*
|
5 |
+
* Prints out the Premium search tab in Relevanssi settings.
|
6 |
+
*
|
7 |
+
* @package Relevanssi_Premium
|
8 |
+
* @author Mikko Saari
|
9 |
+
* @license https://wordpress.org/about/gpl/ GNU General Public License
|
10 |
+
* @see https://www.relevanssi.com/
|
11 |
+
*/
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Prints out the Premium search tab in Relevanssi settings.
|
15 |
+
*/
|
16 |
+
function relevanssi_search_tab() {
|
17 |
+
?>
|
18 |
+
<p><?php esc_html_e( 'You can use this search to perform Relevanssi searches without any restrictions from WordPress. You can search all post types here.', 'relevanssi' ); ?></p>
|
19 |
+
|
20 |
+
<table class="form-table">
|
21 |
+
<tr>
|
22 |
+
<th scope="row">
|
23 |
+
<label for='s'><?php esc_html_e( 'Search terms', 'relevanssi' ); ?></label>
|
24 |
+
</th>
|
25 |
+
<td>
|
26 |
+
<input type='text' name='s' id='s' size='60' />
|
27 |
+
</td>
|
28 |
+
</tr>
|
29 |
+
<tr>
|
30 |
+
<th scope="row">
|
31 |
+
<label for='posts_per_page'><?php esc_html_e( 'Posts per page', 'relevanssi' ); ?></label>
|
32 |
+
</th>
|
33 |
+
<td>
|
34 |
+
<select name='posts_per_page' id='posts_per_page'>
|
35 |
+
<option value='0'><?php esc_html_e( 'All', 'relevanssi' ); ?></option>
|
36 |
+
<option>10</option>
|
37 |
+
<option>50</option>
|
38 |
+
<option>100</option>
|
39 |
+
</select>
|
40 |
+
</td>
|
41 |
+
</tr>
|
42 |
+
<tr>
|
43 |
+
<th scope="row">
|
44 |
+
<label for='args'><?php esc_html_e( 'Search parameters', 'relevanssi' ); ?></label>
|
45 |
+
</th>
|
46 |
+
<td>
|
47 |
+
<input type='text' name='args' id='args' size='60' />
|
48 |
+
<?php // Translators: example query string. ?>
|
49 |
+
<p class='description'><?php printf( esc_html__( 'Use query parameter formatting here, the same that would appear on search page results URL. For example %s.', 'relevanssi' ), '<code>posts_per_page=10&post_types=page&from=2018-01-01</code>' ); ?></p>
|
50 |
+
</td>
|
51 |
+
</tr>
|
52 |
+
<tr>
|
53 |
+
<th scope="row">
|
54 |
+
</th>
|
55 |
+
<td>
|
56 |
+
<input type='submit' name='search' id='search' value='<?php echo esc_html_x( 'Search', 'button action', 'relevanssi' ); ?>' class='button' />
|
57 |
+
</td>
|
58 |
+
</tr>
|
59 |
+
</table>
|
60 |
+
|
61 |
+
<div id='results'></div>
|
62 |
+
<?php
|
63 |
+
}
|
lib/tabs/searching-tab.php
CHANGED
@@ -332,7 +332,7 @@ function relevanssi_searching_tab() {
|
|
332 |
<td>
|
333 |
<div class="categorydiv" style="max-width: 400px">
|
334 |
<div class="tabs-panel">
|
335 |
-
<ul id="
|
336 |
<?php
|
337 |
$selected_cats = explode( ',', $cat );
|
338 |
$walker = get_relevanssi_taxonomy_walker();
|
@@ -357,7 +357,7 @@ function relevanssi_searching_tab() {
|
|
357 |
<td>
|
358 |
<div class="categorydiv" style="max-width: 400px">
|
359 |
<div class="tabs-panel">
|
360 |
-
<ul id="
|
361 |
<?php
|
362 |
$selected_cats = explode( ',', $excat );
|
363 |
$walker = get_relevanssi_taxonomy_walker();
|
332 |
<td>
|
333 |
<div class="categorydiv" style="max-width: 400px">
|
334 |
<div class="tabs-panel">
|
335 |
+
<ul id="category_inclusion_checklist">
|
336 |
<?php
|
337 |
$selected_cats = explode( ',', $cat );
|
338 |
$walker = get_relevanssi_taxonomy_walker();
|
357 |
<td>
|
358 |
<div class="categorydiv" style="max-width: 400px">
|
359 |
<div class="tabs-panel">
|
360 |
+
<ul id="category_exclusion_checklist">
|
361 |
<?php
|
362 |
$selected_cats = explode( ',', $excat );
|
363 |
$walker = get_relevanssi_taxonomy_walker();
|
readme.txt
CHANGED
@@ -5,7 +5,7 @@ Tags: search, relevance, better search
|
|
5 |
Requires at least: 4.0
|
6 |
Tested up to: 5.0
|
7 |
Requires PHP: 5.6
|
8 |
-
Stable tag: 4.
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
@@ -130,6 +130,21 @@ Each document database is full of useless words. All the little words that appea
|
|
130 |
|
131 |
== Changelog ==
|
132 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
= 4.0.11 =
|
134 |
* Home page links were getting the highlight parameter even though they shouldn't. This has been fixed.
|
135 |
* Added support for WP JV Post Reading Groups.
|
@@ -155,38 +170,11 @@ Each document database is full of useless words. All the little words that appea
|
|
155 |
* Random order works again; using orderby `rand` didn't work properly. The `rand(seed)` format is also supported now.
|
156 |
* Fixed quotes and apostrophes in Did you mean suggestions.
|
157 |
|
158 |
-
= 4.0.9 =
|
159 |
-
* Fixes broken tag and category indexing and searching. If you use tags and categories, rebuild the index after updating.
|
160 |
-
* Phrases were not highlighted correctly on documents. This is now fixed.
|
161 |
-
* Shortcode fix: 'wp_show_posts' shouldn't cause problems anymore.
|
162 |
-
* New filter: `relevanssi_indexing_restriction` allows filtering posts before indexing.
|
163 |
-
* New WooCommerce product visibility filtering tool makes WooCommerce product indexing faster.
|
164 |
-
* MemberPress post controls were loose and showed drafts to searchers. That is now fixed.
|
165 |
-
* Highlighting was too loose, even if matching was set to whole words.
|
166 |
-
* Highlighting now works better in cases where there's a hyphen or an apostrophe inside a word.
|
167 |
-
|
168 |
-
= 4.0.8 =
|
169 |
-
* Fixed cases where Relevanssi added an ellipsis even if the excerpt was from the start of the post.
|
170 |
-
* Highlighting now works with numeric search strings.
|
171 |
-
* Improved highlighting for accented words. Thanks to Paul Ryan.
|
172 |
-
* A surplus comma at the end of post exclusion setting won't break the search anymore.
|
173 |
-
* Fixed instructions for adjusting the throttle limit.
|
174 |
-
|
175 |
-
= 4.0.7 =
|
176 |
-
* Recent post bonus is now applied to searches.
|
177 |
-
* Exact term setting can now be disabled.
|
178 |
-
* Users of Members plugin would have drafts appear in search results. This is now fixed.
|
179 |
-
|
180 |
-
= 4.0.6 =
|
181 |
-
* Indexing bugs squashed.
|
182 |
-
* Missing tag and category weight settings returned.
|
183 |
-
* Fusion builder shortcodes are removed from excerpts.
|
184 |
-
* MemberPress post control was backwards.
|
185 |
-
* User searches page reset buttons fixed.
|
186 |
-
* WPML language filter fix.
|
187 |
-
|
188 |
== Upgrade notice ==
|
189 |
|
|
|
|
|
|
|
190 |
= 4.0.11 =
|
191 |
* Several small improvements, new filters and highlighting fixes.
|
192 |
|
@@ -194,16 +182,4 @@ Each document database is full of useless words. All the little words that appea
|
|
194 |
* Privacy feature bug fix.
|
195 |
|
196 |
= 4.0.10 =
|
197 |
-
* Privacy update, with some bug fixes.
|
198 |
-
|
199 |
-
= 4.0.9 =
|
200 |
-
* Fixes broken tag and category searching and indexing. Reindex after the update!
|
201 |
-
|
202 |
-
= 4.0.8 =
|
203 |
-
* Improvements to highlighting and excerpts.
|
204 |
-
|
205 |
-
= 4.0.7 =
|
206 |
-
* Small bug fixes.
|
207 |
-
|
208 |
-
= 4.0.6 =
|
209 |
-
* Indexing bugs fixed and WPML support corrected.
|
5 |
Requires at least: 4.0
|
6 |
Tested up to: 5.0
|
7 |
Requires PHP: 5.6
|
8 |
+
Stable tag: 4.1
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
130 |
|
131 |
== Changelog ==
|
132 |
|
133 |
+
= 4.1 =
|
134 |
+
* New feature: You can now export the search log as a CSV file.
|
135 |
+
* New feature: Admin Search page allows you to perform searches in WP admin using Relevanssi.
|
136 |
+
* New filter: `relevanssi_admin_search_capability` can be used to adjust who sees the admin search page.
|
137 |
+
* New filter: `relevanssi_entities_inside_pre` and `relevanssi_entities_inside_code` adjust how HTML entities are handled inside `pre` and `code` tags.
|
138 |
+
* Numeric meta values (`meta_value_num`) are now sorted as numbers and not strings.
|
139 |
+
* Pinned posts have `$post->relevanssi_pinned` set to 1 for debugging purposes, but you can also use this for styling the posts in the search results templates.
|
140 |
+
* The Did you mean feature has been toned down a bit, to make the suggestions slightly less weird in some cases.
|
141 |
+
* Post parent parameters now accept 0 as a value, making it easier to search for children of any post or posts without a parent.
|
142 |
+
* Polylang compatibility has been improved.
|
143 |
+
* Phrases with apostrophes inside work better.
|
144 |
+
* The `relevanssi_excerpt` filter hook got a second parameter that holds the post ID.
|
145 |
+
* Custom field sorting actually works now.
|
146 |
+
* WP Search Suggest compatibility added.
|
147 |
+
|
148 |
= 4.0.11 =
|
149 |
* Home page links were getting the highlight parameter even though they shouldn't. This has been fixed.
|
150 |
* Added support for WP JV Post Reading Groups.
|
170 |
* Random order works again; using orderby `rand` didn't work properly. The `rand(seed)` format is also supported now.
|
171 |
* Fixed quotes and apostrophes in Did you mean suggestions.
|
172 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
173 |
== Upgrade notice ==
|
174 |
|
175 |
+
= 4.1 =
|
176 |
+
* New features and plenty of small fixes.
|
177 |
+
|
178 |
= 4.0.11 =
|
179 |
* Several small improvements, new filters and highlighting fixes.
|
180 |
|
182 |
* Privacy feature bug fix.
|
183 |
|
184 |
= 4.0.10 =
|
185 |
+
* Privacy update, with some bug fixes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
relevanssi.php
CHANGED
@@ -13,7 +13,7 @@
|
|
13 |
* Plugin Name: Relevanssi
|
14 |
* Plugin URI: https://www.relevanssi.com/
|
15 |
* Description: This plugin replaces WordPress search with a relevance-sorting search.
|
16 |
-
* Version: 4.
|
17 |
* Author: Mikko Saari
|
18 |
* Author URI: http://www.mikkosaari.fi/
|
19 |
* Text Domain: relevanssi
|
@@ -39,6 +39,8 @@
|
|
39 |
|
40 |
define( 'RELEVANSSI_PREMIUM', false );
|
41 |
|
|
|
|
|
42 |
global $relevanssi_variables;
|
43 |
global $wpdb;
|
44 |
|
@@ -56,16 +58,15 @@ $relevanssi_variables['database_version'] = 5;
|
|
56 |
$relevanssi_variables['file'] = __FILE__;
|
57 |
$relevanssi_variables['plugin_dir'] = plugin_dir_path( __FILE__ );
|
58 |
|
59 |
-
require_once 'lib/common.php';
|
60 |
-
require_once 'lib/excerpts-highlights.php';
|
61 |
-
require_once 'lib/indexing.php';
|
62 |
-
require_once 'lib/init.php';
|
63 |
require_once 'lib/install.php';
|
|
|
64 |
require_once 'lib/interface.php';
|
|
|
65 |
require_once 'lib/log.php';
|
66 |
-
require_once 'lib/
|
|
|
67 |
require_once 'lib/search.php';
|
|
|
68 |
require_once 'lib/shortcodes.php';
|
69 |
-
require_once 'lib/
|
70 |
-
require_once 'lib/
|
71 |
-
require_once 'lib/uninstall.php';
|
13 |
* Plugin Name: Relevanssi
|
14 |
* Plugin URI: https://www.relevanssi.com/
|
15 |
* Description: This plugin replaces WordPress search with a relevance-sorting search.
|
16 |
+
* Version: 4.1
|
17 |
* Author: Mikko Saari
|
18 |
* Author URI: http://www.mikkosaari.fi/
|
19 |
* Text Domain: relevanssi
|
39 |
|
40 |
define( 'RELEVANSSI_PREMIUM', false );
|
41 |
|
42 |
+
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'relevanssi_action_links' );
|
43 |
+
|
44 |
global $relevanssi_variables;
|
45 |
global $wpdb;
|
46 |
|
58 |
$relevanssi_variables['file'] = __FILE__;
|
59 |
$relevanssi_variables['plugin_dir'] = plugin_dir_path( __FILE__ );
|
60 |
|
|
|
|
|
|
|
|
|
61 |
require_once 'lib/install.php';
|
62 |
+
require_once 'lib/init.php';
|
63 |
require_once 'lib/interface.php';
|
64 |
+
require_once 'lib/indexing.php';
|
65 |
require_once 'lib/log.php';
|
66 |
+
require_once 'lib/sorting.php';
|
67 |
+
require_once 'lib/stopwords.php';
|
68 |
require_once 'lib/search.php';
|
69 |
+
require_once 'lib/excerpts-highlights.php';
|
70 |
require_once 'lib/shortcodes.php';
|
71 |
+
require_once 'lib/common.php';
|
72 |
+
require_once 'lib/admin-ajax.php';
|
|