Version Description
- New feature: You can now give Gutenberg blocks a CSS class
relevanssi_noindex
to exclude them from being indexed. Relevanssi will not index Gutenberg blocks that have the class. - New feature: Relevanssi automatically skips some custom fields from common plugins that only contain unnecessary metadata.
- New feature: The search results breakdown is added to the post objects and can be found in $post->relevanssi_hits. The data also includes new fields and the breakdown from the excerpt settings page can now show author, excerpt, custom field and MySQL column hits.
- New feature: Relevanssi can now index Ninja Tables table content. This is something of an experimental feature right now, feedback is welcome.
- New feature: New filter hook
relevanssi_indexing_query
filters the indexing query and is mostly interesting for debugging reasons. - Minor fix: Deleted and trashed comment contents were not deindexed when the comment was removed. That has been corrected now.
- Minor fix: Phrase matching is now applied to attachments as well, including the attachments indexed for parent post.
- Minor fix: Phrase matching only looks at custom fields that are indexed by Relevanssi.
- Minor fix: Exact match bonus now uses the original query without synonyms added for the exact match check.
- Minor fix: Paid Membership Pro filtering is only applied to published posts to prevent drafts from showing up in the search results.
Download this release
Release Info
Developer | msaari |
Plugin | Relevanssi – A Better Search |
Version | 4.3.4 |
Comparing to | |
See all releases |
Code changes from version 4.3.3 to 4.3.4
- lib/common.php +202 -75
- lib/compatibility/gutenberg.php +24 -4
- lib/compatibility/ninjatables.php +84 -0
- lib/compatibility/paidmembershippro.php +7 -2
- lib/compatibility/polylang.php +14 -2
- lib/indexing.php +91 -103
- lib/init.php +8 -2
- lib/search-query-restrictions.php +4 -1
- lib/search.php +96 -56
- lib/tabs/excerpts-tab.php +1 -1
- readme.txt +24 -5
- relevanssi.php +9 -2
lib/common.php
CHANGED
@@ -51,68 +51,121 @@ function relevanssi_strtolower( $string ) {
|
|
51 |
}
|
52 |
|
53 |
/**
|
54 |
-
*
|
55 |
-
*
|
56 |
-
* Gets the source data, generates numbers of it and then replaces the placeholders
|
57 |
-
* in the breakdown template with the data.
|
58 |
*
|
59 |
-
*
|
60 |
-
*
|
|
|
61 |
*
|
62 |
-
* @
|
|
|
63 |
*/
|
64 |
-
function
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
}
|
70 |
-
if ( isset( $data['title_matches'][ $
|
71 |
-
$title = $data['title_matches'][ $
|
72 |
-
} else {
|
73 |
-
$title = 0;
|
74 |
}
|
75 |
-
if ( isset( $data['tag_matches'][ $
|
76 |
-
$tag = $data['tag_matches'][ $
|
77 |
-
} else {
|
78 |
-
$tag = 0;
|
79 |
}
|
80 |
-
if ( isset( $data['category_matches'][ $
|
81 |
-
$category = $data['category_matches'][ $
|
82 |
-
} else {
|
83 |
-
$category = 0;
|
84 |
}
|
85 |
-
if ( isset( $data['taxonomy_matches'][ $
|
86 |
-
$taxonomy = $data['taxonomy_matches'][ $
|
87 |
-
} else {
|
88 |
-
$taxonomy = 0;
|
89 |
}
|
90 |
-
if ( isset( $data['comment_matches'][ $
|
91 |
-
$comment = $data['comment_matches'][ $
|
92 |
-
} else {
|
93 |
-
$comment = 0;
|
94 |
}
|
95 |
-
if ( isset( $data['
|
96 |
-
$
|
97 |
-
} else {
|
98 |
-
$score = 0;
|
99 |
}
|
100 |
-
if ( isset( $data['
|
101 |
-
$
|
102 |
-
|
103 |
-
|
104 |
-
$
|
105 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
$term_hits = '';
|
107 |
$total_hits = 0;
|
108 |
-
foreach ( $
|
109 |
$term_hits .= " $term: $hits";
|
110 |
$total_hits += $hits;
|
111 |
}
|
112 |
|
113 |
$text = stripslashes( get_option( 'relevanssi_show_matches_text' ) );
|
114 |
-
$replace_these = array(
|
115 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
116 |
$result = ' ' . str_replace( $replace_these, $replacements, $text );
|
117 |
|
118 |
/**
|
@@ -323,51 +376,91 @@ function relevanssi_recognize_phrases( $search_query, $operator = 'AND' ) {
|
|
323 |
$phrases = relevanssi_extract_phrases( $search_query );
|
324 |
$status = relevanssi_valid_status_array();
|
325 |
|
|
|
|
|
|
|
|
|
|
|
326 |
$all_queries = array();
|
327 |
-
if ( count( $phrases )
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
|
|
|
|
|
|
|
|
344 |
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
|
349 |
-
|
|
|
|
|
|
|
|
|
|
|
350 |
|
351 |
$query = "(SELECT ID FROM $wpdb->posts as p, $wpdb->term_relationships as r, $wpdb->term_taxonomy as s, $wpdb->terms as t
|
352 |
WHERE r.term_taxonomy_id = s.term_taxonomy_id AND s.term_id = t.term_id AND p.ID = r.object_id
|
|
|
353 |
AND t.name LIKE '%$phrase%' AND p.post_status IN ($status))";
|
354 |
|
355 |
$queries[] = $query;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
356 |
|
357 |
$query = "(SELECT ID
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
|
|
362 |
|
363 |
$queries[] = $query;
|
|
|
364 |
|
365 |
-
|
366 |
-
$
|
367 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
368 |
}
|
369 |
-
|
370 |
-
$
|
|
|
|
|
371 |
}
|
372 |
|
373 |
$operator = strtoupper( $operator );
|
@@ -896,7 +989,7 @@ function relevanssi_the_tags( $before = null, $separator = ', ', $after = '', $e
|
|
896 |
|
897 |
$count = count( $matches[0] );
|
898 |
for ( $i = 0; $i < $count; $i++ ) {
|
899 |
-
$highlighted_tag_name = relevanssi_highlight_terms( $tag_names[ $i ], get_search_query() );
|
900 |
$highlighted[ $i ] = str_replace( '>' . $tag_names[ $i ] . '<', '>' . $highlighted_tag_name . '<', $originals[ $i ] );
|
901 |
}
|
902 |
|
@@ -1653,9 +1746,19 @@ function relevanssi_get_forbidden_post_types() {
|
|
1653 |
'jp_pay_product', // Jetpack.
|
1654 |
'jp_mem_plan', // Jetpack.
|
1655 |
'tablepress_table', // TablePress.
|
|
|
1656 |
'shop_order', // WooCommerce.
|
1657 |
'shop_order_refund', // WooCommerce.
|
1658 |
'shop_webhook', // WooCommerce.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1659 |
);
|
1660 |
}
|
1661 |
|
@@ -1670,6 +1773,7 @@ function relevanssi_get_forbidden_taxonomies() {
|
|
1670 |
'link_category', // Link categories.
|
1671 |
'amp_validation_error', // AMP.
|
1672 |
'product_visibility', // WooCommerce.
|
|
|
1673 |
);
|
1674 |
}
|
1675 |
|
@@ -1683,3 +1787,26 @@ function relevanssi_get_forbidden_taxonomies() {
|
|
1683 |
function relevanssi_return_off() {
|
1684 |
return 'off';
|
1685 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
}
|
52 |
|
53 |
/**
|
54 |
+
* Adds the search result match breakdown to the post object.
|
|
|
|
|
|
|
55 |
*
|
56 |
+
* Reads in the number of matches and stores it in the relevanssi_hits filed
|
57 |
+
* of the post object. The post object is passed as a reference and modified
|
58 |
+
* on the fly.
|
59 |
*
|
60 |
+
* @param object $post The post object, passed as a reference.
|
61 |
+
* @param array $data The source data.
|
62 |
*/
|
63 |
+
function relevanssi_add_matches( &$post, $data ) {
|
64 |
+
$hits = array(
|
65 |
+
'body' => 0,
|
66 |
+
'title' => 0,
|
67 |
+
'comment' => 0,
|
68 |
+
'author' => 0,
|
69 |
+
'excerpt' => 0,
|
70 |
+
'customfield' => 0,
|
71 |
+
'mysqlcolumn' => 0,
|
72 |
+
'taxonomy' => array(
|
73 |
+
'tag' => 0,
|
74 |
+
'category' => 0,
|
75 |
+
'taxonomy' => 0,
|
76 |
+
),
|
77 |
+
'score' => 0,
|
78 |
+
'terms' => array(),
|
79 |
+
);
|
80 |
+
if ( isset( $data['body_matches'][ $post->ID ] ) ) {
|
81 |
+
$hits['body'] = $data['body_matches'][ $post->ID ];
|
82 |
}
|
83 |
+
if ( isset( $data['title_matches'][ $post->ID ] ) ) {
|
84 |
+
$hits['title'] = $data['title_matches'][ $post->ID ];
|
|
|
|
|
85 |
}
|
86 |
+
if ( isset( $data['tag_matches'][ $post->ID ] ) ) {
|
87 |
+
$hits['taxonomy']['tag'] = $data['tag_matches'][ $post->ID ];
|
|
|
|
|
88 |
}
|
89 |
+
if ( isset( $data['category_matches'][ $post->ID ] ) ) {
|
90 |
+
$hits['taxonomy']['category'] = $data['category_matches'][ $post->ID ];
|
|
|
|
|
91 |
}
|
92 |
+
if ( isset( $data['taxonomy_matches'][ $post->ID ] ) ) {
|
93 |
+
$hits['taxonomy']['taxonomy'] = $data['taxonomy_matches'][ $post->ID ];
|
|
|
|
|
94 |
}
|
95 |
+
if ( isset( $data['comment_matches'][ $post->ID ] ) ) {
|
96 |
+
$hits['comment'] = $data['comment_matches'][ $post->ID ];
|
|
|
|
|
97 |
}
|
98 |
+
if ( isset( $data['author_matches'][ $post->ID ] ) ) {
|
99 |
+
$hits['author'] = $data['author_matches'][ $post->ID ];
|
|
|
|
|
100 |
}
|
101 |
+
if ( isset( $data['excerpt_matches'][ $post->ID ] ) ) {
|
102 |
+
$hits['excerpt'] = $data['excerpt_matches'][ $post->ID ];
|
103 |
+
}
|
104 |
+
if ( isset( $data['customfield_matches'][ $post->ID ] ) ) {
|
105 |
+
$hits['customfield'] = $data['customfield_matches'][ $post->ID ];
|
106 |
}
|
107 |
+
if ( isset( $data['mysqlcolumn_matches'][ $post->ID ] ) ) {
|
108 |
+
$hits['mysqlcolumn'] = $data['mysqlcolumn_matches'][ $post->ID ];
|
109 |
+
}
|
110 |
+
if ( isset( $data['scores'][ $post->ID ] ) ) {
|
111 |
+
$hits['score'] = round( $data['scores'][ $post->ID ], 2 );
|
112 |
+
}
|
113 |
+
if ( isset( $data['term_hits'][ $post->ID ] ) ) {
|
114 |
+
$hits['terms'] = $data['term_hits'][ $post->ID ];
|
115 |
+
arsort( $hits['terms'] );
|
116 |
+
}
|
117 |
+
$post->relevanssi_hits = $hits;
|
118 |
+
}
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Generates the search result breakdown added to the search results.
|
122 |
+
*
|
123 |
+
* Gets the source data from the post object and then replaces the placeholders
|
124 |
+
* in the breakdown template with the data.
|
125 |
+
*
|
126 |
+
* @param object $post The post object.
|
127 |
+
*
|
128 |
+
* @return string The search results breakdown for the post.
|
129 |
+
*/
|
130 |
+
function relevanssi_show_matches( $post ) {
|
131 |
$term_hits = '';
|
132 |
$total_hits = 0;
|
133 |
+
foreach ( $post->relevanssi_hits['terms'] as $term => $hits ) {
|
134 |
$term_hits .= " $term: $hits";
|
135 |
$total_hits += $hits;
|
136 |
}
|
137 |
|
138 |
$text = stripslashes( get_option( 'relevanssi_show_matches_text' ) );
|
139 |
+
$replace_these = array(
|
140 |
+
'%body%',
|
141 |
+
'%title%',
|
142 |
+
'%tags%',
|
143 |
+
'%categories%',
|
144 |
+
'%taxonomies%',
|
145 |
+
'%comments%',
|
146 |
+
'%customfields%',
|
147 |
+
'%author%',
|
148 |
+
'%excerpt%',
|
149 |
+
'%mysqlcolumns%',
|
150 |
+
'%score%',
|
151 |
+
'%terms%',
|
152 |
+
'%total%',
|
153 |
+
);
|
154 |
+
$replacements = array(
|
155 |
+
$post->relevanssi_hits['body'],
|
156 |
+
$post->relevanssi_hits['title'],
|
157 |
+
$post->relevanssi_hits['taxonomy']['tag'],
|
158 |
+
$post->relevanssi_hits['taxonomy']['category'],
|
159 |
+
$post->relevanssi_hits['taxonomy']['taxonomy'],
|
160 |
+
$post->relevanssi_hits['comment'],
|
161 |
+
$post->relevanssi_hits['customfield'],
|
162 |
+
$post->relevanssi_hits['author'],
|
163 |
+
$post->relevanssi_hits['excerpt'],
|
164 |
+
$post->relevanssi_hits['mysqlcolumn'],
|
165 |
+
$post->relevanssi_hits['score'],
|
166 |
+
$term_hits,
|
167 |
+
$total_hits,
|
168 |
+
);
|
169 |
$result = ' ' . str_replace( $replace_these, $replacements, $text );
|
170 |
|
171 |
/**
|
376 |
$phrases = relevanssi_extract_phrases( $search_query );
|
377 |
$status = relevanssi_valid_status_array();
|
378 |
|
379 |
+
// Add "inherit" to the list of allowed statuses to include attachments.
|
380 |
+
if ( ! strstr( $status, 'inherit' ) ) {
|
381 |
+
$status .= ",'inherit'";
|
382 |
+
}
|
383 |
+
|
384 |
$all_queries = array();
|
385 |
+
if ( 0 === count( $phrases ) ) {
|
386 |
+
return $all_queries;
|
387 |
+
}
|
388 |
+
|
389 |
+
foreach ( $phrases as $phrase ) {
|
390 |
+
$queries = array();
|
391 |
+
$phrase = $wpdb->esc_like( $phrase );
|
392 |
+
$phrase = str_replace( '‘', '_', $phrase );
|
393 |
+
$phrase = str_replace( '’', '_', $phrase );
|
394 |
+
$phrase = str_replace( "'", '_', $phrase );
|
395 |
+
$phrase = str_replace( '"', '_', $phrase );
|
396 |
+
$phrase = str_replace( '”', '_', $phrase );
|
397 |
+
$phrase = str_replace( '“', '_', $phrase );
|
398 |
+
$phrase = str_replace( '„', '_', $phrase );
|
399 |
+
$phrase = str_replace( '´', '_', $phrase );
|
400 |
+
$phrase = esc_sql( $phrase );
|
401 |
+
|
402 |
+
$excerpt = '';
|
403 |
+
if ( 'on' === get_option( 'relevanssi_index_excerpt' ) ) {
|
404 |
+
$excerpt = " OR post_excerpt LIKE '%$phrase%'";
|
405 |
+
}
|
406 |
|
407 |
+
$query = "(SELECT ID FROM $wpdb->posts
|
408 |
+
WHERE (post_content LIKE '%$phrase%' OR post_title LIKE '%$phrase%' $excerpt)
|
409 |
+
AND post_status IN ($status))";
|
410 |
|
411 |
+
$queries[] = $query;
|
412 |
+
|
413 |
+
$taxonomies = get_option( 'relevanssi_index_taxonomies_list', array() );
|
414 |
+
if ( $taxonomies ) {
|
415 |
+
$taxonomies_escaped = implode( "','", array_map( 'esc_sql', $taxonomies ) );
|
416 |
+
$taxonomies_sql = "AND s.taxonomy IN ('$taxonomies_escaped')";
|
417 |
|
418 |
$query = "(SELECT ID FROM $wpdb->posts as p, $wpdb->term_relationships as r, $wpdb->term_taxonomy as s, $wpdb->terms as t
|
419 |
WHERE r.term_taxonomy_id = s.term_taxonomy_id AND s.term_id = t.term_id AND p.ID = r.object_id
|
420 |
+
$taxonomies_sql
|
421 |
AND t.name LIKE '%$phrase%' AND p.post_status IN ($status))";
|
422 |
|
423 |
$queries[] = $query;
|
424 |
+
}
|
425 |
+
|
426 |
+
$custom_fields = relevanssi_get_custom_fields();
|
427 |
+
if ( $custom_fields ) {
|
428 |
+
$keys = '';
|
429 |
+
|
430 |
+
if ( is_array( $custom_fields ) ) {
|
431 |
+
$custom_fields_escaped = implode( "','", array_map( 'esc_sql', $custom_fields ) );
|
432 |
+
$keys = "AND m.meta_key IN ('$custom_fields_escaped')";
|
433 |
+
}
|
434 |
+
|
435 |
+
if ( 'visible' === $custom_fields ) {
|
436 |
+
$keys = "AND (m.meta_key NOT LIKE '_%' OR m.meta_key = '_relevanssi_pdf_content')";
|
437 |
+
}
|
438 |
|
439 |
$query = "(SELECT ID
|
440 |
+
FROM $wpdb->posts AS p, $wpdb->postmeta AS m
|
441 |
+
WHERE p.ID = m.post_id
|
442 |
+
$keys
|
443 |
+
AND m.meta_value LIKE '%$phrase%'
|
444 |
+
AND p.post_status IN ($status))";
|
445 |
|
446 |
$queries[] = $query;
|
447 |
+
}
|
448 |
|
449 |
+
if ( 'on' === get_option( 'relevanssi_index_pdf_parent' ) ) {
|
450 |
+
$query = "(SELECT parent.ID
|
451 |
+
FROM $wpdb->posts AS p, $wpdb->postmeta AS m, $wpdb->posts AS parent
|
452 |
+
WHERE p.ID = m.post_id
|
453 |
+
AND p.post_parent = parent.ID
|
454 |
+
AND m.meta_key = '_relevanssi_pdf_content'
|
455 |
+
AND m.meta_value LIKE '%$phrase%'
|
456 |
+
AND p.post_status = 'inherit')";
|
457 |
+
|
458 |
+
$queries[] = $query;
|
459 |
}
|
460 |
+
|
461 |
+
$queries = implode( ' OR relevanssi.doc IN ', $queries );
|
462 |
+
$queries = "(relevanssi.doc IN $queries)";
|
463 |
+
$all_queries[] = $queries;
|
464 |
}
|
465 |
|
466 |
$operator = strtoupper( $operator );
|
989 |
|
990 |
$count = count( $matches[0] );
|
991 |
for ( $i = 0; $i < $count; $i++ ) {
|
992 |
+
$highlighted_tag_name = relevanssi_highlight_terms( $tag_names[ $i ], get_search_query(), true );
|
993 |
$highlighted[ $i ] = str_replace( '>' . $tag_names[ $i ] . '<', '>' . $highlighted_tag_name . '<', $originals[ $i ] );
|
994 |
}
|
995 |
|
1746 |
'jp_pay_product', // Jetpack.
|
1747 |
'jp_mem_plan', // Jetpack.
|
1748 |
'tablepress_table', // TablePress.
|
1749 |
+
'ninja-table', // Ninja Tables.
|
1750 |
'shop_order', // WooCommerce.
|
1751 |
'shop_order_refund', // WooCommerce.
|
1752 |
'shop_webhook', // WooCommerce.
|
1753 |
+
'et_theme_builder', // Divi.
|
1754 |
+
'et_template', // Divi.
|
1755 |
+
'et_header_layout', // Divi.
|
1756 |
+
'et_body_layout', // Divi.
|
1757 |
+
'et_footer_layout', // Divi.
|
1758 |
+
'wpforms', // WP Forms.
|
1759 |
+
'amn_wpforms', // WP Forms.
|
1760 |
+
'wpforms_log', // WP Forms.
|
1761 |
+
'dlm_download_version', // Download Monitor.
|
1762 |
);
|
1763 |
}
|
1764 |
|
1773 |
'link_category', // Link categories.
|
1774 |
'amp_validation_error', // AMP.
|
1775 |
'product_visibility', // WooCommerce.
|
1776 |
+
'wpforms_log_type', // WP Forms.
|
1777 |
);
|
1778 |
}
|
1779 |
|
1787 |
function relevanssi_return_off() {
|
1788 |
return 'off';
|
1789 |
}
|
1790 |
+
|
1791 |
+
/**
|
1792 |
+
* Filters out unwanted custom fields.
|
1793 |
+
*
|
1794 |
+
* Added to the relevanssi_custom_field_value filter hook.
|
1795 |
+
*
|
1796 |
+
* @see relevanssi_index_custom_fields()
|
1797 |
+
*
|
1798 |
+
* @param array $values The custom field values.
|
1799 |
+
* @param string $field The custom field name.
|
1800 |
+
*
|
1801 |
+
* @return array Empty array for unwanted custom fields.
|
1802 |
+
*/
|
1803 |
+
function relevanssi_filter_custom_fields( $values, $field ) {
|
1804 |
+
$unwanted_custom_fields = array(
|
1805 |
+
'classic-editor-remember' => true,
|
1806 |
+
'php_everywhere_code' => true,
|
1807 |
+
);
|
1808 |
+
if ( isset( $unwanted_custom_fields[ $field ] ) ) {
|
1809 |
+
$values = array();
|
1810 |
+
}
|
1811 |
+
return $values;
|
1812 |
+
}
|
lib/compatibility/gutenberg.php
CHANGED
@@ -19,15 +19,35 @@ if ( RELEVANSSI_PREMIUM ) {
|
|
19 |
add_filter( 'relevanssi_post_content', 'relevanssi_gutenberg_block_rendering', 10 );
|
20 |
|
21 |
/**
|
22 |
-
* Renders Gutenberg
|
23 |
*
|
24 |
-
*
|
25 |
-
*
|
|
|
|
|
|
|
|
|
26 |
*
|
27 |
* @param string $content The post content.
|
28 |
*
|
29 |
* @return string The post content with the rendered content added.
|
30 |
*/
|
31 |
function relevanssi_gutenberg_block_rendering( $content ) {
|
32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
}
|
19 |
add_filter( 'relevanssi_post_content', 'relevanssi_gutenberg_block_rendering', 10 );
|
20 |
|
21 |
/**
|
22 |
+
* Renders Gutenberg blocks.
|
23 |
*
|
24 |
+
* Renders all sorts of Gutenberg blocks, including reusable blocks and ACF
|
25 |
+
* blocks. Also enables basic Gutenberg deindexing: you can add an extra CSS
|
26 |
+
* class 'relevanssi_noindex' to a block to stop it from being indexed by
|
27 |
+
* Relevanssi. This function is essentially the same as core do_blocks().
|
28 |
+
*
|
29 |
+
* @see do_blocks()
|
30 |
*
|
31 |
* @param string $content The post content.
|
32 |
*
|
33 |
* @return string The post content with the rendered content added.
|
34 |
*/
|
35 |
function relevanssi_gutenberg_block_rendering( $content ) {
|
36 |
+
$blocks = parse_blocks( $content );
|
37 |
+
$output = '';
|
38 |
+
|
39 |
+
foreach ( $blocks as $block ) {
|
40 |
+
if ( ! isset( $block['attrs']['className'] ) || strstr( $block['attrs']['className'], 'relevanssi_noindex' ) === false ) {
|
41 |
+
$output .= render_block( $block );
|
42 |
+
}
|
43 |
+
}
|
44 |
+
|
45 |
+
// If there are blocks in this content, we shouldn't run wpautop() on it later.
|
46 |
+
$priority = has_filter( 'the_content', 'wpautop' );
|
47 |
+
if ( false !== $priority && doing_filter( 'the_content' ) && has_blocks( $content ) ) {
|
48 |
+
remove_filter( 'the_content', 'wpautop', $priority );
|
49 |
+
add_filter( 'the_content', '_restore_wpautop_hook', $priority + 1 );
|
50 |
+
}
|
51 |
+
|
52 |
+
return $output;
|
53 |
}
|
lib/compatibility/ninjatables.php
ADDED
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* /lib/compatibility/ninjatables.php
|
4 |
+
*
|
5 |
+
* Ninja Tables 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( 'relevanssi_post_content', 'relevanssi_index_ninja_tables' );
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Indexes Ninja Tables table contents.
|
17 |
+
*
|
18 |
+
* Uses regular expression matching to find all the Ninja Tables shortcodes in
|
19 |
+
* the post content and then uses relevanssi_index_ninja_table() to convert the
|
20 |
+
* tables into strings.
|
21 |
+
*
|
22 |
+
* @uses $wpdb WordPress database abstraction.
|
23 |
+
* @see relevanssi_index_ninja_table()
|
24 |
+
*
|
25 |
+
* @param string $content The post content.
|
26 |
+
*
|
27 |
+
* @return string Post content with the Ninja Tables data.
|
28 |
+
*/
|
29 |
+
function relevanssi_index_ninja_tables( $content ) {
|
30 |
+
$m = preg_match_all(
|
31 |
+
'/.*\[ninja_tables.*?id=["\'](\d+)["\'].*?\]/im',
|
32 |
+
$content,
|
33 |
+
$matches,
|
34 |
+
PREG_PATTERN_ORDER
|
35 |
+
);
|
36 |
+
if ( ! $m ) {
|
37 |
+
return $content;
|
38 |
+
}
|
39 |
+
foreach ( $matches[1] as $table_id ) {
|
40 |
+
$content .= ' ' . relevanssi_index_ninja_table( $table_id );
|
41 |
+
}
|
42 |
+
|
43 |
+
return $content;
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Creates a string containing a Ninja Table table contents.
|
48 |
+
*
|
49 |
+
* The string contains the caption and the values from each row. The table
|
50 |
+
* title and description are also included, if they are set visible on the
|
51 |
+
* frontend.
|
52 |
+
*
|
53 |
+
* @uses $wpdb WordPress database abstraction.
|
54 |
+
*
|
55 |
+
* @param int $table_id The table ID.
|
56 |
+
*
|
57 |
+
* @return string The table content as a string.
|
58 |
+
*/
|
59 |
+
function relevanssi_index_ninja_table( $table_id ) {
|
60 |
+
global $wpdb;
|
61 |
+
$table_post = get_post( $table_id );
|
62 |
+
$table_settings = get_post_meta( $table_id, '_ninja_table_settings', true );
|
63 |
+
$table_contents = '';
|
64 |
+
|
65 |
+
if ( isset( $table_settings['show_description'] ) && '1' === $table_settings['show_description'] ) {
|
66 |
+
$table_contents .= ' ' . $table_post->post_content;
|
67 |
+
}
|
68 |
+
if ( isset( $table_settings['show_title'] ) && '1' === $table_settings['show_title'] ) {
|
69 |
+
$table_contents .= ' ' . $table_post->post_title;
|
70 |
+
}
|
71 |
+
$table_contents .= ' ' . get_post_meta( $table_id, '_ninja_table_caption', true );
|
72 |
+
|
73 |
+
$rows = $wpdb->get_results(
|
74 |
+
$wpdb->prepare(
|
75 |
+
"SELECT value FROM {$wpdb->prefix}ninja_table_items WHERE table_id=%d",
|
76 |
+
$table_id
|
77 |
+
)
|
78 |
+
);
|
79 |
+
foreach ( $rows as $row ) {
|
80 |
+
$table_contents .= ' ' . implode( ' ', array_values( get_object_vars( json_decode( $row->value ) ) ) );
|
81 |
+
}
|
82 |
+
|
83 |
+
return $table_contents;
|
84 |
+
}
|
lib/compatibility/paidmembershippro.php
CHANGED
@@ -22,8 +22,13 @@ add_filter( 'relevanssi_post_ok', 'relevanssi_paidmembershippro_compatibility',
|
|
22 |
* otherwise false.
|
23 |
*/
|
24 |
function relevanssi_paidmembershippro_compatibility( $post_ok, $post_id ) {
|
25 |
-
$
|
26 |
-
|
|
|
|
|
|
|
|
|
|
|
27 |
|
28 |
return $post_ok;
|
29 |
}
|
22 |
* otherwise false.
|
23 |
*/
|
24 |
function relevanssi_paidmembershippro_compatibility( $post_ok, $post_id ) {
|
25 |
+
$status = relevanssi_get_post_status( $post_id );
|
26 |
+
|
27 |
+
if ( 'publish' === $status ) {
|
28 |
+
// Only apply to published posts, don't apply to drafts.
|
29 |
+
$current_user = wp_get_current_user();
|
30 |
+
$post_ok = pmpro_has_membership_access( $post_id, $current_user->ID );
|
31 |
+
}
|
32 |
|
33 |
return $post_ok;
|
34 |
}
|
lib/compatibility/polylang.php
CHANGED
@@ -134,14 +134,26 @@ function relevanssi_polylang_term_filter( $hits ) {
|
|
134 |
}
|
135 |
$accepted_hits = array();
|
136 |
foreach ( $hits[0] as $hit ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
137 |
if ( -1 === $hit->ID && isset( $hit->term_id ) ) {
|
138 |
$term_id = intval( $hit->term_id );
|
139 |
$translations = pll_get_term_translations( $term_id );
|
140 |
if ( isset( $translations[ $current_language ] ) && $translations[ $current_language ] === $term_id ) {
|
141 |
-
$accepted_hits[] = $
|
142 |
}
|
143 |
} else {
|
144 |
-
$accepted_hits[] = $
|
145 |
}
|
146 |
}
|
147 |
$hits[0] = $accepted_hits;
|
134 |
}
|
135 |
$accepted_hits = array();
|
136 |
foreach ( $hits[0] as $hit ) {
|
137 |
+
$original_hit = $hit;
|
138 |
+
if ( is_numeric( $hit ) ) {
|
139 |
+
// In case "fields" is set to "ids", fetch the post object we need.
|
140 |
+
$original_hit = $hit;
|
141 |
+
$hit = get_post( $hit );
|
142 |
+
}
|
143 |
+
if ( ! isset( $hit->post_content ) ) {
|
144 |
+
// The "fields" is set to "id=>parent".
|
145 |
+
$original_hit = $hit;
|
146 |
+
$hit = get_post( $hit->ID );
|
147 |
+
}
|
148 |
+
|
149 |
if ( -1 === $hit->ID && isset( $hit->term_id ) ) {
|
150 |
$term_id = intval( $hit->term_id );
|
151 |
$translations = pll_get_term_translations( $term_id );
|
152 |
if ( isset( $translations[ $current_language ] ) && $translations[ $current_language ] === $term_id ) {
|
153 |
+
$accepted_hits[] = $original_hit;
|
154 |
}
|
155 |
} else {
|
156 |
+
$accepted_hits[] = $original_hit;
|
157 |
}
|
158 |
}
|
159 |
$hits[0] = $accepted_hits;
|
lib/indexing.php
CHANGED
@@ -129,12 +129,17 @@ function relevanssi_generate_indexing_query( $valid_status, $extend = false, $re
|
|
129 |
AND post.ID NOT IN (SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_hide_post' AND meta_value = 'on')
|
130 |
$restriction ORDER BY post.ID DESC $limit";
|
131 |
} else {
|
|
|
|
|
|
|
|
|
|
|
132 |
$q = "SELECT post.ID
|
133 |
FROM $wpdb->posts post
|
134 |
LEFT JOIN $wpdb->posts parent ON (post.post_parent=parent.ID)
|
135 |
LEFT JOIN $relevanssi_table r ON (post.ID=r.doc)
|
136 |
WHERE
|
137 |
-
|
138 |
AND
|
139 |
(post.post_status IN ($valid_status)
|
140 |
OR
|
@@ -149,7 +154,12 @@ function relevanssi_generate_indexing_query( $valid_status, $extend = false, $re
|
|
149 |
$restriction ORDER BY post.ID DESC $limit";
|
150 |
}
|
151 |
|
152 |
-
|
|
|
|
|
|
|
|
|
|
|
153 |
}
|
154 |
|
155 |
/**
|
@@ -193,14 +203,20 @@ function relevanssi_post_type_restriction() {
|
|
193 |
/**
|
194 |
* Generates a list of valid post statuses.
|
195 |
*
|
196 |
-
* Generates a list of valid post statuses to use in indexing. By default,
|
197 |
-
* accepts 'publish', 'draft', 'private', 'pending', and 'future'. If
|
198 |
-
* a custom post status, you can use the
|
199 |
-
* your own post status to the list
|
|
|
|
|
|
|
|
|
200 |
*
|
201 |
-
* @return string A comma-separated list of valid post statuses
|
|
|
|
|
202 |
*/
|
203 |
-
function relevanssi_valid_status_array() {
|
204 |
/**
|
205 |
* Filters the valid status array.
|
206 |
*
|
@@ -210,7 +226,12 @@ function relevanssi_valid_status_array() {
|
|
210 |
* @return array Array of post statuses.
|
211 |
*/
|
212 |
$valid_status_array = apply_filters( 'relevanssi_valid_status', array( 'publish', 'draft', 'private', 'pending', 'future' ) );
|
213 |
-
|
|
|
|
|
|
|
|
|
|
|
214 |
|
215 |
if ( is_array( $valid_status_array ) && count( $valid_status_array ) > 0 ) {
|
216 |
foreach ( $valid_status_array as $status ) {
|
@@ -229,21 +250,23 @@ function relevanssi_valid_status_array() {
|
|
229 |
* Builds the index.
|
230 |
*
|
231 |
* @global object $wpdb The WordPress database interface.
|
232 |
-
* @global array $relevanssi_variables The Relevanssi global variables array,
|
233 |
-
* for table names.
|
234 |
*
|
235 |
* @param boolean|int $extend_offset If numeric, offsets the indexing by that
|
236 |
-
* amount. If true, doesn't truncate the index before indexing. If false,
|
237 |
-
* index before indexing. Default false.
|
238 |
-
* @param boolean $verbose Not used anymore, kept for backwards
|
239 |
-
*
|
|
|
|
|
240 |
* @param boolean $is_ajax If true, indexing is done in AJAX context.
|
241 |
* Default false.
|
242 |
*
|
243 |
-
* @return array In AJAX context, returns array with two values:
|
244 |
-
* tells whether indexing is completed or not, and 'indexed'
|
245 |
-
* posts indexed. Outside AJAX context, these values are
|
246 |
-
* format of array(completed, posts indexed).
|
247 |
*/
|
248 |
function relevanssi_build_index( $extend_offset = false, $verbose = null, $post_limit = null, $is_ajax = false ) {
|
249 |
global $wpdb, $relevanssi_variables;
|
@@ -367,6 +390,9 @@ function relevanssi_build_index( $extend_offset = false, $verbose = null, $post_
|
|
367 |
* Default false.
|
368 |
* @param boolean $debug If true, echo out debugging information.
|
369 |
* Default false.
|
|
|
|
|
|
|
370 |
*/
|
371 |
function relevanssi_index_doc( $index_post, $remove_first = false, $custom_fields = '', $bypass_global_post = false, $debug = false ) {
|
372 |
global $wpdb, $post, $relevanssi_variables;
|
@@ -706,16 +732,22 @@ function relevanssi_update_child_posts( $new_status, $old_status, $post ) {
|
|
706 |
* Indexes a published post.
|
707 |
*
|
708 |
* @param int $post_id The post ID.
|
709 |
-
* @param boolean $bypass_global_post If
|
|
|
|
|
|
|
|
|
|
|
|
|
710 |
*/
|
711 |
function relevanssi_publish( $post_id, $bypass_global_post = false ) {
|
712 |
$post_status = get_post_status( $post_id );
|
713 |
if ( 'auto-draft' === $post_status ) {
|
714 |
-
return;
|
715 |
}
|
716 |
|
717 |
$custom_fields = relevanssi_get_custom_fields();
|
718 |
-
relevanssi_index_doc( $post_id, true, $custom_fields, $bypass_global_post );
|
719 |
}
|
720 |
|
721 |
/**
|
@@ -730,13 +762,19 @@ function relevanssi_publish( $post_id, $bypass_global_post = false ) {
|
|
730 |
* @global object $wpdb The WP database interface.
|
731 |
*
|
732 |
* @param int $post_id The post ID.
|
|
|
|
|
|
|
|
|
|
|
|
|
733 |
*/
|
734 |
function relevanssi_insert_edit( $post_id ) {
|
735 |
global $wpdb;
|
736 |
|
737 |
$post_status = get_post_status( $post_id );
|
738 |
if ( 'auto-draft' === $post_status ) {
|
739 |
-
return;
|
740 |
}
|
741 |
|
742 |
if ( 'inherit' === $post_status ) {
|
@@ -758,125 +796,76 @@ function relevanssi_insert_edit( $post_id ) {
|
|
758 |
}
|
759 |
}
|
760 |
|
761 |
-
$
|
|
|
762 |
if ( ! in_array( $post_status, $index_statuses, true ) ) {
|
763 |
$index_this_post = false;
|
764 |
}
|
765 |
|
766 |
if ( $index_this_post ) {
|
767 |
$bypass_global_post = true;
|
768 |
-
relevanssi_publish( $post_id, $bypass_global_post );
|
769 |
} else {
|
770 |
// The post isn't supposed to be indexed anymore, remove it from index.
|
771 |
relevanssi_remove_doc( $post_id );
|
|
|
772 |
}
|
773 |
|
774 |
relevanssi_update_doc_count();
|
775 |
-
}
|
776 |
|
777 |
-
|
778 |
-
* Triggers comment indexing when a comment is edited.
|
779 |
-
*
|
780 |
-
* @author OdditY
|
781 |
-
*
|
782 |
-
* @param int $comment_id Comment id.
|
783 |
-
*/
|
784 |
-
function relevanssi_comment_edit( $comment_id ) {
|
785 |
-
$action = 'update';
|
786 |
-
relevanssi_index_comment( $comment_id, $action );
|
787 |
}
|
788 |
|
789 |
/**
|
790 |
-
*
|
791 |
*
|
792 |
* @author OdditY
|
793 |
*
|
794 |
-
* @param int $comment_id
|
795 |
-
*/
|
796 |
-
function relevanssi_comment_remove( $comment_id ) {
|
797 |
-
$action = 'remove';
|
798 |
-
relevanssi_index_comment( $comment_id, $action );
|
799 |
-
}
|
800 |
-
|
801 |
-
/**
|
802 |
-
* Updates comment indexing when comments are added, edited or deleted.
|
803 |
*
|
804 |
-
* @
|
|
|
|
|
805 |
*
|
806 |
-
* @
|
807 |
-
*
|
|
|
808 |
*/
|
809 |
-
function relevanssi_index_comment( $comment_id
|
810 |
-
global $wpdb;
|
811 |
-
|
812 |
$comment_indexing_type = get_option( 'relevanssi_index_comments' );
|
813 |
$no_pingbacks = false;
|
814 |
$post_id = null;
|
815 |
|
816 |
-
|
817 |
-
|
818 |
-
// All.
|
819 |
-
break;
|
820 |
-
case 'normal':
|
821 |
-
// Exclude trackbacks and pingbacks.
|
822 |
-
$no_pingbacks = true;
|
823 |
-
break;
|
824 |
-
default:
|
825 |
-
// No indexing.
|
826 |
-
return;
|
827 |
}
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
$post_id = $comment->comment_post_ID;
|
836 |
-
break;
|
837 |
-
case 'remove':
|
838 |
-
// Remove, empty the comment and reindex the post.
|
839 |
-
$comment = get_comment( $comment_id );
|
840 |
-
if ( $no_pingbacks && ! empty( $comment->comment_type ) ) {
|
841 |
-
break;
|
842 |
-
}
|
843 |
-
$post_id = $comment->comment_post_ID;
|
844 |
-
if ( $post_id ) {
|
845 |
-
// Empty comment_content and reindex, then let WP delete the empty comment.
|
846 |
-
$wpdb->query( $wpdb->prepare( "UPDATE $wpdb->comments SET comment_content='' WHERE comment_ID=%d", $comment_id ) );
|
847 |
-
}
|
848 |
-
break;
|
849 |
-
default:
|
850 |
-
// Add new comment.
|
851 |
-
$comment = get_comment( $comment_id );
|
852 |
-
if ( $no_pingbacks && ! empty( $comment->comment_type ) ) {
|
853 |
-
break;
|
854 |
-
}
|
855 |
-
if ( 1 !== intval( $comment->comment_approved ) ) {
|
856 |
-
// Comment isn't approved, do not index.
|
857 |
-
break;
|
858 |
-
}
|
859 |
-
$post_id = $comment->comment_post_ID;
|
860 |
-
break;
|
861 |
}
|
862 |
-
if ( $
|
863 |
-
|
864 |
}
|
|
|
|
|
|
|
|
|
|
|
865 |
}
|
866 |
|
867 |
/**
|
868 |
* Returns the comment text for a post.
|
869 |
*
|
870 |
-
* @global object $wpdb The WordPress database interface.
|
871 |
-
*
|
872 |
* @param int $post_id The post ID.
|
873 |
*
|
874 |
* @return string All the comment content as a string that has the comment author
|
875 |
* and the comment text.
|
876 |
*/
|
877 |
function relevanssi_get_comments( $post_id ) {
|
878 |
-
global $wpdb;
|
879 |
-
|
880 |
/**
|
881 |
* If this filter returns true, the comments for the post are not indexed.
|
882 |
*
|
@@ -909,7 +898,6 @@ function relevanssi_get_comments( $post_id ) {
|
|
909 |
'type' => $comment_types,
|
910 |
);
|
911 |
$comments = get_approved_comments( $post_id, $args );
|
912 |
-
|
913 |
if ( count( $comments ) === 0 ) {
|
914 |
break;
|
915 |
}
|
129 |
AND post.ID NOT IN (SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_hide_post' AND meta_value = 'on')
|
130 |
$restriction ORDER BY post.ID DESC $limit";
|
131 |
} else {
|
132 |
+
$processed_post_filter = 'r.doc is null';
|
133 |
+
if ( 'noindex' !== get_option( 'relevanssi_internal_links', 'noindex' ) ) {
|
134 |
+
$processed_post_filter = "(r.doc is null OR r.doc NOT IN (SELECT DISTINCT(doc) FROM $relevanssi_table WHERE link = 0))";
|
135 |
+
}
|
136 |
+
|
137 |
$q = "SELECT post.ID
|
138 |
FROM $wpdb->posts post
|
139 |
LEFT JOIN $wpdb->posts parent ON (post.post_parent=parent.ID)
|
140 |
LEFT JOIN $relevanssi_table r ON (post.ID=r.doc)
|
141 |
WHERE
|
142 |
+
$processed_post_filter
|
143 |
AND
|
144 |
(post.post_status IN ($valid_status)
|
145 |
OR
|
154 |
$restriction ORDER BY post.ID DESC $limit";
|
155 |
}
|
156 |
|
157 |
+
/**
|
158 |
+
* Filters the Relevanssi indexing query.
|
159 |
+
*
|
160 |
+
* @param string $q The indexing MySQL query.
|
161 |
+
*/
|
162 |
+
return apply_filters( 'relevanssi_indexing_query', $q );
|
163 |
}
|
164 |
|
165 |
/**
|
203 |
/**
|
204 |
* Generates a list of valid post statuses.
|
205 |
*
|
206 |
+
* Generates a list of valid post statuses to use in indexing. By default,
|
207 |
+
* Relevanssi accepts 'publish', 'draft', 'private', 'pending', and 'future'. If
|
208 |
+
* you need to use a custom post status, you can use the
|
209 |
+
* 'relevanssi_valid_status' filter hook to add your own post status to the list
|
210 |
+
* of valid statuses.
|
211 |
+
*
|
212 |
+
* @param boolean $return_array If true, return array; default false, return
|
213 |
+
* string.
|
214 |
*
|
215 |
+
* @return string|array A comma-separated list of escaped valid post statuses
|
216 |
+
* ready for MySQL, or an unfiltered array, depending on the $return_array
|
217 |
+
* parameter.
|
218 |
*/
|
219 |
+
function relevanssi_valid_status_array( $return_array = false ) {
|
220 |
/**
|
221 |
* Filters the valid status array.
|
222 |
*
|
226 |
* @return array Array of post statuses.
|
227 |
*/
|
228 |
$valid_status_array = apply_filters( 'relevanssi_valid_status', array( 'publish', 'draft', 'private', 'pending', 'future' ) );
|
229 |
+
|
230 |
+
if ( $return_array ) {
|
231 |
+
return $valid_status_array;
|
232 |
+
}
|
233 |
+
|
234 |
+
$valid_status = array();
|
235 |
|
236 |
if ( is_array( $valid_status_array ) && count( $valid_status_array ) > 0 ) {
|
237 |
foreach ( $valid_status_array as $status ) {
|
250 |
* Builds the index.
|
251 |
*
|
252 |
* @global object $wpdb The WordPress database interface.
|
253 |
+
* @global array $relevanssi_variables The Relevanssi global variables array,
|
254 |
+
* used for table names.
|
255 |
*
|
256 |
* @param boolean|int $extend_offset If numeric, offsets the indexing by that
|
257 |
+
* amount. If true, doesn't truncate the index before indexing. If false,
|
258 |
+
* truncates index before indexing. Default false.
|
259 |
+
* @param boolean $verbose Not used anymore, kept for backwards
|
260 |
+
* compatibility.
|
261 |
+
* @param int $post_limit How many posts to index. Default null, no
|
262 |
+
* limit.
|
263 |
* @param boolean $is_ajax If true, indexing is done in AJAX context.
|
264 |
* Default false.
|
265 |
*
|
266 |
+
* @return array In AJAX context, returns array with two values:
|
267 |
+
* 'indexing_complete' tells whether indexing is completed or not, and 'indexed'
|
268 |
+
* returns the number of posts indexed. Outside AJAX context, these values are
|
269 |
+
* returned as an array in format of array(completed, posts indexed).
|
270 |
*/
|
271 |
function relevanssi_build_index( $extend_offset = false, $verbose = null, $post_limit = null, $is_ajax = false ) {
|
272 |
global $wpdb, $relevanssi_variables;
|
390 |
* Default false.
|
391 |
* @param boolean $debug If true, echo out debugging information.
|
392 |
* Default false.
|
393 |
+
*
|
394 |
+
* @return string|int Number of insert queries run, or -1 if the indexing fails,
|
395 |
+
* or 'hide' in case the post is hidden or 'donotindex' if a filter blocks this.
|
396 |
*/
|
397 |
function relevanssi_index_doc( $index_post, $remove_first = false, $custom_fields = '', $bypass_global_post = false, $debug = false ) {
|
398 |
global $wpdb, $post, $relevanssi_variables;
|
732 |
* Indexes a published post.
|
733 |
*
|
734 |
* @param int $post_id The post ID.
|
735 |
+
* @param boolean $bypass_global_post If true, bypass the global $post object.
|
736 |
+
* Default false.
|
737 |
+
*
|
738 |
+
* @return string|int Returns 'auto-draft' if the post is an auto draft and
|
739 |
+
* thus skipped, or the relevanssi_index_doc() return value.
|
740 |
+
*
|
741 |
+
* @see relevanssi_index_doc()
|
742 |
*/
|
743 |
function relevanssi_publish( $post_id, $bypass_global_post = false ) {
|
744 |
$post_status = get_post_status( $post_id );
|
745 |
if ( 'auto-draft' === $post_status ) {
|
746 |
+
return 'auto-draft';
|
747 |
}
|
748 |
|
749 |
$custom_fields = relevanssi_get_custom_fields();
|
750 |
+
return relevanssi_index_doc( $post_id, true, $custom_fields, $bypass_global_post );
|
751 |
}
|
752 |
|
753 |
/**
|
762 |
* @global object $wpdb The WP database interface.
|
763 |
*
|
764 |
* @param int $post_id The post ID.
|
765 |
+
*
|
766 |
+
* @return string|int Returns 'auto-draft' if the post is an auto draft and
|
767 |
+
* thus skipped, 'removed' if the post is removed or the relevanssi_index_doc()
|
768 |
+
* return value from relevanssi_publish().
|
769 |
+
*
|
770 |
+
* @see relevanssi_publish()
|
771 |
*/
|
772 |
function relevanssi_insert_edit( $post_id ) {
|
773 |
global $wpdb;
|
774 |
|
775 |
$post_status = get_post_status( $post_id );
|
776 |
if ( 'auto-draft' === $post_status ) {
|
777 |
+
return 'auto-draft';
|
778 |
}
|
779 |
|
780 |
if ( 'inherit' === $post_status ) {
|
796 |
}
|
797 |
}
|
798 |
|
799 |
+
$return_array = true;
|
800 |
+
$index_statuses = relevanssi_valid_status_array( $return_array );
|
801 |
if ( ! in_array( $post_status, $index_statuses, true ) ) {
|
802 |
$index_this_post = false;
|
803 |
}
|
804 |
|
805 |
if ( $index_this_post ) {
|
806 |
$bypass_global_post = true;
|
807 |
+
$return_value = relevanssi_publish( $post_id, $bypass_global_post );
|
808 |
} else {
|
809 |
// The post isn't supposed to be indexed anymore, remove it from index.
|
810 |
relevanssi_remove_doc( $post_id );
|
811 |
+
$return_value = 'removed';
|
812 |
}
|
813 |
|
814 |
relevanssi_update_doc_count();
|
|
|
815 |
|
816 |
+
return $return_value;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
817 |
}
|
818 |
|
819 |
/**
|
820 |
+
* Updates comment indexing when comments are added, edited or deleted.
|
821 |
*
|
822 |
* @author OdditY
|
823 |
*
|
824 |
+
* @param int $comment_id Commend ID.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
825 |
*
|
826 |
+
* @see relevanssi_comment_remove
|
827 |
+
* @see relevanssi_comment_edit
|
828 |
+
* @see relevanssi_publish
|
829 |
*
|
830 |
+
* @return int|string The relevanssi_publish return value, "nocommentfound" if
|
831 |
+
* the comment doesn't exist or "donotindex" if it cannot be indexed.
|
832 |
+
* comment indexing is disabled.
|
833 |
*/
|
834 |
+
function relevanssi_index_comment( $comment_id ) {
|
|
|
|
|
835 |
$comment_indexing_type = get_option( 'relevanssi_index_comments' );
|
836 |
$no_pingbacks = false;
|
837 |
$post_id = null;
|
838 |
|
839 |
+
if ( 'normal' === $comment_indexing_type ) {
|
840 |
+
$no_pingbacks = true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
841 |
}
|
842 |
+
if ( 'normal' !== $comment_indexing_type && 'all' !== $comment_indexing_type ) {
|
843 |
+
return 'donotindex';
|
844 |
+
}
|
845 |
+
|
846 |
+
$comment = get_comment( $comment_id );
|
847 |
+
if ( ! $comment ) {
|
848 |
+
return 'nocommentfound';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
849 |
}
|
850 |
+
if ( $no_pingbacks && ! empty( $comment->comment_type ) ) {
|
851 |
+
return 'donotindex';
|
852 |
}
|
853 |
+
if ( 1 !== intval( $comment->comment_approved ) ) {
|
854 |
+
// Comment isn't approved, do not index.
|
855 |
+
return 'donotindex';
|
856 |
+
}
|
857 |
+
return relevanssi_publish( $comment->comment_post_ID );
|
858 |
}
|
859 |
|
860 |
/**
|
861 |
* Returns the comment text for a post.
|
862 |
*
|
|
|
|
|
863 |
* @param int $post_id The post ID.
|
864 |
*
|
865 |
* @return string All the comment content as a string that has the comment author
|
866 |
* and the comment text.
|
867 |
*/
|
868 |
function relevanssi_get_comments( $post_id ) {
|
|
|
|
|
869 |
/**
|
870 |
* If this filter returns true, the comments for the post are not indexed.
|
871 |
*
|
898 |
'type' => $comment_types,
|
899 |
);
|
900 |
$comments = get_approved_comments( $post_id, $args );
|
|
|
901 |
if ( count( $comments ) === 0 ) {
|
902 |
break;
|
903 |
}
|
lib/init.php
CHANGED
@@ -26,8 +26,9 @@ add_action( 'delete_post', 'relevanssi_remove_doc' );
|
|
26 |
|
27 |
// Comment indexing.
|
28 |
add_action( 'comment_post', 'relevanssi_index_comment' );
|
29 |
-
add_action( 'edit_comment', '
|
30 |
-
add_action( '
|
|
|
31 |
|
32 |
// Attachment indexing.
|
33 |
add_action( 'delete_attachment', 'relevanssi_remove_doc' );
|
@@ -42,6 +43,7 @@ add_filter( 'relevanssi_remove_punctuation', 'relevanssi_remove_punct' );
|
|
42 |
add_filter( 'relevanssi_post_ok', 'relevanssi_default_post_ok', 9, 2 );
|
43 |
add_filter( 'relevanssi_query_filter', 'relevanssi_limit_filter' );
|
44 |
add_action( 'relevanssi_trim_logs', 'relevanssi_trim_logs' );
|
|
|
45 |
|
46 |
// Plugin and theme compatibility.
|
47 |
add_filter( 'relevanssi_pre_excerpt_content', 'relevanssi_remove_page_builder_shortcodes', 9 );
|
@@ -194,6 +196,10 @@ function relevanssi_init() {
|
|
194 |
|
195 |
// Always required, the functions check if TablePress is active.
|
196 |
require_once 'compatibility/tablepress.php';
|
|
|
|
|
|
|
|
|
197 |
}
|
198 |
|
199 |
/**
|
26 |
|
27 |
// Comment indexing.
|
28 |
add_action( 'comment_post', 'relevanssi_index_comment' );
|
29 |
+
add_action( 'edit_comment', 'relevanssi_index_comment' );
|
30 |
+
add_action( 'trashed_comment', 'relevanssi_index_comment' );
|
31 |
+
add_action( 'deleted_comment', 'relevanssi_index_comment' );
|
32 |
|
33 |
// Attachment indexing.
|
34 |
add_action( 'delete_attachment', 'relevanssi_remove_doc' );
|
43 |
add_filter( 'relevanssi_post_ok', 'relevanssi_default_post_ok', 9, 2 );
|
44 |
add_filter( 'relevanssi_query_filter', 'relevanssi_limit_filter' );
|
45 |
add_action( 'relevanssi_trim_logs', 'relevanssi_trim_logs' );
|
46 |
+
add_action( 'relevanssi_custom_field_value', 'relevanssi_filter_custom_fields', 10, 2 );
|
47 |
|
48 |
// Plugin and theme compatibility.
|
49 |
add_filter( 'relevanssi_pre_excerpt_content', 'relevanssi_remove_page_builder_shortcodes', 9 );
|
196 |
|
197 |
// Always required, the functions check if TablePress is active.
|
198 |
require_once 'compatibility/tablepress.php';
|
199 |
+
|
200 |
+
if ( defined( 'NINJA_TABLES_VERSION' ) ) {
|
201 |
+
require_once 'compatibility/ninjatables.php';
|
202 |
+
}
|
203 |
}
|
204 |
|
205 |
/**
|
lib/search-query-restrictions.php
CHANGED
@@ -23,9 +23,11 @@ function relevanssi_process_query_args( $args ) {
|
|
23 |
$query_restrictions = '';
|
24 |
$query_join = '';
|
25 |
$query = '';
|
|
|
26 |
|
27 |
if ( function_exists( 'wp_encode_emoji' ) ) {
|
28 |
-
$query
|
|
|
29 |
}
|
30 |
|
31 |
if ( $args['sentence'] ) {
|
@@ -89,6 +91,7 @@ function relevanssi_process_query_args( $args ) {
|
|
89 |
'query_restrictions' => $query_restrictions,
|
90 |
'query_join' => $query_join,
|
91 |
'query_query' => $query,
|
|
|
92 |
);
|
93 |
}
|
94 |
|
23 |
$query_restrictions = '';
|
24 |
$query_join = '';
|
25 |
$query = '';
|
26 |
+
$query_no_synonyms = '';
|
27 |
|
28 |
if ( function_exists( 'wp_encode_emoji' ) ) {
|
29 |
+
$query = wp_encode_emoji( $args['q'] );
|
30 |
+
$query_no_synonyms = wp_encode_emoji( $args['q_no_synonyms'] );
|
31 |
}
|
32 |
|
33 |
if ( $args['sentence'] ) {
|
91 |
'query_restrictions' => $query_restrictions,
|
92 |
'query_join' => $query_join,
|
93 |
'query_query' => $query,
|
94 |
+
'query_no_synonyms' => $query_no_synonyms,
|
95 |
);
|
96 |
}
|
97 |
|
lib/search.php
CHANGED
@@ -129,6 +129,7 @@ function relevanssi_search( $args ) {
|
|
129 |
$query_restrictions = $query_data['query_restrictions'];
|
130 |
$query_join = $query_data['query_join'];
|
131 |
$q = $query_data['query_query'];
|
|
|
132 |
|
133 |
/**
|
134 |
* Filters whether stopwords are removed from titles.
|
@@ -180,15 +181,19 @@ function relevanssi_search( $args ) {
|
|
180 |
|
181 |
$total_hits = 0;
|
182 |
|
183 |
-
$title_matches
|
184 |
-
$tag_matches
|
185 |
-
$comment_matches
|
186 |
-
$link_matches
|
187 |
-
$body_matches
|
188 |
-
$category_matches
|
189 |
-
$taxonomy_matches
|
190 |
-
$
|
191 |
-
$
|
|
|
|
|
|
|
|
|
192 |
|
193 |
$fuzzy = get_option( 'relevanssi_fuzzy' );
|
194 |
|
@@ -470,7 +475,7 @@ function relevanssi_search( $args ) {
|
|
470 |
|
471 |
if ( $exact_match_bonus ) {
|
472 |
$post = relevanssi_get_post( $match->doc );
|
473 |
-
$clean_q = str_replace( array( '"', '”', '“' ), '', $
|
474 |
if ( $post && $clean_q ) {
|
475 |
if ( stristr( $post->post_title, $clean_q ) !== false ) {
|
476 |
$match->weight *= $exact_match_boost['title'];
|
@@ -502,13 +507,29 @@ function relevanssi_search( $args ) {
|
|
502 |
if ( ! isset( $comment_matches[ $match->doc ] ) ) {
|
503 |
$comment_matches[ $match->doc ] = 0;
|
504 |
}
|
505 |
-
$
|
506 |
-
|
507 |
-
|
508 |
-
$
|
509 |
-
|
510 |
-
|
511 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
512 |
|
513 |
/* Post type weights. */
|
514 |
$type = null;
|
@@ -668,19 +689,24 @@ function relevanssi_search( $args ) {
|
|
668 |
global $wp_query;
|
669 |
$wp_query->set( 'operator', 'OR' );
|
670 |
|
671 |
-
$or_args['
|
672 |
-
$
|
673 |
-
|
674 |
-
|
675 |
-
$
|
676 |
-
$
|
677 |
-
$
|
678 |
-
$
|
679 |
-
$
|
680 |
-
$
|
681 |
-
$
|
682 |
-
$
|
683 |
-
$
|
|
|
|
|
|
|
|
|
|
|
684 |
}
|
685 |
$params = array( 'args' => $args );
|
686 |
/**
|
@@ -695,18 +721,21 @@ function relevanssi_search( $args ) {
|
|
695 |
$params = apply_filters( 'relevanssi_fallback', $params );
|
696 |
$args = $params['args'];
|
697 |
if ( isset( $params['return'] ) ) {
|
698 |
-
$return
|
699 |
-
$hits
|
700 |
-
$body_matches
|
701 |
-
$title_matches
|
702 |
-
$tag_matches
|
703 |
-
$category_matches
|
704 |
-
$taxonomy_matches
|
705 |
-
$comment_matches
|
706 |
-
$
|
707 |
-
$
|
708 |
-
$
|
709 |
-
$
|
|
|
|
|
|
|
710 |
}
|
711 |
}
|
712 |
|
@@ -753,17 +782,21 @@ function relevanssi_search( $args ) {
|
|
753 |
}
|
754 |
}
|
755 |
$return = array(
|
756 |
-
'hits'
|
757 |
-
'body_matches'
|
758 |
-
'title_matches'
|
759 |
-
'tag_matches'
|
760 |
-
'category_matches'
|
761 |
-
'
|
762 |
-
'
|
763 |
-
'
|
764 |
-
'
|
765 |
-
'
|
766 |
-
'
|
|
|
|
|
|
|
|
|
767 |
);
|
768 |
|
769 |
return $return;
|
@@ -920,6 +953,9 @@ function relevanssi_do_query( &$query ) {
|
|
920 |
restore_current_blog();
|
921 |
}
|
922 |
}
|
|
|
|
|
|
|
923 |
if ( 'on' === get_option( 'relevanssi_show_matches' ) && empty( $search_params['fields'] ) ) {
|
924 |
$post_id = $post->ID;
|
925 |
if ( 'user' === $post->post_type ) {
|
@@ -932,7 +968,7 @@ function relevanssi_do_query( &$query ) {
|
|
932 |
if ( isset( $post->blog_id ) ) {
|
933 |
$post_id = $post->blog_id . '|' . $post->ID;
|
934 |
}
|
935 |
-
$post->post_excerpt .= relevanssi_show_matches( $
|
936 |
}
|
937 |
|
938 |
if ( empty( $search_params['fields'] ) ) {
|
@@ -1245,8 +1281,6 @@ function relevanssi_compile_search_args( $query, $q ) {
|
|
1245 |
'operator' => 'NOT IN',
|
1246 |
);
|
1247 |
}
|
1248 |
-
|
1249 |
-
$query->tax_query = $tax_query;
|
1250 |
}
|
1251 |
|
1252 |
$author = false;
|
@@ -1456,8 +1490,13 @@ function relevanssi_compile_search_args( $query, $q ) {
|
|
1456 |
$include_attachments = $query->query_vars['include_attachments'];
|
1457 |
}
|
1458 |
|
|
|
|
|
|
|
|
|
1459 |
// Add synonyms.
|
1460 |
// This is done here so the new terms will get highlighting.
|
|
|
1461 |
if ( 'OR' === $operator ) {
|
1462 |
// Synonyms are only used in OR queries.
|
1463 |
$q = relevanssi_add_synonyms( $q );
|
@@ -1465,6 +1504,7 @@ function relevanssi_compile_search_args( $query, $q ) {
|
|
1465 |
|
1466 |
$search_params = array(
|
1467 |
'q' => $q,
|
|
|
1468 |
'tax_query' => $tax_query,
|
1469 |
'tax_query_relation' => $tax_query_relation,
|
1470 |
'post_query' => $post_query,
|
129 |
$query_restrictions = $query_data['query_restrictions'];
|
130 |
$query_join = $query_data['query_join'];
|
131 |
$q = $query_data['query_query'];
|
132 |
+
$q_no_synonyms = $query_data['query_no_synonyms'];
|
133 |
|
134 |
/**
|
135 |
* Filters whether stopwords are removed from titles.
|
181 |
|
182 |
$total_hits = 0;
|
183 |
|
184 |
+
$title_matches = array();
|
185 |
+
$tag_matches = array();
|
186 |
+
$comment_matches = array();
|
187 |
+
$link_matches = array();
|
188 |
+
$body_matches = array();
|
189 |
+
$category_matches = array();
|
190 |
+
$taxonomy_matches = array();
|
191 |
+
$customfield_matches = array();
|
192 |
+
$mysqlcolumn_matches = array();
|
193 |
+
$author_matches = array();
|
194 |
+
$excerpt_matches = array();
|
195 |
+
$scores = array();
|
196 |
+
$term_hits = array();
|
197 |
|
198 |
$fuzzy = get_option( 'relevanssi_fuzzy' );
|
199 |
|
475 |
|
476 |
if ( $exact_match_bonus ) {
|
477 |
$post = relevanssi_get_post( $match->doc );
|
478 |
+
$clean_q = str_replace( array( '"', '”', '“' ), '', $q_no_synonyms );
|
479 |
if ( $post && $clean_q ) {
|
480 |
if ( stristr( $post->post_title, $clean_q ) !== false ) {
|
481 |
$match->weight *= $exact_match_boost['title'];
|
507 |
if ( ! isset( $comment_matches[ $match->doc ] ) ) {
|
508 |
$comment_matches[ $match->doc ] = 0;
|
509 |
}
|
510 |
+
if ( ! isset( $customfield_matches[ $match->doc ] ) ) {
|
511 |
+
$customfield_matches[ $match->doc ] = 0;
|
512 |
+
}
|
513 |
+
if ( ! isset( $author_matches[ $match->doc ] ) ) {
|
514 |
+
$author_matches[ $match->doc ] = 0;
|
515 |
+
}
|
516 |
+
if ( ! isset( $excerpt_matches[ $match->doc ] ) ) {
|
517 |
+
$excerpt_matches[ $match->doc ] = 0;
|
518 |
+
}
|
519 |
+
if ( ! isset( $mysqlcolumn_matches[ $match->doc ] ) ) {
|
520 |
+
$mysqlcolumn_matches[ $match->doc ] = 0;
|
521 |
+
}
|
522 |
+
$body_matches[ $match->doc ] += $match->content;
|
523 |
+
$title_matches[ $match->doc ] += $match->title;
|
524 |
+
$link_matches[ $match->doc ] += $match->link;
|
525 |
+
$tag_matches[ $match->doc ] += $match->tag;
|
526 |
+
$category_matches[ $match->doc ] += $match->category;
|
527 |
+
$taxonomy_matches[ $match->doc ] += $match->taxonomy;
|
528 |
+
$comment_matches[ $match->doc ] += $match->comment;
|
529 |
+
$customfield_matches[ $match->doc ] += $match->customfield;
|
530 |
+
$author_matches[ $match->doc ] += $match->author;
|
531 |
+
$excerpt_matches[ $match->doc ] += $match->excerpt;
|
532 |
+
$mysqlcolumn_matches[ $match->doc ] += $match->mysqlcolumn;
|
533 |
|
534 |
/* Post type weights. */
|
535 |
$type = null;
|
689 |
global $wp_query;
|
690 |
$wp_query->set( 'operator', 'OR' );
|
691 |
|
692 |
+
$or_args['q_no_synonyms'] = $q;
|
693 |
+
$or_args['q'] = relevanssi_add_synonyms( $q );
|
694 |
+
$return = relevanssi_search( $or_args );
|
695 |
+
|
696 |
+
$hits = $return['hits'];
|
697 |
+
$body_matches = $return['body_matches'];
|
698 |
+
$title_matches = $return['title_matches'];
|
699 |
+
$tag_matches = $return['tag_matches'];
|
700 |
+
$category_matches = $return['category_matches'];
|
701 |
+
$taxonomy_matches = $return['taxonomy_matches'];
|
702 |
+
$comment_matches = $return['comment_matches'];
|
703 |
+
$link_matches = $return['link_matches'];
|
704 |
+
$author_matches = $return['author_matches'];
|
705 |
+
$customfield_matches = $return['customfield_matches'];
|
706 |
+
$mysqlcolumn_matches = $return['mysqlcolumn_matches'];
|
707 |
+
$excerpt_matches = $return['excerpt_matches'];
|
708 |
+
$term_hits = $return['term_hits'];
|
709 |
+
$q = $return['query'];
|
710 |
}
|
711 |
$params = array( 'args' => $args );
|
712 |
/**
|
721 |
$params = apply_filters( 'relevanssi_fallback', $params );
|
722 |
$args = $params['args'];
|
723 |
if ( isset( $params['return'] ) ) {
|
724 |
+
$return = $params['return'];
|
725 |
+
$hits = $return['hits'];
|
726 |
+
$body_matches = $return['body_matches'];
|
727 |
+
$title_matches = $return['title_matches'];
|
728 |
+
$tag_matches = $return['tag_matches'];
|
729 |
+
$category_matches = $return['category_matches'];
|
730 |
+
$taxonomy_matches = $return['taxonomy_matches'];
|
731 |
+
$comment_matches = $return['comment_matches'];
|
732 |
+
$link_matches = $return['link_matches'];
|
733 |
+
$author_matches = $return['author_matches'];
|
734 |
+
$customfield_matches = $return['customfield_matches'];
|
735 |
+
$mysqlcolumn_matches = $return['mysqlcolumn_matches'];
|
736 |
+
$excerpt_matches = $return['excerpt_matches'];
|
737 |
+
$term_hits = $return['term_hits'];
|
738 |
+
$q = $return['query'];
|
739 |
}
|
740 |
}
|
741 |
|
782 |
}
|
783 |
}
|
784 |
$return = array(
|
785 |
+
'hits' => $hits,
|
786 |
+
'body_matches' => $body_matches,
|
787 |
+
'title_matches' => $title_matches,
|
788 |
+
'tag_matches' => $tag_matches,
|
789 |
+
'category_matches' => $category_matches,
|
790 |
+
'comment_matches' => $comment_matches,
|
791 |
+
'taxonomy_matches' => $taxonomy_matches,
|
792 |
+
'link_matches' => $link_matches,
|
793 |
+
'customfield_matches' => $customfield_matches,
|
794 |
+
'mysqlcolumn_matches' => $mysqlcolumn_matches,
|
795 |
+
'author_matches' => $author_matches,
|
796 |
+
'excerpt_matches' => $excerpt_matches,
|
797 |
+
'scores' => $scores,
|
798 |
+
'term_hits' => $term_hits,
|
799 |
+
'query' => $q,
|
800 |
);
|
801 |
|
802 |
return $return;
|
953 |
restore_current_blog();
|
954 |
}
|
955 |
}
|
956 |
+
if ( empty( $search_params['fields'] ) ) {
|
957 |
+
relevanssi_add_matches( $post, $return );
|
958 |
+
}
|
959 |
if ( 'on' === get_option( 'relevanssi_show_matches' ) && empty( $search_params['fields'] ) ) {
|
960 |
$post_id = $post->ID;
|
961 |
if ( 'user' === $post->post_type ) {
|
968 |
if ( isset( $post->blog_id ) ) {
|
969 |
$post_id = $post->blog_id . '|' . $post->ID;
|
970 |
}
|
971 |
+
$post->post_excerpt .= relevanssi_show_matches( $post );
|
972 |
}
|
973 |
|
974 |
if ( empty( $search_params['fields'] ) ) {
|
1281 |
'operator' => 'NOT IN',
|
1282 |
);
|
1283 |
}
|
|
|
|
|
1284 |
}
|
1285 |
|
1286 |
$author = false;
|
1490 |
$include_attachments = $query->query_vars['include_attachments'];
|
1491 |
}
|
1492 |
|
1493 |
+
if ( function_exists( 'relevanssi_extract_specifier' ) ) {
|
1494 |
+
$q = relevanssi_extract_specifier( $q );
|
1495 |
+
}
|
1496 |
+
|
1497 |
// Add synonyms.
|
1498 |
// This is done here so the new terms will get highlighting.
|
1499 |
+
$q_no_synonyms = $q;
|
1500 |
if ( 'OR' === $operator ) {
|
1501 |
// Synonyms are only used in OR queries.
|
1502 |
$q = relevanssi_add_synonyms( $q );
|
1504 |
|
1505 |
$search_params = array(
|
1506 |
'q' => $q,
|
1507 |
+
'q_no_synonyms' => $q_no_synonyms,
|
1508 |
'tax_query' => $tax_query,
|
1509 |
'tax_query_relation' => $tax_query_relation,
|
1510 |
'post_query' => $post_query,
|
lib/tabs/excerpts-tab.php
CHANGED
@@ -434,7 +434,7 @@ function relevanssi_excerpts_tab() {
|
|
434 |
}
|
435 |
?>
|
436 |
><?php echo esc_attr( $show_matches_text ); ?></textarea>
|
437 |
-
<p class="description"><?php esc_html_e( 'Use %body%, %title%, %tags% and %
|
438 |
</td>
|
439 |
</tr>
|
440 |
</table>
|
434 |
}
|
435 |
?>
|
436 |
><?php echo esc_attr( $show_matches_text ); ?></textarea>
|
437 |
+
<p class="description"><?php esc_html_e( 'Use %body%, %title%, %categories%, %tags%, %taxonomies%, %comments%, %customfields%, %author%, %excerpt% and %mysqlcolumns% to display the number of hits (in different parts of the post), %total% for total hits, %score% to display the document weight and %terms% to show how many hits each search term got.', 'relevanssi' ); /* phpcs:ignore WordPress.WP.I18n */ ?></p>
|
438 |
</td>
|
439 |
</tr>
|
440 |
</table>
|
readme.txt
CHANGED
@@ -2,10 +2,10 @@
|
|
2 |
Contributors: msaari
|
3 |
Donate link: https://www.relevanssi.com/buy-premium/
|
4 |
Tags: search, relevance, better search
|
5 |
-
Requires at least: 4.
|
6 |
-
Tested up to: 5.
|
7 |
Requires PHP: 5.6
|
8 |
-
Stable tag: 4.3.
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
@@ -29,6 +29,7 @@ Do note that using Relevanssi may require large amounts (hundreds of megabytes)
|
|
29 |
* Search comments, tags, categories and custom fields.
|
30 |
* Multisite friendly.
|
31 |
* bbPress support.
|
|
|
32 |
|
33 |
= Advanced features =
|
34 |
* Adjust the weighting for titles, tags and comments.
|
@@ -38,7 +39,7 @@ Do note that using Relevanssi may require large amounts (hundreds of megabytes)
|
|
38 |
* Index the contents of shortcodes.
|
39 |
* Google-style "Did you mean?" suggestions based on successful user searches.
|
40 |
* Support for [WPML multi-language plugin](http://wpml.org/) and [Polylang](https://wordpress.org/plugins/polylang/).
|
41 |
-
* Support for [s2member membership plugin](http://www.s2member.com/), [Members](https://wordpress.org/plugins/members/), [Groups](https://wordpress.org/plugins/groups/)
|
42 |
* Advanced filtering to help hacking the search results the way you want.
|
43 |
* Search result throttling to improve performance on large databases.
|
44 |
* Disable indexing of post content and post titles with a simple filter hook.
|
@@ -55,7 +56,8 @@ Do note that using Relevanssi may require large amounts (hundreds of megabytes)
|
|
55 |
* Let the user choose between AND and OR searches, use + and - operator (AND and NOT).
|
56 |
* Export and import settings.
|
57 |
* [WP CLI commands](https://www.relevanssi.com/user-manual/wp-cli/).
|
58 |
-
* Related posts.
|
|
|
59 |
|
60 |
= Relevanssi in Facebook =
|
61 |
You can find [Relevanssi in Facebook](https://www.facebook.com/relevanssi).
|
@@ -121,6 +123,8 @@ Thus, the weight of the word for a document increases the more often it appears
|
|
121 |
|
122 |
Each document database is full of useless words. All the little words that appear in just about every document are completely useless for information retrieval purposes. Basically, their inverted document frequency is really low, so they never have much power in matching. Also, removing those words helps to make the index smaller and searching faster.
|
123 |
|
|
|
|
|
124 |
== Thanks ==
|
125 |
* Cristian Damm for tag indexing, comment indexing, post/page exclusion and general helpfulness.
|
126 |
* Marcus Dalgren for UTF-8 fixing.
|
@@ -129,6 +133,18 @@ Each document database is full of useless words. All the little words that appea
|
|
129 |
* John Calahan for extensive 4.0 beta testing.
|
130 |
|
131 |
== Changelog ==
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
= 4.3.3 =
|
133 |
* New feature: New filter hook `relevanssi_indexing_adjust` can be used to stop Relevanssi from adjusting the number of posts indexed at once during the indexing.
|
134 |
* New feature: New filter hook `relevanssi_acf_field_value` filters ACF field values before they are indexed.
|
@@ -171,6 +187,9 @@ Each document database is full of useless words. All the little words that appea
|
|
171 |
* Deprecated: `relevanssi_get_term_taxonomy()` function is deprecated and will be removed at some point in the future.
|
172 |
|
173 |
== Upgrade notice ==
|
|
|
|
|
|
|
174 |
= 4.3.3 =
|
175 |
* Bug fixes and overall improvements.
|
176 |
|
2 |
Contributors: msaari
|
3 |
Donate link: https://www.relevanssi.com/buy-premium/
|
4 |
Tags: search, relevance, better search
|
5 |
+
Requires at least: 4.9
|
6 |
+
Tested up to: 5.3
|
7 |
Requires PHP: 5.6
|
8 |
+
Stable tag: 4.3.4
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
29 |
* Search comments, tags, categories and custom fields.
|
30 |
* Multisite friendly.
|
31 |
* bbPress support.
|
32 |
+
* Gutenberg friendly.
|
33 |
|
34 |
= Advanced features =
|
35 |
* Adjust the weighting for titles, tags and comments.
|
39 |
* Index the contents of shortcodes.
|
40 |
* Google-style "Did you mean?" suggestions based on successful user searches.
|
41 |
* Support for [WPML multi-language plugin](http://wpml.org/) and [Polylang](https://wordpress.org/plugins/polylang/).
|
42 |
+
* Support for [s2member membership plugin](http://www.s2member.com/), [Members](https://wordpress.org/plugins/members/), [Groups](https://wordpress.org/plugins/groups/), [Simple Membership](https://wordpress.org/plugins/simple-membership/) and other membership plugins.
|
43 |
* Advanced filtering to help hacking the search results the way you want.
|
44 |
* Search result throttling to improve performance on large databases.
|
45 |
* Disable indexing of post content and post titles with a simple filter hook.
|
56 |
* Let the user choose between AND and OR searches, use + and - operator (AND and NOT).
|
57 |
* Export and import settings.
|
58 |
* [WP CLI commands](https://www.relevanssi.com/user-manual/wp-cli/).
|
59 |
+
* [Related posts](https://www.relevanssi.com/knowledge-base/related-posts/).
|
60 |
+
* [Redirects for searches](https://www.relevanssi.com/user-manual/redirects/).
|
61 |
|
62 |
= Relevanssi in Facebook =
|
63 |
You can find [Relevanssi in Facebook](https://www.facebook.com/relevanssi).
|
123 |
|
124 |
Each document database is full of useless words. All the little words that appear in just about every document are completely useless for information retrieval purposes. Basically, their inverted document frequency is really low, so they never have much power in matching. Also, removing those words helps to make the index smaller and searching faster.
|
125 |
|
126 |
+
[](http://coderisk.com/wp/plugin/relevanssi/RIPS-XC1ekC4JKr)
|
127 |
+
|
128 |
== Thanks ==
|
129 |
* Cristian Damm for tag indexing, comment indexing, post/page exclusion and general helpfulness.
|
130 |
* Marcus Dalgren for UTF-8 fixing.
|
133 |
* John Calahan for extensive 4.0 beta testing.
|
134 |
|
135 |
== Changelog ==
|
136 |
+
= 4.3.4 =
|
137 |
+
* New feature: You can now give Gutenberg blocks a CSS class `relevanssi_noindex` to exclude them from being indexed. Relevanssi will not index Gutenberg blocks that have the class.
|
138 |
+
* New feature: Relevanssi automatically skips some custom fields from common plugins that only contain unnecessary metadata.
|
139 |
+
* New feature: The search results breakdown is added to the post objects and can be found in $post->relevanssi_hits. The data also includes new fields and the breakdown from the excerpt settings page can now show author, excerpt, custom field and MySQL column hits.
|
140 |
+
* New feature: Relevanssi can now index Ninja Tables table content. This is something of an experimental feature right now, feedback is welcome.
|
141 |
+
* New feature: New filter hook `relevanssi_indexing_query` filters the indexing query and is mostly interesting for debugging reasons.
|
142 |
+
* Minor fix: Deleted and trashed comment contents were not deindexed when the comment was removed. That has been corrected now.
|
143 |
+
* Minor fix: Phrase matching is now applied to attachments as well, including the attachments indexed for parent post.
|
144 |
+
* Minor fix: Phrase matching only looks at custom fields that are indexed by Relevanssi.
|
145 |
+
* Minor fix: Exact match bonus now uses the original query without synonyms added for the exact match check.
|
146 |
+
* Minor fix: Paid Membership Pro filtering is only applied to published posts to prevent drafts from showing up in the search results.
|
147 |
+
|
148 |
= 4.3.3 =
|
149 |
* New feature: New filter hook `relevanssi_indexing_adjust` can be used to stop Relevanssi from adjusting the number of posts indexed at once during the indexing.
|
150 |
* New feature: New filter hook `relevanssi_acf_field_value` filters ACF field values before they are indexed.
|
187 |
* Deprecated: `relevanssi_get_term_taxonomy()` function is deprecated and will be removed at some point in the future.
|
188 |
|
189 |
== Upgrade notice ==
|
190 |
+
= 4.3.4 =
|
191 |
+
* Comment indexing bug fix, compatibility improvements and minor bug fixes and improvements.
|
192 |
+
|
193 |
= 4.3.3 =
|
194 |
* Bug fixes and overall improvements.
|
195 |
|
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.3.
|
17 |
* Author: Mikko Saari
|
18 |
* Author URI: http://www.mikkosaari.fi/
|
19 |
* Text Domain: relevanssi
|
@@ -41,6 +41,13 @@ 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,7 +65,7 @@ $relevanssi_variables['database_version'] = 5;
|
|
58 |
$relevanssi_variables['file'] = __FILE__;
|
59 |
$relevanssi_variables['plugin_dir'] = plugin_dir_path( __FILE__ );
|
60 |
$relevanssi_variables['plugin_basename'] = plugin_basename( __FILE__ );
|
61 |
-
$relevanssi_variables['plugin_version'] = '4.3.
|
62 |
|
63 |
require_once 'lib/admin-ajax.php';
|
64 |
require_once 'lib/common.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.3.4
|
17 |
* Author: Mikko Saari
|
18 |
* Author URI: http://www.mikkosaari.fi/
|
19 |
* Text Domain: relevanssi
|
41 |
|
42 |
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'relevanssi_action_links' );
|
43 |
|
44 |
+
global $wp_version;
|
45 |
+
if ( version_compare( $wp_version, '5.1', '>=' ) ) {
|
46 |
+
add_action( 'wp_insert_site', 'relevanssi_new_blog', 10, 1 );
|
47 |
+
} else {
|
48 |
+
add_action( 'wpmu_new_blog', 'relevanssi_new_blog', 10, 1 );
|
49 |
+
}
|
50 |
+
|
51 |
global $relevanssi_variables;
|
52 |
global $wpdb;
|
53 |
|
65 |
$relevanssi_variables['file'] = __FILE__;
|
66 |
$relevanssi_variables['plugin_dir'] = plugin_dir_path( __FILE__ );
|
67 |
$relevanssi_variables['plugin_basename'] = plugin_basename( __FILE__ );
|
68 |
+
$relevanssi_variables['plugin_version'] = '4.3.4';
|
69 |
|
70 |
require_once 'lib/admin-ajax.php';
|
71 |
require_once 'lib/common.php';
|