Version Description
- New feature: There's now a "Debugging" tab in the Relevanssi settings, letting you see how the Relevanssi index sees posts. This is familiar to Premium users, but is now available in the free version as well.
- New feature: The SEO Framework plugin is now supported and posts set excluded from the search in SEO Framework settings will be excluded from the index.
- New feature: There's a new option, "Expand highlights". Enabling it makes Relevanssi expand partial-word highlights to cover the full word. This is useful when doing partial matching and when using a stemmer.
- New feature: New filter hook
relevanssi_excerpt_part
allows you to modify the excerpt parts before they are combined together. This doesn't do much in the free version. - New feature: Improved compatibility with Oxygen Builder. Relevanssi automatically indexes the Oxygen Builder content and cleans it up. New filter hooks
relevanssi_oxygen_section_filters
andrelevanssi_oxygen_section_content
allow easier filtering of Oxygen content to eg. remove unwanted sections. - Changed behaviour: The "Uncheck this for non-ASCII highlights" option has been removed. Highlights are now done in a slightly different way that should work in all cases, including for example Cyrillic text, thus this option is no longer necessary.
- Minor fix: Fixes phrase searching using non-US alphabet.
- Minor fix: Relevanssi would break admin searching for hierarchical post types. This is now fixed, Relevanssi won't do that anymore.
- Minor fix: Relevanssi indexing now survives better shortcodes that change the global
$post
. - Minor fix: Warnings about missing
relevanssi_update_counts
function are now removed. - Minor fix: Paid Membership Pro support now takes notice of the "filter queries" setting.
- Minor fix: OR logic didn't work correctly when two phrases both had the same word (for example "freedom of speech" and "free speech"). The search would always be an AND search in those cases. That has been fixed.
- Minor fix: Relevanssi no longer blocks the Pretty Links admin page search.
- Minor fix: The "Respect 'exclude_from_search'" setting did not work if no post type parameter was included in the search parameters.
- Minor fix: The category inclusion and exclusion setting checkboxes on the Searching tab didn't work. The setting was saved, but the checkboxes wouldn't appear.
Download this release
Release Info
Developer | msaari |
Plugin | Relevanssi – A Better Search |
Version | 4.9.0 |
Comparing to | |
See all releases |
Code changes from version 4.8.3 to 4.9.0
- lib/admin_scripts.js +3 -1
- lib/admin_styles.css +7 -0
- lib/class-relevanssi-taxonomy-walker.php +1 -1
- lib/common.php +245 -11
- lib/compatibility/oxygen.php +115 -0
- lib/compatibility/paidmembershippro.php +9 -5
- lib/compatibility/pretty-links.php +30 -0
- lib/compatibility/seoframework.php +54 -0
- lib/excerpts-highlights.php +201 -111
- lib/indexing.php +31 -20
- lib/init.php +12 -2
- lib/install.php +1 -1
- lib/interface.php +279 -209
- lib/search-query-restrictions.php +17 -12
- lib/search.php +2 -3
- lib/tabs/debugging-tab.php +49 -0
- lib/tabs/excerpts-tab.php +12 -7
- lib/uninstall.php +2 -1
- readme.txt +22 -2
- relevanssi.php +2 -2
lib/admin_scripts.js
CHANGED
@@ -126,8 +126,10 @@ jQuery(document).ready(function ($) {
|
|
126 |
!this.checked
|
127 |
)
|
128 |
$("#tr_excerpt_length").toggleClass("relevanssi_disabled", !this.checked)
|
|
|
129 |
$("#relevanssi_excerpt_length").attr("disabled", !this.checked)
|
130 |
$("#relevanssi_excerpt_type").attr("disabled", !this.checked)
|
|
|
131 |
$("#relevanssi_excerpt_allowable_tags").attr("disabled", !this.checked)
|
132 |
$("#relevanssi_excerpt_custom_fields").attr("disabled", !this.checked)
|
133 |
$("#relevanssi_highlight").attr("disabled", !this.checked)
|
@@ -138,9 +140,9 @@ jQuery(document).ready(function ($) {
|
|
138 |
$("#relevanssi_hilite_title").attr("disabled", !this.checked)
|
139 |
$("#relevanssi_highlight_docs").attr("disabled", !this.checked)
|
140 |
$("#relevanssi_highlight_comments").attr("disabled", !this.checked)
|
141 |
-
$("#relevanssi_word_boundaries").attr("disabled", !this.checked)
|
142 |
$("#relevanssi_show_matches").attr("disabled", !this.checked)
|
143 |
$("#relevanssi_show_matches_text").attr("disabled", !this.checked)
|
|
|
144 |
})
|
145 |
|
146 |
$("#relevanssi_searchblogs_all").click(function () {
|
126 |
!this.checked
|
127 |
)
|
128 |
$("#tr_excerpt_length").toggleClass("relevanssi_disabled", !this.checked)
|
129 |
+
$("#tr_max_excerpts").toggleClass("relevanssi_disabled", !this.checked)
|
130 |
$("#relevanssi_excerpt_length").attr("disabled", !this.checked)
|
131 |
$("#relevanssi_excerpt_type").attr("disabled", !this.checked)
|
132 |
+
$("#relevanssi_max_excerpts").attr("disabled", !this.checked)
|
133 |
$("#relevanssi_excerpt_allowable_tags").attr("disabled", !this.checked)
|
134 |
$("#relevanssi_excerpt_custom_fields").attr("disabled", !this.checked)
|
135 |
$("#relevanssi_highlight").attr("disabled", !this.checked)
|
140 |
$("#relevanssi_hilite_title").attr("disabled", !this.checked)
|
141 |
$("#relevanssi_highlight_docs").attr("disabled", !this.checked)
|
142 |
$("#relevanssi_highlight_comments").attr("disabled", !this.checked)
|
|
|
143 |
$("#relevanssi_show_matches").attr("disabled", !this.checked)
|
144 |
$("#relevanssi_show_matches_text").attr("disabled", !this.checked)
|
145 |
+
$("#relevanssi_expand_highlights").attr("disabled", !this.checked)
|
146 |
})
|
147 |
|
148 |
$("#relevanssi_searchblogs_all").click(function () {
|
lib/admin_styles.css
CHANGED
@@ -107,4 +107,11 @@ table.form-table table.widefat th {
|
|
107 |
|
108 |
#redirect_table td {
|
109 |
vertical-align: top;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
}
|
107 |
|
108 |
#redirect_table td {
|
109 |
vertical-align: top;
|
110 |
+
}
|
111 |
+
|
112 |
+
#relevanssi_sees_container {
|
113 |
+
width: 80%;
|
114 |
+
background: white;
|
115 |
+
padding: 5px 20px;
|
116 |
+
border: thin solid black;
|
117 |
}
|
lib/class-relevanssi-taxonomy-walker.php
CHANGED
@@ -66,7 +66,7 @@ class Relevanssi_Taxonomy_Walker extends Walker_Category_Checklist {
|
|
66 |
/** This filter is documented in wp-includes/category-template.php */
|
67 |
$output .= "\n<li id='{$taxonomy}-{$category->term_id}'$class>" .
|
68 |
'<label class="selectit"><input value="' . $category->term_id . '" type="checkbox" name="' . $name . '[]" id="in-' . $taxonomy . '-' . $category->term_id . '"' .
|
69 |
-
checked( in_array(
|
70 |
disabled( empty( $args['disabled'] ), false, false ) . ' /> ' .
|
71 |
esc_html( apply_filters( 'the_category', $category->name ) ) . '</label>';
|
72 |
}
|
66 |
/** This filter is documented in wp-includes/category-template.php */
|
67 |
$output .= "\n<li id='{$taxonomy}-{$category->term_id}'$class>" .
|
68 |
'<label class="selectit"><input value="' . $category->term_id . '" type="checkbox" name="' . $name . '[]" id="in-' . $taxonomy . '-' . $category->term_id . '"' .
|
69 |
+
checked( in_array( intval( $category->term_id ), $args['selected_cats'], true ), true, false ) .
|
70 |
disabled( empty( $args['disabled'] ), false, false ) . ' /> ' .
|
71 |
esc_html( apply_filters( 'the_category', $category->name ) ) . '</label>';
|
72 |
}
|
lib/common.php
CHANGED
@@ -509,7 +509,7 @@ function relevanssi_generate_phrase_queries( $phrases, $taxonomies, $custom_fiel
|
|
509 |
$queries = array();
|
510 |
$phrase = $wpdb->esc_like( $phrase );
|
511 |
$phrase = str_replace( array( '‘', '’', "'", '"', '”', '“', '“', '„', '´' ), '_', $phrase );
|
512 |
-
$phrase =
|
513 |
$phrase = esc_sql( $phrase );
|
514 |
|
515 |
$excerpt = '';
|
@@ -900,8 +900,9 @@ function relevanssi_prevent_default_request( $request, $query ) {
|
|
900 |
$admin_search_ok = false;
|
901 |
}
|
902 |
|
903 |
-
if ( $query->is_admin && '
|
904 |
-
// Relevanssi doesn't work on
|
|
|
905 |
$prevent = false;
|
906 |
$admin_search_ok = false;
|
907 |
}
|
@@ -1014,14 +1015,22 @@ function relevanssi_tokenize( $string, $remove_stops = true, $min_word_length =
|
|
1014 |
|
1015 |
if ( $accept ) {
|
1016 |
$token = relevanssi_mb_trim( $token );
|
1017 |
-
|
1018 |
-
|
1019 |
-
|
1020 |
-
|
1021 |
-
|
1022 |
-
|
1023 |
-
|
1024 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1025 |
}
|
1026 |
}
|
1027 |
|
@@ -2250,3 +2259,228 @@ function relevanssi_launch_ajax_action( $action, $payload_args = array() ) {
|
|
2250 |
$url = admin_url( 'admin-ajax.php' );
|
2251 |
return wp_remote_post( $url, $args );
|
2252 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
509 |
$queries = array();
|
510 |
$phrase = $wpdb->esc_like( $phrase );
|
511 |
$phrase = str_replace( array( '‘', '’', "'", '"', '”', '“', '“', '„', '´' ), '_', $phrase );
|
512 |
+
$phrase = htmlspecialchars( $phrase );
|
513 |
$phrase = esc_sql( $phrase );
|
514 |
|
515 |
$excerpt = '';
|
900 |
$admin_search_ok = false;
|
901 |
}
|
902 |
|
903 |
+
if ( $query->is_admin && isset( $query->query['fields'] ) && 'id=>parent' === $query->query['fields'] ) {
|
904 |
+
// Relevanssi doesn't work on hierarchical post type admin screens,
|
905 |
+
// so disable.
|
906 |
$prevent = false;
|
907 |
$admin_search_ok = false;
|
908 |
}
|
1015 |
|
1016 |
if ( $accept ) {
|
1017 |
$token = relevanssi_mb_trim( $token );
|
1018 |
+
|
1019 |
+
/**
|
1020 |
+
* This explode is done so that a stemmer can return both the
|
1021 |
+
* original term and the stemmed term and both can be indexed.
|
1022 |
+
*/
|
1023 |
+
$token_array = explode( ' ', $token );
|
1024 |
+
foreach ( $token_array as $token ) {
|
1025 |
+
if ( is_numeric( $token ) ) {
|
1026 |
+
// $token ends up as an array index, and numbers don't work there.
|
1027 |
+
$token = " $token";
|
1028 |
+
}
|
1029 |
+
if ( ! isset( $tokens[ $token ] ) ) {
|
1030 |
+
$tokens[ $token ] = 1;
|
1031 |
+
} else {
|
1032 |
+
$tokens[ $token ]++;
|
1033 |
+
}
|
1034 |
}
|
1035 |
}
|
1036 |
|
2259 |
$url = admin_url( 'admin-ajax.php' );
|
2260 |
return wp_remote_post( $url, $args );
|
2261 |
}
|
2262 |
+
|
2263 |
+
/**
|
2264 |
+
* Fetches the data and generates the HTML for the "How Relevanssi sees this
|
2265 |
+
* post".
|
2266 |
+
*
|
2267 |
+
* @param int $post_id The post ID.
|
2268 |
+
* @param boolean $display If false, add "display: none" style to the element.
|
2269 |
+
*
|
2270 |
+
* @return string The HTML code for the "How Relevanssi sees this post".
|
2271 |
+
*/
|
2272 |
+
function relevanssi_generate_how_relevanssi_sees( $post_id, $display = true ) {
|
2273 |
+
$style = '';
|
2274 |
+
if ( ! $display ) {
|
2275 |
+
$style = 'style="display: none"';
|
2276 |
+
}
|
2277 |
+
|
2278 |
+
$element = '<div id="relevanssi_sees_container" ' . $style . '>';
|
2279 |
+
|
2280 |
+
$data = relevanssi_fetch_sees_data( $post_id );
|
2281 |
+
|
2282 |
+
if ( empty( $data['terms_list'] ) && empty( $data['reason'] ) ) {
|
2283 |
+
$element .= '<p>'
|
2284 |
+
// Translators: %d is the post ID.
|
2285 |
+
. sprintf( __( 'Nothing found for post ID %d.', 'relevanssi' ), $post_id )
|
2286 |
+
. '</p>';
|
2287 |
+
$element .= '</div>';
|
2288 |
+
return $element;
|
2289 |
+
}
|
2290 |
+
|
2291 |
+
if ( ! empty( $data['reason'] ) ) {
|
2292 |
+
$element .= '<h3>' . esc_html__( 'Possible reasons this post is not indexed', 'relevanssi' ) . '</h3>';
|
2293 |
+
$element .= '<p>' . esc_html( $data['reason'] ) . '</p>';
|
2294 |
+
}
|
2295 |
+
if ( ! empty( $data['title'] ) ) {
|
2296 |
+
$element .= '<h3>' . esc_html__( 'Post title', 'relevanssi' ) . '</h3>';
|
2297 |
+
$element .= '<p>' . esc_html( $data['title'] ) . '</p>';
|
2298 |
+
}
|
2299 |
+
if ( ! empty( $data['content'] ) ) {
|
2300 |
+
$element .= '<h3>' . esc_html__( 'Post content', 'relevanssi' ) . '</h3>';
|
2301 |
+
$element .= '<p>' . esc_html( $data['content'] ) . '</p>';
|
2302 |
+
}
|
2303 |
+
if ( ! empty( $data['comment'] ) ) {
|
2304 |
+
$element .= '<h3>' . esc_html__( 'Comments', 'relevanssi' ) . '</h3>';
|
2305 |
+
$element .= '<p>' . esc_html( $data['comment'] ) . '</p>';
|
2306 |
+
}
|
2307 |
+
if ( ! empty( $data['tag'] ) ) {
|
2308 |
+
$element .= '<h3>' . esc_html__( 'Tags', 'relevanssi' ) . '</h3>';
|
2309 |
+
$element .= '<p>' . esc_html( $data['tag'] ) . '</p>';
|
2310 |
+
}
|
2311 |
+
if ( ! empty( $data['category'] ) ) {
|
2312 |
+
$element .= '<h3>' . esc_html__( 'Categories', 'relevanssi' ) . '</h3>';
|
2313 |
+
$element .= '<p>' . esc_html( $data['category'] ) . '</p>';
|
2314 |
+
}
|
2315 |
+
if ( ! empty( $data['taxonomy'] ) ) {
|
2316 |
+
$element .= '<h3>' . esc_html__( 'Other taxonomies', 'relevanssi' ) . '</h3>';
|
2317 |
+
$element .= '<p>' . esc_html( $data['taxonomy'] ) . '</p>';
|
2318 |
+
}
|
2319 |
+
if ( ! empty( $data['link'] ) ) {
|
2320 |
+
$element .= '<h3>' . esc_html__( 'Links', 'relevanssi' ) . '</h3>';
|
2321 |
+
$element .= '<p>' . esc_html( $data['link'] ) . '</p>';
|
2322 |
+
}
|
2323 |
+
if ( ! empty( $data['author'] ) ) {
|
2324 |
+
$element .= '<h3>' . esc_html__( 'Authors', 'relevanssi' ) . '</h3>';
|
2325 |
+
$element .= '<p>' . esc_html( $data['author'] ) . '</p>';
|
2326 |
+
}
|
2327 |
+
if ( ! empty( $data['excerpt'] ) ) {
|
2328 |
+
$element .= '<h3>' . esc_html__( 'Excerpt', 'relevanssi' ) . '</h3>';
|
2329 |
+
$element .= '<p>' . esc_html( $data['excerpt'] ) . '</p>';
|
2330 |
+
}
|
2331 |
+
if ( ! empty( $data['customfield'] ) ) {
|
2332 |
+
$element .= '<h3>' . esc_html__( 'Custom fields', 'relevanssi' ) . '</h3>';
|
2333 |
+
$element .= '<p>' . esc_html( $data['customfield'] ) . '</p>';
|
2334 |
+
}
|
2335 |
+
if ( ! empty( $data['mysql'] ) ) {
|
2336 |
+
$element .= '<h3>' . esc_html__( 'MySQL content', 'relevanssi' ) . '</h3>';
|
2337 |
+
$element .= '<p>' . esc_html( $data['mysql'] ) . '</p>';
|
2338 |
+
}
|
2339 |
+
$element .= '</div>';
|
2340 |
+
return $element;
|
2341 |
+
}
|
2342 |
+
|
2343 |
+
/**
|
2344 |
+
* Fetches the Relevanssi indexing data for a post.
|
2345 |
+
*
|
2346 |
+
* @param int $post_id The post ID.
|
2347 |
+
*
|
2348 |
+
* @global array $relevanssi_variables The Relevanssi global variables array,
|
2349 |
+
* used for the database table name.
|
2350 |
+
* @global object $wpdb The WordPress database interface.
|
2351 |
+
*
|
2352 |
+
* @return array The indexed terms for various parts of the post in an
|
2353 |
+
* associative array.
|
2354 |
+
*/
|
2355 |
+
function relevanssi_fetch_sees_data( $post_id ) {
|
2356 |
+
global $wpdb, $relevanssi_variables;
|
2357 |
+
|
2358 |
+
$terms_list = $wpdb->get_results(
|
2359 |
+
$wpdb->prepare(
|
2360 |
+
'SELECT * FROM ' . $relevanssi_variables['relevanssi_table'] . ' WHERE doc = %d', // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared
|
2361 |
+
$post_id
|
2362 |
+
),
|
2363 |
+
OBJECT
|
2364 |
+
);
|
2365 |
+
|
2366 |
+
$terms['content'] = array();
|
2367 |
+
$terms['title'] = array();
|
2368 |
+
$terms['comment'] = array();
|
2369 |
+
$terms['tag'] = array();
|
2370 |
+
$terms['link'] = array();
|
2371 |
+
$terms['author'] = array();
|
2372 |
+
$terms['category'] = array();
|
2373 |
+
$terms['excerpt'] = array();
|
2374 |
+
$terms['taxonomy'] = array();
|
2375 |
+
$terms['customfield'] = array();
|
2376 |
+
$terms['mysql'] = array();
|
2377 |
+
|
2378 |
+
foreach ( $terms_list as $row ) {
|
2379 |
+
if ( $row->content > 0 ) {
|
2380 |
+
$terms['content'][] = $row->term;
|
2381 |
+
}
|
2382 |
+
if ( $row->title > 0 ) {
|
2383 |
+
$terms['title'][] = $row->term;
|
2384 |
+
}
|
2385 |
+
if ( $row->comment > 0 ) {
|
2386 |
+
$terms['comment'][] = $row->term;
|
2387 |
+
}
|
2388 |
+
if ( $row->tag > 0 ) {
|
2389 |
+
$terms['tag'][] = $row->term;
|
2390 |
+
}
|
2391 |
+
if ( $row->link > 0 ) {
|
2392 |
+
$terms['link'][] = $row->term;
|
2393 |
+
}
|
2394 |
+
if ( $row->author > 0 ) {
|
2395 |
+
$terms['author'][] = $row->term;
|
2396 |
+
}
|
2397 |
+
if ( $row->category > 0 ) {
|
2398 |
+
$terms['category'][] = $row->term;
|
2399 |
+
}
|
2400 |
+
if ( $row->excerpt > 0 ) {
|
2401 |
+
$terms['excerpt'][] = $row->term;
|
2402 |
+
}
|
2403 |
+
if ( $row->taxonomy > 0 ) {
|
2404 |
+
$terms['taxonomy'][] = $row->term;
|
2405 |
+
}
|
2406 |
+
if ( $row->customfield > 0 ) {
|
2407 |
+
$terms['customfield'][] = $row->term;
|
2408 |
+
}
|
2409 |
+
if ( $row->mysqlcolumn > 0 ) {
|
2410 |
+
$terms['mysql'][] = $row->term;
|
2411 |
+
}
|
2412 |
+
}
|
2413 |
+
|
2414 |
+
$reason = get_post_meta( $post_id, '_relevanssi_noindex_reason', true );
|
2415 |
+
|
2416 |
+
return array(
|
2417 |
+
'content' => implode( ' ', $terms['content'] ),
|
2418 |
+
'title' => implode( ' ', $terms['title'] ),
|
2419 |
+
'comment' => implode( ' ', $terms['comment'] ),
|
2420 |
+
'tag' => implode( ' ', $terms['tag'] ),
|
2421 |
+
'link' => implode( ' ', $terms['link'] ),
|
2422 |
+
'author' => implode( ' ', $terms['author'] ),
|
2423 |
+
'category' => implode( ' ', $terms['category'] ),
|
2424 |
+
'excerpt' => implode( ' ', $terms['excerpt'] ),
|
2425 |
+
'taxonomy' => implode( ' ', $terms['taxonomy'] ),
|
2426 |
+
'customfield' => implode( ' ', $terms['customfield'] ),
|
2427 |
+
'mysql' => implode( ' ', $terms['mysql'] ),
|
2428 |
+
'reason' => $reason,
|
2429 |
+
'terms_list' => $terms_list,
|
2430 |
+
);
|
2431 |
+
}
|
2432 |
+
|
2433 |
+
/**
|
2434 |
+
* Removes quotes from array keys. Does not keep array values.
|
2435 |
+
*
|
2436 |
+
* Used to remove phrase quotes from search term array, which have the format
|
2437 |
+
* of (term => hits). The number of hits is not needed, so this function
|
2438 |
+
* discards it as a side effect.
|
2439 |
+
*
|
2440 |
+
* @param array $array An array to process.
|
2441 |
+
*
|
2442 |
+
* @return array The same array with quotes removed from the keys.
|
2443 |
+
*/
|
2444 |
+
function relevanssi_remove_quotes_from_array_keys( $array ) {
|
2445 |
+
$array = array_keys( $array );
|
2446 |
+
array_walk(
|
2447 |
+
$array,
|
2448 |
+
function( &$key ) {
|
2449 |
+
$key = relevanssi_remove_quotes( $key );
|
2450 |
+
}
|
2451 |
+
);
|
2452 |
+
return array_flip( $array );
|
2453 |
+
}
|
2454 |
+
|
2455 |
+
/**
|
2456 |
+
* Removes quotes (", ”, “) from a string.
|
2457 |
+
*
|
2458 |
+
* @param string $string The string to clean.
|
2459 |
+
*
|
2460 |
+
* @return string The cleaned string.
|
2461 |
+
*/
|
2462 |
+
function relevanssi_remove_quotes( $string ) {
|
2463 |
+
return str_replace( array( '”', '“', '"' ), '', $string );
|
2464 |
+
}
|
2465 |
+
|
2466 |
+
/**
|
2467 |
+
* Strips tags from contents, keeping the allowed tags.
|
2468 |
+
*
|
2469 |
+
* The allowable tags are read from the relevanssi_excerpt_allowable_tags
|
2470 |
+
* option. Spaces are added between tags before removing the tags, so that
|
2471 |
+
* words don't get stuck together. The function also remove invisible content.
|
2472 |
+
*
|
2473 |
+
* @see relevanssi_strip_invisibles
|
2474 |
+
*
|
2475 |
+
* @param string $content The content.
|
2476 |
+
*
|
2477 |
+
* @return string The content without tags.
|
2478 |
+
*/
|
2479 |
+
function relevanssi_strip_tags( $content ) {
|
2480 |
+
$content = relevanssi_strip_invisibles( $content );
|
2481 |
+
$content = preg_replace( '/(<\/[^>]+?>)(<[^>\/][^>]*?>)/', '$1 $2', $content );
|
2482 |
+
return strip_tags(
|
2483 |
+
$content,
|
2484 |
+
get_option( 'relevanssi_excerpt_allowable_tags', '' )
|
2485 |
+
);
|
2486 |
+
}
|
lib/compatibility/oxygen.php
ADDED
@@ -0,0 +1,115 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* /lib/compatibility/oxygen.php
|
4 |
+
*
|
5 |
+
* Oxygen Builder 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_custom_field_value', 'relevanssi_oxygen_compatibility', 10, 3 );
|
14 |
+
add_filter( 'relevanssi_index_custom_fields', 'relevanssi_add_oxygen' );
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Cleans up the Oxygen Builder custom field for Relevanssi consumption.
|
18 |
+
*
|
19 |
+
* Splits up the big custom field content from ct_builder_shortcodes into
|
20 |
+
* sections ([ct_section] tags). Each section can be processed with filters
|
21 |
+
* defined with `relevanssi_oxygen_section_filters`, for example to remove
|
22 |
+
* sections based on their "nicename" or "ct_category" values. After that the
|
23 |
+
* section is passed through the `relevanssi_oxygen_section_content` filter.
|
24 |
+
* Finally all shortcode tags are removed, leaving just the content.
|
25 |
+
*
|
26 |
+
* @param array $value An array of custom field values.
|
27 |
+
* @param string $field The name of the custom field. This function only looks
|
28 |
+
* at `ct_builder_shortcodes` fields.
|
29 |
+
* @param int $post_id The post ID.
|
30 |
+
*
|
31 |
+
* @return array|null An array of custom field values, null if no value exists.
|
32 |
+
*/
|
33 |
+
function relevanssi_oxygen_compatibility( $value, $field, $post_id ) {
|
34 |
+
if ( 'ct_builder_shortcodes' === $field ) {
|
35 |
+
if ( empty( $value ) ) {
|
36 |
+
return null;
|
37 |
+
}
|
38 |
+
|
39 |
+
$content_tags = explode( '[ct_section', $value[0] );
|
40 |
+
$page_content = '';
|
41 |
+
foreach ( $content_tags as $content ) {
|
42 |
+
if ( empty( $content ) ) {
|
43 |
+
continue;
|
44 |
+
}
|
45 |
+
$content = '[ct_section' . $content;
|
46 |
+
/**
|
47 |
+
* Allows defining filters to remove Oxygen Builder sections.
|
48 |
+
*
|
49 |
+
* The filters are arrays, with the array key defining the key and
|
50 |
+
* the value defining the value. If the filter array is
|
51 |
+
* array( 'nicename' => 'Hero BG' ), Relevanssi will look for
|
52 |
+
* sections that have "nicename":"Hero BG" in their settings and
|
53 |
+
* will remove those.
|
54 |
+
*
|
55 |
+
* @param array An array of filtering rules, defaults empty.
|
56 |
+
*
|
57 |
+
* @return array
|
58 |
+
*/
|
59 |
+
$filters = apply_filters(
|
60 |
+
'relevanssi_oxygen_section_filters',
|
61 |
+
array()
|
62 |
+
);
|
63 |
+
array_walk(
|
64 |
+
$filters,
|
65 |
+
function( $filter ) use ( &$content ) {
|
66 |
+
foreach ( $filter as $key => $value ) {
|
67 |
+
if ( stristr( $content, '"' . $key . '":"' . $value . '"' ) !== false ) {
|
68 |
+
$content = '';
|
69 |
+
}
|
70 |
+
}
|
71 |
+
}
|
72 |
+
);
|
73 |
+
|
74 |
+
$content = preg_replace(
|
75 |
+
'/\[.*?\]/',
|
76 |
+
' ',
|
77 |
+
/**
|
78 |
+
* Filters the Oxygen Builder section content before the
|
79 |
+
* shortcode tags are removed.
|
80 |
+
*
|
81 |
+
* @param string $content The single section content.
|
82 |
+
* @param itn $post_id The post ID.
|
83 |
+
*
|
84 |
+
* @return string
|
85 |
+
*/
|
86 |
+
apply_filters(
|
87 |
+
'relevanssi_oxygen_section_content',
|
88 |
+
$content,
|
89 |
+
$post_id
|
90 |
+
)
|
91 |
+
);
|
92 |
+
|
93 |
+
$page_content .= $content;
|
94 |
+
}
|
95 |
+
|
96 |
+
$value[0] = $page_content;
|
97 |
+
}
|
98 |
+
return $value;
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Adds the `ct_builder_shortcodes` to the list of indexed custom fields.
|
103 |
+
*
|
104 |
+
* @param array|boolean $fields An array of custom fields to index, or false.
|
105 |
+
*
|
106 |
+
* @return array An array of custom fields, including `ct_builder_shortcodes`.
|
107 |
+
*/
|
108 |
+
function relevanssi_add_oxygen( $fields ) {
|
109 |
+
if ( ! is_array( $fields ) ) {
|
110 |
+
$fields = array();
|
111 |
+
}
|
112 |
+
$fields[] = 'ct_builder_shortcodes';
|
113 |
+
return $fields;
|
114 |
+
}
|
115 |
+
|
lib/compatibility/paidmembershippro.php
CHANGED
@@ -22,12 +22,16 @@ add_filter( 'relevanssi_post_ok', 'relevanssi_paidmembershippro_compatibility',
|
|
22 |
* otherwise false.
|
23 |
*/
|
24 |
function relevanssi_paidmembershippro_compatibility( $post_ok, $post_id ) {
|
25 |
-
$
|
26 |
|
27 |
-
if (
|
28 |
-
|
29 |
-
|
30 |
-
|
|
|
|
|
|
|
|
|
31 |
}
|
32 |
|
33 |
return $post_ok;
|
22 |
* otherwise false.
|
23 |
*/
|
24 |
function relevanssi_paidmembershippro_compatibility( $post_ok, $post_id ) {
|
25 |
+
$pmpro_active = get_option( 'pmpro_filterqueries', 0 );
|
26 |
|
27 |
+
if ( $pmpro_active ) {
|
28 |
+
$status = relevanssi_get_post_status( $post_id );
|
29 |
+
|
30 |
+
if ( 'publish' === $status ) {
|
31 |
+
// Only apply to published posts, don't apply to drafts.
|
32 |
+
$current_user = wp_get_current_user();
|
33 |
+
$post_ok = pmpro_has_membership_access( $post_id, $current_user->ID );
|
34 |
+
}
|
35 |
}
|
36 |
|
37 |
return $post_ok;
|
lib/compatibility/pretty-links.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* /lib/compatibility/pretty-links.php
|
4 |
+
*
|
5 |
+
* Pretty Links 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_admin_search_ok', 'relevanssi_pretty_links_ok', 10, 2 );
|
14 |
+
add_filter( 'relevanssi_prevent_default_request', 'relevanssi_pretty_links_ok', 10, 2 );
|
15 |
+
add_filter( 'relevanssi_search_ok', 'relevanssi_pretty_links_ok', 10, 2 );
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Returns false if the query post type is set to 'pretty-link'.
|
19 |
+
*
|
20 |
+
* @param boolean $ok Whether to allow the query.
|
21 |
+
* @param WP_Query $query The WP_Query object.
|
22 |
+
*
|
23 |
+
* @return boolean False if this is a Pretty Links query.
|
24 |
+
*/
|
25 |
+
function relevanssi_pretty_links_ok( $ok, $query ) {
|
26 |
+
if ( 'pretty-link' === $query->query['post_type'] ) {
|
27 |
+
$ok = false;
|
28 |
+
}
|
29 |
+
return $ok;
|
30 |
+
}
|
lib/compatibility/seoframework.php
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* /lib/compatibility/seoframework.php
|
4 |
+
*
|
5 |
+
* The SEO Framework noindex filtering function.
|
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_do_not_index', 'relevanssi_seoframework_noindex', 10, 2 );
|
14 |
+
add_filter( 'relevanssi_indexing_restriction', 'relevanssi_seoframework_exclude' );
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Blocks indexing of posts marked "Exclude this page from all search queries
|
18 |
+
* on this site." in the SEO Framework settings.
|
19 |
+
*
|
20 |
+
* Attaches to the 'relevanssi_do_not_index' filter hook.
|
21 |
+
*
|
22 |
+
* @param boolean $do_not_index True, if the post shouldn't be indexed.
|
23 |
+
* @param integer $post_id The post ID number.
|
24 |
+
*
|
25 |
+
* @return string|boolean If the post shouldn't be indexed, this returns
|
26 |
+
* 'SEO Framework'. The value may also be a boolean.
|
27 |
+
*/
|
28 |
+
function relevanssi_seoframework_noindex( $do_not_index, $post_id ) {
|
29 |
+
$noindex = get_post_meta( $post_id, 'exclude_local_search', true );
|
30 |
+
if ( '1' === $noindex ) {
|
31 |
+
$do_not_index = 'SEO Framework';
|
32 |
+
}
|
33 |
+
return $do_not_index;
|
34 |
+
}
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Excludes the "noindex" posts from Relevanssi indexing.
|
38 |
+
*
|
39 |
+
* Adds a MySQL query restriction that blocks posts that have the SEO Framework
|
40 |
+
* "Exclude this page from all search queries on this site" setting set to "1"
|
41 |
+
* from indexing.
|
42 |
+
*
|
43 |
+
* @param array $restriction An array with two values: 'mysql' for the MySQL
|
44 |
+
* query restriction to modify, 'reason' for the reason of restriction.
|
45 |
+
*/
|
46 |
+
function relevanssi_seoframework_exclude( $restriction ) {
|
47 |
+
global $wpdb;
|
48 |
+
|
49 |
+
$restriction['mysql'] .= " AND post.ID NOT IN (SELECT post_id FROM
|
50 |
+
$wpdb->postmeta WHERE meta_key = 'exclude_local_search'
|
51 |
+
AND meta_value = '1' ) ";
|
52 |
+
$restriction['reason'] .= ' SEO Framework';
|
53 |
+
return $restriction;
|
54 |
+
}
|
lib/excerpts-highlights.php
CHANGED
@@ -154,15 +154,7 @@ function relevanssi_do_excerpt( $t_post, $query, $excerpt_length = null, $excerp
|
|
154 |
* @param string $query The search query.
|
155 |
*/
|
156 |
$content = apply_filters( 'relevanssi_excerpt_content', $content, $post, $query );
|
157 |
-
|
158 |
-
// Removes <script>, <embed> &c with content.
|
159 |
-
$content = relevanssi_strip_invisibles( $content );
|
160 |
-
|
161 |
-
// Add spaces between tags to avoid getting words stuck together.
|
162 |
-
$content = preg_replace( '/(<\/[^>]+?>)(<[^>\/][^>]*?>)/', '$1 $2', $content );
|
163 |
-
|
164 |
-
// This removes the tags, but leaves the content.
|
165 |
-
$content = strip_tags( $content, get_option( 'relevanssi_excerpt_allowable_tags', '' ) );
|
166 |
|
167 |
// Replace linefeeds and carriage returns with spaces.
|
168 |
$content = preg_replace( "/\n\r|\r\n|\n|\r/", ' ', $content );
|
@@ -172,63 +164,72 @@ function relevanssi_do_excerpt( $t_post, $query, $excerpt_length = null, $excerp
|
|
172 |
}
|
173 |
|
174 |
// Find the appropriate spot from the post.
|
175 |
-
$
|
|
|
|
|
|
|
176 |
|
|
|
177 |
if ( 'none' !== get_option( 'relevanssi_index_comments' ) ) {
|
178 |
-
|
179 |
-
$comment_content = relevanssi_get_comments( $post->ID );
|
180 |
-
$comment_content = preg_replace( '/(<\/[^>]+?>)(<[^>\/][^>]*?>)/', '$1 $2', $comment_content );
|
181 |
-
$comment_content = strip_tags( $comment_content, get_option( 'relevanssi_excerpt_allowable_tags', '' ) );
|
182 |
if ( ! empty( $comment_content ) ) {
|
183 |
-
$comment_excerpts =
|
184 |
$comment_content,
|
185 |
$terms,
|
186 |
$query,
|
187 |
$excerpt_length,
|
188 |
$excerpt_type
|
189 |
);
|
190 |
-
if (
|
191 |
-
|
192 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
}
|
194 |
}
|
195 |
}
|
196 |
|
|
|
197 |
if ( 'off' !== get_option( 'relevanssi_index_excerpt' ) ) {
|
198 |
-
$excerpt_content = $post->post_excerpt;
|
199 |
-
$excerpt_content = strip_tags( $excerpt_content, get_option( 'relevanssi_excerpt_allowable_tags', '' ) );
|
200 |
-
|
201 |
if ( ! empty( $excerpt_content ) ) {
|
202 |
-
$excerpt_excerpts =
|
203 |
$excerpt_content,
|
204 |
$terms,
|
205 |
$query,
|
206 |
$excerpt_length,
|
207 |
$excerpt_type
|
208 |
);
|
209 |
-
if (
|
210 |
-
|
211 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
212 |
}
|
213 |
}
|
214 |
}
|
215 |
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
*
|
224 |
-
* @param string $excerpt The excerpt.
|
225 |
-
* @param int $post->ID The post ID.
|
226 |
-
*/
|
227 |
-
$excerpt = apply_filters( 'relevanssi_excerpt', $excerpt, $post->ID );
|
228 |
-
|
229 |
-
$whole_post_excerpted = false;
|
230 |
-
if ( $excerpt === $post->post_content ) {
|
231 |
-
$whole_post_excerpted = true;
|
232 |
}
|
233 |
|
234 |
/**
|
@@ -236,43 +237,58 @@ function relevanssi_do_excerpt( $t_post, $query, $excerpt_length = null, $excerp
|
|
236 |
*
|
237 |
* @param string $ellipsis Default '...'.
|
238 |
*/
|
239 |
-
$ellipsis
|
240 |
-
|
241 |
$highlight = get_option( 'relevanssi_highlight' );
|
242 |
-
if ( 'none' !== $highlight ) {
|
243 |
-
if ( ! is_admin() || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
|
244 |
-
$excerpt = relevanssi_highlight_terms( $excerpt, $query );
|
245 |
-
}
|
246 |
-
}
|
247 |
|
248 |
-
$
|
249 |
|
250 |
-
$
|
251 |
-
|
252 |
-
if (
|
253 |
-
$
|
254 |
}
|
255 |
|
256 |
-
if (
|
257 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
258 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
259 |
}
|
260 |
|
261 |
if ( null !== $old_global_post ) {
|
262 |
$post = $old_global_post; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
263 |
}
|
264 |
|
265 |
-
return $
|
266 |
}
|
267 |
|
268 |
/**
|
269 |
* Creates an excerpt from content.
|
270 |
*
|
271 |
-
*
|
272 |
-
* the
|
273 |
-
*
|
274 |
-
*
|
275 |
-
*
|
|
|
276 |
*
|
277 |
* @param string $content The content.
|
278 |
* @param array $terms The search terms, tokenized.
|
@@ -284,13 +300,49 @@ function relevanssi_do_excerpt( $t_post, $query, $excerpt_length = null, $excerp
|
|
284 |
* element 2 is true, if the excerpt is from the start of the content.
|
285 |
*/
|
286 |
function relevanssi_create_excerpt( $content, $terms, $query, $excerpt_length = 30, $excerpt_type = 'words' ) {
|
287 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
288 |
|
289 |
-
$excerpt =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
290 |
$content = ' ' . preg_replace( '/\s+/u', ' ', $content );
|
291 |
$content = html_entity_decode( $content );
|
292 |
// Finds all the phrases in the query.
|
293 |
$phrases = relevanssi_extract_phrases( stripslashes( $query ) );
|
|
|
294 |
|
295 |
/**
|
296 |
* This process generates an array of terms, which has single terms and all the
|
@@ -313,27 +365,48 @@ function relevanssi_create_excerpt( $content, $terms, $query, $excerpt_length =
|
|
313 |
// Sort the longest search terms first, because those are generally more significant.
|
314 |
uksort( $terms, 'relevanssi_strlen_sort' );
|
315 |
|
316 |
-
$
|
|
|
317 |
if ( 'chars' === $excerpt_type ) {
|
318 |
$prev_count = floor( $excerpt_length / 6 );
|
319 |
|
320 |
-
list( $
|
321 |
relevanssi_extract_relevant(
|
322 |
array_keys( $terms ),
|
323 |
$content,
|
324 |
$excerpt_length + 1,
|
325 |
$prev_count
|
326 |
);
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
$content,
|
332 |
-
$excerpt_length
|
333 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
334 |
}
|
335 |
|
336 |
-
return
|
337 |
}
|
338 |
|
339 |
/**
|
@@ -437,7 +510,7 @@ function relevanssi_highlight_terms( $content, $query, $in_docs = false ) {
|
|
437 |
return $content;
|
438 |
}
|
439 |
|
440 |
-
$start_emp_token = '**{
|
441 |
$end_emp_token = ']}**';
|
442 |
|
443 |
if ( function_exists( 'mb_internal_encoding' ) ) {
|
@@ -513,12 +586,8 @@ function relevanssi_highlight_terms( $content, $query, $in_docs = false ) {
|
|
513 |
|
514 |
usort( $terms, 'relevanssi_strlen_sort' );
|
515 |
|
516 |
-
$word_boundaries_available = false;
|
517 |
-
if ( 'on' === get_option( 'relevanssi_word_boundaries', 'off' ) ) {
|
518 |
-
$word_boundaries_available = true;
|
519 |
-
}
|
520 |
-
|
521 |
$content = html_entity_decode( $content, ENT_QUOTES, 'UTF-8' );
|
|
|
522 |
|
523 |
foreach ( $terms as $term ) {
|
524 |
$pr_term = preg_quote( $term, '/' );
|
@@ -531,24 +600,56 @@ function relevanssi_highlight_terms( $content, $query, $in_docs = false ) {
|
|
531 |
$pr_term
|
532 |
);
|
533 |
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
}
|
539 |
-
$
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
);
|
|
|
|
|
|
|
|
|
|
|
544 |
} else {
|
545 |
-
$
|
546 |
-
"/($pr_term)/iu",
|
547 |
-
$start_emp_token . '\\1' . $end_emp_token,
|
548 |
-
$content
|
549 |
-
);
|
550 |
}
|
551 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
552 |
if ( preg_match_all( '/<.*>/U', $content, $matches ) > 0 ) {
|
553 |
// Remove highlights from inside HTML tags.
|
554 |
foreach ( $matches as $match ) {
|
@@ -870,11 +971,6 @@ function relevanssi_count_matches( $words, $complete_text ) {
|
|
870 |
$lowercase_text = relevanssi_strtolower( $complete_text, 'UTF-8' );
|
871 |
$text = '';
|
872 |
|
873 |
-
$word_boundaries_available = false;
|
874 |
-
if ( 'on' === get_option( 'relevanssi_word_boundaries', 'off' ) ) {
|
875 |
-
$word_boundaries_available = true;
|
876 |
-
}
|
877 |
-
|
878 |
$count_words = count( $words );
|
879 |
for ( $t = 0; $t < $count_words; $t++ ) {
|
880 |
$word_slice = relevanssi_strtolower(
|
@@ -893,15 +989,12 @@ function relevanssi_count_matches( $words, $complete_text ) {
|
|
893 |
$word_slice
|
894 |
);
|
895 |
|
896 |
-
if (
|
897 |
-
|
898 |
-
$regex = "/\b$word_slice|$word_slice\b/";
|
899 |
-
} else {
|
900 |
-
$regex = "/\b$word_slice\b/";
|
901 |
-
}
|
902 |
} else {
|
903 |
-
$regex = "
|
904 |
}
|
|
|
905 |
$lines = preg_split( $regex, $lowercase_text );
|
906 |
if ( $lines && count( $lines ) > 1 ) {
|
907 |
$count_lines = count( $lines );
|
@@ -1010,10 +1103,7 @@ function relevanssi_extract_relevant( $words, $fulltext, $excerpt_length = 300,
|
|
1010 |
$startpos -= ( $text_length - $startpos ) / 2;
|
1011 |
}
|
1012 |
|
1013 |
-
$substr = 'substr';
|
1014 |
-
if ( function_exists( 'mb_substr' ) ) {
|
1015 |
-
$substr = 'mb_substr';
|
1016 |
-
}
|
1017 |
|
1018 |
$excerpt = call_user_func( $substr, $fulltext, $startpos, $excerpt_length );
|
1019 |
|
@@ -1106,7 +1196,7 @@ function relevanssi_extract_relevant_words( $terms, $content, $excerpt_length =
|
|
1106 |
$start = true;
|
1107 |
}
|
1108 |
|
1109 |
-
return array( $excerpt, $best_excerpt_term_hits, $start );
|
1110 |
}
|
1111 |
|
1112 |
/**
|
@@ -1129,7 +1219,7 @@ function relevanssi_add_accent_variations( $word ) {
|
|
1129 |
'relevanssi_accents_replacement_arrays',
|
1130 |
array(
|
1131 |
'from' => array( 'a', 'c', 'e', 'i', 'o', 'u', 'n' ),
|
1132 |
-
'to' => array( '(a|á|à|â)', '(c|ç)', '(e|é|è|ê|ë)', '(i|í|ì|î|ï)', '(o|ó|ò|ô|õ)', '(u|ú|ù|ü|û)', '(n|ñ)' ),
|
1133 |
'from_re' => array( "/(s)('|’)?$/", "/[^\(\|]('|’)/" ),
|
1134 |
'to_re' => array( "(('|’)?\\1|\\1('|’)?)", "?('|’)?" ),
|
1135 |
)
|
154 |
* @param string $query The search query.
|
155 |
*/
|
156 |
$content = apply_filters( 'relevanssi_excerpt_content', $content, $post, $query );
|
157 |
+
$content = relevanssi_strip_tags( $content );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
158 |
|
159 |
// Replace linefeeds and carriage returns with spaces.
|
160 |
$content = preg_replace( "/\n\r|\r\n|\n|\r/", ' ', $content );
|
164 |
}
|
165 |
|
166 |
// Find the appropriate spot from the post.
|
167 |
+
$excerpts = relevanssi_create_excerpts( $content, $terms, $query, $excerpt_length, $excerpt_type );
|
168 |
+
if ( function_exists( 'relevanssi_add_source_to_excerpts' ) ) {
|
169 |
+
relevanssi_add_source_to_excerpts( $excerpts, 'content' );
|
170 |
+
}
|
171 |
|
172 |
+
$comment_excerpts = array();
|
173 |
if ( 'none' !== get_option( 'relevanssi_index_comments' ) ) {
|
174 |
+
$comment_content = relevanssi_strip_tags( relevanssi_get_comments( $post->ID ) );
|
|
|
|
|
|
|
175 |
if ( ! empty( $comment_content ) ) {
|
176 |
+
$comment_excerpts = relevanssi_create_excerpts(
|
177 |
$comment_content,
|
178 |
$terms,
|
179 |
$query,
|
180 |
$excerpt_length,
|
181 |
$excerpt_type
|
182 |
);
|
183 |
+
if ( function_exists( 'relevanssi_add_source_to_excerpts' ) ) {
|
184 |
+
relevanssi_add_source_to_excerpts( $comment_excerpts, 'comments' );
|
185 |
+
$comment_excerpts = array_filter(
|
186 |
+
$comment_excerpts,
|
187 |
+
function( $excerpt ) {
|
188 |
+
return $excerpt['hits'];
|
189 |
+
}
|
190 |
+
);
|
191 |
+
} elseif ( is_array( $comment_excerpts ) ) {
|
192 |
+
if ( $comment_excerpts[0]['hits'] > $excerpts[0]['hits'] ) {
|
193 |
+
$excerpts = $comment_excerpts;
|
194 |
+
}
|
195 |
}
|
196 |
}
|
197 |
}
|
198 |
|
199 |
+
$excerpt_excerpts = array();
|
200 |
if ( 'off' !== get_option( 'relevanssi_index_excerpt' ) ) {
|
201 |
+
$excerpt_content = relevanssi_strip_tags( $post->post_excerpt );
|
|
|
|
|
202 |
if ( ! empty( $excerpt_content ) ) {
|
203 |
+
$excerpt_excerpts = relevanssi_create_excerpts(
|
204 |
$excerpt_content,
|
205 |
$terms,
|
206 |
$query,
|
207 |
$excerpt_length,
|
208 |
$excerpt_type
|
209 |
);
|
210 |
+
if ( function_exists( 'relevanssi_add_source_to_excerpts' ) ) {
|
211 |
+
relevanssi_add_source_to_excerpts( $excerpt_excerpts, 'excerpt' );
|
212 |
+
$excerpt_excerpts = array_filter(
|
213 |
+
$excerpt_excerpts,
|
214 |
+
function( $excerpt ) {
|
215 |
+
return $excerpt['hits'];
|
216 |
+
}
|
217 |
+
);
|
218 |
+
} elseif ( is_array( $excerpt_excerpts ) ) {
|
219 |
+
if ( $excerpt_excerpts[0]['hits'] > $excerpts[0]['hits'] ) {
|
220 |
+
$excerpts = $excerpt_excerpts;
|
221 |
+
}
|
222 |
}
|
223 |
}
|
224 |
}
|
225 |
|
226 |
+
if ( function_exists( 'relevanssi_combine_excerpts' ) ) {
|
227 |
+
$excerpts = relevanssi_combine_excerpts(
|
228 |
+
$post->ID,
|
229 |
+
$excerpts,
|
230 |
+
$comment_excerpts,
|
231 |
+
$excerpt_excerpts
|
232 |
+
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
233 |
}
|
234 |
|
235 |
/**
|
237 |
*
|
238 |
* @param string $ellipsis Default '...'.
|
239 |
*/
|
240 |
+
$ellipsis = apply_filters( 'relevanssi_ellipsis', '...' );
|
|
|
241 |
$highlight = get_option( 'relevanssi_highlight' );
|
|
|
|
|
|
|
|
|
|
|
242 |
|
243 |
+
$excerpt_text = '';
|
244 |
|
245 |
+
foreach ( $excerpts as $excerpt ) {
|
246 |
+
$whole_post_excerpted = false;
|
247 |
+
if ( $excerpt['text'] === $post->post_content ) {
|
248 |
+
$whole_post_excerpted = true;
|
249 |
}
|
250 |
|
251 |
+
if ( 'none' !== $highlight ) {
|
252 |
+
if ( ! is_admin() || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
|
253 |
+
$excerpt['text'] = relevanssi_highlight_terms( $excerpt['text'], $query );
|
254 |
+
}
|
255 |
+
}
|
256 |
+
|
257 |
+
$excerpt['text'] = relevanssi_close_tags( $excerpt['text'] );
|
258 |
+
|
259 |
+
if ( ! $whole_post_excerpted ) {
|
260 |
+
if ( ! $excerpt['start'] && ! empty( $excerpt['text'] ) ) {
|
261 |
+
$excerpt['text'] = $ellipsis . $excerpt['text'];
|
262 |
+
}
|
263 |
+
|
264 |
+
if ( ! empty( $excerpt['text'] ) ) {
|
265 |
+
$excerpt['text'] = $excerpt['text'] . $ellipsis;
|
266 |
+
}
|
267 |
}
|
268 |
+
|
269 |
+
$excerpt_text .= apply_filters(
|
270 |
+
'relevanssi_excerpt_part',
|
271 |
+
'<span class="excerpt_part">' . $excerpt['text'] . '</span>',
|
272 |
+
$excerpt
|
273 |
+
);
|
274 |
}
|
275 |
|
276 |
if ( null !== $old_global_post ) {
|
277 |
$post = $old_global_post; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
278 |
}
|
279 |
|
280 |
+
return $excerpt_text;
|
281 |
}
|
282 |
|
283 |
/**
|
284 |
* Creates an excerpt from content.
|
285 |
*
|
286 |
+
* This is provided for backwards compatibility. The new version of the function
|
287 |
+
* supports the Premium capability to return multiple excerpts. Since that
|
288 |
+
* changes the return value of the function, this function is provided to
|
289 |
+
* return the original return value.
|
290 |
+
*
|
291 |
+
* @uses relevanssi_create_excerpts()
|
292 |
*
|
293 |
* @param string $content The content.
|
294 |
* @param array $terms The search terms, tokenized.
|
300 |
* element 2 is true, if the excerpt is from the start of the content.
|
301 |
*/
|
302 |
function relevanssi_create_excerpt( $content, $terms, $query, $excerpt_length = 30, $excerpt_type = 'words' ) {
|
303 |
+
$excerpts = relevanssi_create_excerpts( $content, $terms, $query, $excerpt_length, $excerpt_type );
|
304 |
+
usort(
|
305 |
+
$excerpts,
|
306 |
+
function( $a, $b ) {
|
307 |
+
return $b['hits'] - $a['hits'];
|
308 |
+
}
|
309 |
+
);
|
310 |
|
311 |
+
$excerpt = array(
|
312 |
+
0 => $excerpts[0]['text'],
|
313 |
+
1 => $excerpts[0]['hits'],
|
314 |
+
2 => $excerpts[0]['start'],
|
315 |
+
);
|
316 |
+
return $excerpt;
|
317 |
+
}
|
318 |
+
|
319 |
+
/**
|
320 |
+
* Creates an excerpt from content.
|
321 |
+
*
|
322 |
+
* Relevanssi Premium has the capability to generate multiple excerpts from one
|
323 |
+
* post. While the free version only generates one excerpt per post, this
|
324 |
+
* function supports the multiple excerpt behaviour by returning an array of
|
325 |
+
* excerpts, even though just one excerpt is returned.
|
326 |
+
*
|
327 |
+
* @see relevanssi_create_excerpt()
|
328 |
+
*
|
329 |
+
* @param string $content The content.
|
330 |
+
* @param array $terms The search terms, tokenized.
|
331 |
+
* @param string $query The search query (not used anymore).
|
332 |
+
* @param int $excerpt_length The length of the excerpt, default 30.
|
333 |
+
* @param string $excerpt_type Either 'chars' or 'words', default 'words'.
|
334 |
+
*
|
335 |
+
* @return array An array of excerpts. In each excerpt, there are following
|
336 |
+
* parts: 'text' has the excerpt text, 'hits' the number of keyword matches in
|
337 |
+
* the excerpt, 'start' is true if the excerpt is from the beginning of the
|
338 |
+
* content.
|
339 |
+
*/
|
340 |
+
function relevanssi_create_excerpts( $content, $terms, $query, $excerpt_length = 30, $excerpt_type = 'words' ) {
|
341 |
$content = ' ' . preg_replace( '/\s+/u', ' ', $content );
|
342 |
$content = html_entity_decode( $content );
|
343 |
// Finds all the phrases in the query.
|
344 |
$phrases = relevanssi_extract_phrases( stripslashes( $query ) );
|
345 |
+
$terms = relevanssi_remove_quotes_from_array_keys( $terms );
|
346 |
|
347 |
/**
|
348 |
* This process generates an array of terms, which has single terms and all the
|
365 |
// Sort the longest search terms first, because those are generally more significant.
|
366 |
uksort( $terms, 'relevanssi_strlen_sort' );
|
367 |
|
368 |
+
$excerpts = array();
|
369 |
+
$start = false;
|
370 |
if ( 'chars' === $excerpt_type ) {
|
371 |
$prev_count = floor( $excerpt_length / 6 );
|
372 |
|
373 |
+
list( $excerpt_text, $best_excerpt_term_hits, $start ) =
|
374 |
relevanssi_extract_relevant(
|
375 |
array_keys( $terms ),
|
376 |
$content,
|
377 |
$excerpt_length + 1,
|
378 |
$prev_count
|
379 |
);
|
380 |
+
$excerpt = array(
|
381 |
+
'text' => $excerpt_text,
|
382 |
+
'hits' => $best_excerpt_term_hits,
|
383 |
+
'start' => $start,
|
|
|
|
|
384 |
);
|
385 |
+
$excerpts[] = $excerpt;
|
386 |
+
} else {
|
387 |
+
if ( function_exists( 'relevanssi_extract_multiple_excerpts' ) ) {
|
388 |
+
$excerpts = relevanssi_extract_multiple_excerpts(
|
389 |
+
array_keys( $terms ),
|
390 |
+
$content,
|
391 |
+
$excerpt_length
|
392 |
+
);
|
393 |
+
} else {
|
394 |
+
list( $excerpt_text, $best_excerpt_term_hits, $start ) =
|
395 |
+
relevanssi_extract_relevant_words(
|
396 |
+
array_keys( $terms ),
|
397 |
+
$content,
|
398 |
+
$excerpt_length
|
399 |
+
);
|
400 |
+
$excerpt = array(
|
401 |
+
'text' => $excerpt_text,
|
402 |
+
'hits' => $best_excerpt_term_hits,
|
403 |
+
'start' => $start,
|
404 |
+
);
|
405 |
+
$excerpts[] = $excerpt;
|
406 |
+
}
|
407 |
}
|
408 |
|
409 |
+
return $excerpts;
|
410 |
}
|
411 |
|
412 |
/**
|
510 |
return $content;
|
511 |
}
|
512 |
|
513 |
+
$start_emp_token = '**{[';
|
514 |
$end_emp_token = ']}**';
|
515 |
|
516 |
if ( function_exists( 'mb_internal_encoding' ) ) {
|
586 |
|
587 |
usort( $terms, 'relevanssi_strlen_sort' );
|
588 |
|
|
|
|
|
|
|
|
|
|
|
589 |
$content = html_entity_decode( $content, ENT_QUOTES, 'UTF-8' );
|
590 |
+
$content = str_replace( "\n", ' ', $content );
|
591 |
|
592 |
foreach ( $terms as $term ) {
|
593 |
$pr_term = preg_quote( $term, '/' );
|
600 |
$pr_term
|
601 |
);
|
602 |
|
603 |
+
$regex = "/([\W])($pr_term)([\W])/iu";
|
604 |
+
$three_parts = true;
|
605 |
+
|
606 |
+
if ( 'never' !== get_option( 'relevanssi_fuzzy' ) ) {
|
607 |
+
$regex = "/([\W]{$pr_term}|{$pr_term}[\W])/iu";
|
608 |
+
$three_parts = false;
|
609 |
+
}
|
610 |
+
|
611 |
+
if ( 'on' === get_option( 'relevanssi_expand_highlights' ) ) {
|
612 |
+
$regex = "/([\w]*{$pr_term}[\W]|[\W]{$pr_term}[\w]*)/iu";
|
613 |
+
$three_parts = false;
|
614 |
+
}
|
615 |
+
|
616 |
+
if ( $three_parts ) {
|
617 |
+
$replace = '\\1' . $start_emp_token . '\\2' . $end_emp_token . '\\3';
|
618 |
} else {
|
619 |
+
$replace = $start_emp_token . '\\1' . $end_emp_token;
|
|
|
|
|
|
|
|
|
620 |
}
|
621 |
|
622 |
+
$content = trim(
|
623 |
+
preg_replace(
|
624 |
+
$regex,
|
625 |
+
$replace,
|
626 |
+
' ' . $content
|
627 |
+
)
|
628 |
+
);
|
629 |
+
|
630 |
+
/**
|
631 |
+
* The method here leaves extra spaces inside the highlighting. That
|
632 |
+
* is cleaned away here.
|
633 |
+
*/
|
634 |
+
$replace_regex = '/(.)(' . preg_quote( $start_emp_token, '/' ) . ')(\s)/iu';
|
635 |
+
$content = preg_replace( $replace_regex, '\1\3\2', $content );
|
636 |
+
|
637 |
+
$replace_regex = '/^(' . preg_quote( $start_emp_token, '/' ) . ')\s/iu';
|
638 |
+
$content = preg_replace( $replace_regex, '\1', $content );
|
639 |
+
|
640 |
+
$replace_regex = '/(\s)(' . preg_quote( $end_emp_token, '/' ) . ')(.)/iu';
|
641 |
+
$content = preg_replace( $replace_regex, '\2\1\3', $content );
|
642 |
+
|
643 |
+
$replace_regex = '/\s(' . preg_quote( $end_emp_token, '/' ) . ')/iu';
|
644 |
+
$content = preg_replace( $replace_regex, '\1', $content );
|
645 |
+
|
646 |
+
// The starting tokens can get interlaced this way, let's unknot them.
|
647 |
+
$content = str_replace(
|
648 |
+
substr( $start_emp_token, 0, -1 ) . $start_emp_token . substr( $start_emp_token, -1, 1 ),
|
649 |
+
$start_emp_token . $start_emp_token,
|
650 |
+
$content
|
651 |
+
);
|
652 |
+
|
653 |
if ( preg_match_all( '/<.*>/U', $content, $matches ) > 0 ) {
|
654 |
// Remove highlights from inside HTML tags.
|
655 |
foreach ( $matches as $match ) {
|
971 |
$lowercase_text = relevanssi_strtolower( $complete_text, 'UTF-8' );
|
972 |
$text = '';
|
973 |
|
|
|
|
|
|
|
|
|
|
|
974 |
$count_words = count( $words );
|
975 |
for ( $t = 0; $t < $count_words; $t++ ) {
|
976 |
$word_slice = relevanssi_strtolower(
|
989 |
$word_slice
|
990 |
);
|
991 |
|
992 |
+
if ( 'never' !== get_option( 'relevanssi_fuzzy' ) ) {
|
993 |
+
$regex = "/[\W]{$word_slice}|{$word_slice}[\W]/iu";
|
|
|
|
|
|
|
|
|
994 |
} else {
|
995 |
+
$regex = "/[\W]{$word_slice}[\W]/iu";
|
996 |
}
|
997 |
+
|
998 |
$lines = preg_split( $regex, $lowercase_text );
|
999 |
if ( $lines && count( $lines ) > 1 ) {
|
1000 |
$count_lines = count( $lines );
|
1103 |
$startpos -= ( $text_length - $startpos ) / 2;
|
1104 |
}
|
1105 |
|
1106 |
+
$substr = function_exists( 'mb_substr' ) ? 'mb_substr' : 'substr';
|
|
|
|
|
|
|
1107 |
|
1108 |
$excerpt = call_user_func( $substr, $fulltext, $startpos, $excerpt_length );
|
1109 |
|
1196 |
$start = true;
|
1197 |
}
|
1198 |
|
1199 |
+
return array( trim( $excerpt ), $best_excerpt_term_hits, $start );
|
1200 |
}
|
1201 |
|
1202 |
/**
|
1219 |
'relevanssi_accents_replacement_arrays',
|
1220 |
array(
|
1221 |
'from' => array( 'a', 'c', 'e', 'i', 'o', 'u', 'n' ),
|
1222 |
+
'to' => array( '(?:a|á|à|â)', '(?:c|ç)', '(?:e|é|è|ê|ë)', '(?:i|í|ì|î|ï)', '(?:o|ó|ò|ô|õ)', '(?:u|ú|ù|ü|û)', '(?:n|ñ)' ),
|
1223 |
'from_re' => array( "/(s)('|’)?$/", "/[^\(\|]('|’)/" ),
|
1224 |
'to_re' => array( "(('|’)?\\1|\\1('|’)?)", "?('|’)?" ),
|
1225 |
)
|
lib/indexing.php
CHANGED
@@ -150,7 +150,6 @@ function relevanssi_generate_indexing_query( $valid_status, $extend = false, $re
|
|
150 |
OR (post.post_parent=0)
|
151 |
)
|
152 |
))
|
153 |
-
AND post.ID NOT IN (SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_hide_post' AND meta_value = 'on')
|
154 |
{$restriction['mysql']} ORDER BY post.ID DESC $limit";
|
155 |
} else {
|
156 |
$processed_post_filter = 'r.doc is null';
|
@@ -174,7 +173,6 @@ function relevanssi_generate_indexing_query( $valid_status, $extend = false, $re
|
|
174 |
)
|
175 |
)
|
176 |
)
|
177 |
-
AND post.ID NOT IN (SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_hide_post' AND meta_value = 'on')
|
178 |
{$restriction['mysql']} ORDER BY post.ID DESC $limit";
|
179 |
}
|
180 |
|
@@ -1427,13 +1425,13 @@ function relevanssi_index_title( &$insert_data, $post, $min_word_length, $debug
|
|
1427 |
* Creates indexing queries for post content.
|
1428 |
*
|
1429 |
* @param array $insert_data The INSERT query data. Modified here.
|
1430 |
-
* @param object $
|
1431 |
* @param int $min_word_length The minimum word length.
|
1432 |
* @param boolean $debug If true, print out debug notices.
|
1433 |
*
|
1434 |
* @return int The number of tokens added to the data.
|
1435 |
*/
|
1436 |
-
function relevanssi_index_content( &$insert_data, $
|
1437 |
$n = 0;
|
1438 |
|
1439 |
/**
|
@@ -1455,10 +1453,10 @@ function relevanssi_index_content( &$insert_data, $post, $min_word_length, $debu
|
|
1455 |
/**
|
1456 |
* Filters the post content before indexing.
|
1457 |
*
|
1458 |
-
* @param string $
|
1459 |
-
* @param object $
|
1460 |
*/
|
1461 |
-
$contents = apply_filters( 'relevanssi_post_content', $
|
1462 |
if ( $debug ) {
|
1463 |
relevanssi_debug_echo( "\tPost content after relevanssi_post_content:\n$contents" );
|
1464 |
}
|
@@ -1468,10 +1466,10 @@ function relevanssi_index_content( &$insert_data, $post, $min_word_length, $debu
|
|
1468 |
*
|
1469 |
* @author Alexander Gieg
|
1470 |
*
|
1471 |
-
* @param string
|
1472 |
-
* @param object $
|
1473 |
*/
|
1474 |
-
$additional_content = trim( apply_filters( 'relevanssi_content_to_index', '', $
|
1475 |
if ( ! empty( $additional_content ) ) {
|
1476 |
$contents .= ' ' . $additional_content;
|
1477 |
|
@@ -1488,9 +1486,22 @@ function relevanssi_index_content( &$insert_data, $post, $min_word_length, $debu
|
|
1488 |
|
1489 |
relevanssi_disable_shortcodes();
|
1490 |
|
1491 |
-
|
1492 |
-
|
1493 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1494 |
|
1495 |
unset( $tablepress_controller );
|
1496 |
} else {
|
@@ -1503,20 +1514,20 @@ function relevanssi_index_content( &$insert_data, $post, $min_word_length, $debu
|
|
1503 |
/**
|
1504 |
* Filters the post content after shortcodes but before HTML stripping.
|
1505 |
*
|
1506 |
-
* @param string $contents
|
1507 |
-
* @param object $
|
1508 |
*/
|
1509 |
$contents = apply_filters(
|
1510 |
'relevanssi_post_content_after_shortcodes',
|
1511 |
$contents,
|
1512 |
-
$
|
1513 |
);
|
1514 |
|
1515 |
$contents = relevanssi_strip_invisibles( $contents );
|
1516 |
|
1517 |
// Premium feature for better control over internal links.
|
1518 |
if ( function_exists( 'relevanssi_process_internal_links' ) ) {
|
1519 |
-
$contents = relevanssi_process_internal_links( $contents, $
|
1520 |
}
|
1521 |
|
1522 |
$contents = preg_replace( '/<[a-zA-Z\/][^>]*>/', ' ', $contents );
|
@@ -1525,10 +1536,10 @@ function relevanssi_index_content( &$insert_data, $post, $min_word_length, $debu
|
|
1525 |
/**
|
1526 |
* Filters the post content in indexing before tokenization.
|
1527 |
*
|
1528 |
-
* @param string $contents
|
1529 |
-
* @param object $
|
1530 |
*/
|
1531 |
-
$contents = apply_filters( 'relevanssi_post_content_before_tokenize', $contents, $
|
1532 |
/** This filter is documented in lib/indexing.php */
|
1533 |
$content_tokens = apply_filters(
|
1534 |
'relevanssi_indexing_tokens',
|
150 |
OR (post.post_parent=0)
|
151 |
)
|
152 |
))
|
|
|
153 |
{$restriction['mysql']} ORDER BY post.ID DESC $limit";
|
154 |
} else {
|
155 |
$processed_post_filter = 'r.doc is null';
|
173 |
)
|
174 |
)
|
175 |
)
|
|
|
176 |
{$restriction['mysql']} ORDER BY post.ID DESC $limit";
|
177 |
}
|
178 |
|
1425 |
* Creates indexing queries for post content.
|
1426 |
*
|
1427 |
* @param array $insert_data The INSERT query data. Modified here.
|
1428 |
+
* @param object $post_object The post object.
|
1429 |
* @param int $min_word_length The minimum word length.
|
1430 |
* @param boolean $debug If true, print out debug notices.
|
1431 |
*
|
1432 |
* @return int The number of tokens added to the data.
|
1433 |
*/
|
1434 |
+
function relevanssi_index_content( &$insert_data, $post_object, $min_word_length, $debug ) {
|
1435 |
$n = 0;
|
1436 |
|
1437 |
/**
|
1453 |
/**
|
1454 |
* Filters the post content before indexing.
|
1455 |
*
|
1456 |
+
* @param string $post_object->post_content The post content.
|
1457 |
+
* @param object $post_object The full post object.
|
1458 |
*/
|
1459 |
+
$contents = apply_filters( 'relevanssi_post_content', $post_object->post_content, $post_object );
|
1460 |
if ( $debug ) {
|
1461 |
relevanssi_debug_echo( "\tPost content after relevanssi_post_content:\n$contents" );
|
1462 |
}
|
1466 |
*
|
1467 |
* @author Alexander Gieg
|
1468 |
*
|
1469 |
+
* @param string The additional content.
|
1470 |
+
* @param object $post_object The post object.
|
1471 |
*/
|
1472 |
+
$additional_content = trim( apply_filters( 'relevanssi_content_to_index', '', $post_object ) );
|
1473 |
if ( ! empty( $additional_content ) ) {
|
1474 |
$contents .= ' ' . $additional_content;
|
1475 |
|
1486 |
|
1487 |
relevanssi_disable_shortcodes();
|
1488 |
|
1489 |
+
/**
|
1490 |
+
* This needs to be global here, otherwise the safety mechanism doesn't
|
1491 |
+
* work correctly.
|
1492 |
+
*/
|
1493 |
+
global $post;
|
1494 |
+
|
1495 |
+
$global_post_before_shortcode = null;
|
1496 |
+
if ( isset( $post ) ) {
|
1497 |
+
$global_post_before_shortcode = $post;
|
1498 |
+
}
|
1499 |
+
|
1500 |
+
$contents = do_shortcode( $contents );
|
1501 |
+
|
1502 |
+
if ( $global_post_before_shortcode ) {
|
1503 |
+
$post = $global_post_before_shortcode; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
1504 |
+
}
|
1505 |
|
1506 |
unset( $tablepress_controller );
|
1507 |
} else {
|
1514 |
/**
|
1515 |
* Filters the post content after shortcodes but before HTML stripping.
|
1516 |
*
|
1517 |
+
* @param string $contents The post content.
|
1518 |
+
* @param object $post_object The full post object.
|
1519 |
*/
|
1520 |
$contents = apply_filters(
|
1521 |
'relevanssi_post_content_after_shortcodes',
|
1522 |
$contents,
|
1523 |
+
$post_object
|
1524 |
);
|
1525 |
|
1526 |
$contents = relevanssi_strip_invisibles( $contents );
|
1527 |
|
1528 |
// Premium feature for better control over internal links.
|
1529 |
if ( function_exists( 'relevanssi_process_internal_links' ) ) {
|
1530 |
+
$contents = relevanssi_process_internal_links( $contents, $post_object->ID );
|
1531 |
}
|
1532 |
|
1533 |
$contents = preg_replace( '/<[a-zA-Z\/][^>]*>/', ' ', $contents );
|
1536 |
/**
|
1537 |
* Filters the post content in indexing before tokenization.
|
1538 |
*
|
1539 |
+
* @param string $contents The post content.
|
1540 |
+
* @param object $post_object The full post object.
|
1541 |
*/
|
1542 |
+
$contents = apply_filters( 'relevanssi_post_content_before_tokenize', $contents, $post_object );
|
1543 |
/** This filter is documented in lib/indexing.php */
|
1544 |
$content_tokens = apply_filters(
|
1545 |
'relevanssi_indexing_tokens',
|
lib/init.php
CHANGED
@@ -182,6 +182,10 @@ function relevanssi_init() {
|
|
182 |
require_once 'compatibility/seopress.php';
|
183 |
}
|
184 |
|
|
|
|
|
|
|
|
|
185 |
if ( function_exists( 'members_content_permissions_enabled' ) ) {
|
186 |
require_once 'compatibility/members.php';
|
187 |
}
|
@@ -223,6 +227,14 @@ function relevanssi_init() {
|
|
223 |
if ( defined( 'NINJA_TABLES_VERSION' ) ) {
|
224 |
require_once 'compatibility/ninjatables.php';
|
225 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
226 |
}
|
227 |
|
228 |
/**
|
@@ -233,8 +245,6 @@ function relevanssi_init() {
|
|
233 |
function relevanssi_admin_init() {
|
234 |
global $relevanssi_variables;
|
235 |
|
236 |
-
require_once $relevanssi_variables['plugin_dir'] . 'lib/admin-ajax.php';
|
237 |
-
|
238 |
add_action( 'admin_enqueue_scripts', 'relevanssi_add_admin_scripts' );
|
239 |
add_filter( 'plugin_action_links_' . $relevanssi_variables['plugin_basename'], 'relevanssi_action_links' );
|
240 |
}
|
182 |
require_once 'compatibility/seopress.php';
|
183 |
}
|
184 |
|
185 |
+
if ( defined( 'THE_SEO_FRAMEWORK_VERSION' ) ) {
|
186 |
+
require_once 'compatibility/seoframework.php';
|
187 |
+
}
|
188 |
+
|
189 |
if ( function_exists( 'members_content_permissions_enabled' ) ) {
|
190 |
require_once 'compatibility/members.php';
|
191 |
}
|
227 |
if ( defined( 'NINJA_TABLES_VERSION' ) ) {
|
228 |
require_once 'compatibility/ninjatables.php';
|
229 |
}
|
230 |
+
|
231 |
+
if ( defined( 'PRLI_PLUGIN_NAME' ) ) {
|
232 |
+
require_once 'compatibility/pretty-links.php';
|
233 |
+
}
|
234 |
+
|
235 |
+
if ( defined( 'CT_VERSION' ) ) {
|
236 |
+
require_once 'compatibility/oxygen.php';
|
237 |
+
}
|
238 |
}
|
239 |
|
240 |
/**
|
245 |
function relevanssi_admin_init() {
|
246 |
global $relevanssi_variables;
|
247 |
|
|
|
|
|
248 |
add_action( 'admin_enqueue_scripts', 'relevanssi_add_admin_scripts' );
|
249 |
add_filter( 'plugin_action_links_' . $relevanssi_variables['plugin_basename'], 'relevanssi_action_links' );
|
250 |
}
|
lib/install.php
CHANGED
@@ -88,6 +88,7 @@ function _relevanssi_install() {
|
|
88 |
add_option( 'relevanssi_excerpt_type', 'words' );
|
89 |
add_option( 'relevanssi_excerpts', 'on' );
|
90 |
add_option( 'relevanssi_exclude_posts', '' );
|
|
|
91 |
add_option( 'relevanssi_expand_shortcodes', 'on' );
|
92 |
add_option( 'relevanssi_extag', '0' );
|
93 |
add_option( 'relevanssi_fuzzy', 'sometimes' );
|
@@ -126,7 +127,6 @@ function _relevanssi_install() {
|
|
126 |
add_option( 'relevanssi_throttle_limit', '500' );
|
127 |
add_option( 'relevanssi_title_boost', $relevanssi_variables['title_boost_default'] );
|
128 |
add_option( 'relevanssi_txt_col', '#ff0000' );
|
129 |
-
add_option( 'relevanssi_word_boundaries', 'on' );
|
130 |
add_option( 'relevanssi_wpml_only_current', 'on' );
|
131 |
|
132 |
if ( function_exists( 'relevanssi_premium_install' ) ) {
|
88 |
add_option( 'relevanssi_excerpt_type', 'words' );
|
89 |
add_option( 'relevanssi_excerpts', 'on' );
|
90 |
add_option( 'relevanssi_exclude_posts', '' );
|
91 |
+
add_option( 'relevanssi_expand_highlights', 'off' );
|
92 |
add_option( 'relevanssi_expand_shortcodes', 'on' );
|
93 |
add_option( 'relevanssi_extag', '0' );
|
94 |
add_option( 'relevanssi_fuzzy', 'sometimes' );
|
127 |
add_option( 'relevanssi_throttle_limit', '500' );
|
128 |
add_option( 'relevanssi_title_boost', $relevanssi_variables['title_boost_default'] );
|
129 |
add_option( 'relevanssi_txt_col', '#ff0000' );
|
|
|
130 |
add_option( 'relevanssi_wpml_only_current', 'on' );
|
131 |
|
132 |
if ( function_exists( 'relevanssi_premium_install' ) ) {
|
lib/interface.php
CHANGED
@@ -107,121 +107,64 @@ function relevanssi_options() {
|
|
107 |
*/
|
108 |
function update_relevanssi_options() {
|
109 |
// phpcs:disable WordPress.Security.NonceVerification
|
110 |
-
if ( isset( $_REQUEST['relevanssi_content_boost'] ) ) {
|
111 |
-
$boost = floatval( $_REQUEST['relevanssi_content_boost'] );
|
112 |
-
update_option( 'relevanssi_content_boost', $boost );
|
113 |
-
}
|
114 |
-
|
115 |
-
if ( isset( $_REQUEST['relevanssi_title_boost'] ) ) {
|
116 |
-
$boost = floatval( $_REQUEST['relevanssi_title_boost'] );
|
117 |
-
update_option( 'relevanssi_title_boost', $boost );
|
118 |
-
}
|
119 |
-
|
120 |
-
if ( isset( $_REQUEST['relevanssi_comment_boost'] ) ) {
|
121 |
-
$boost = floatval( $_REQUEST['relevanssi_comment_boost'] );
|
122 |
-
update_option( 'relevanssi_comment_boost', $boost );
|
123 |
-
}
|
124 |
-
|
125 |
-
if ( isset( $_REQUEST['relevanssi_min_word_length'] ) ) {
|
126 |
-
$value = intval( $_REQUEST['relevanssi_min_word_length'] );
|
127 |
-
if ( 0 === $value ) {
|
128 |
-
$value = 3;
|
129 |
-
}
|
130 |
-
update_option( 'relevanssi_min_word_length', $value );
|
131 |
-
}
|
132 |
-
|
133 |
if ( 'indexing' === $_REQUEST['tab'] ) {
|
134 |
-
|
135 |
-
$_REQUEST
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
}
|
145 |
-
|
146 |
-
if ( ! isset( $_REQUEST['relevanssi_index_image_files'] ) ) {
|
147 |
-
$_REQUEST['relevanssi_index_image_files'] = 'off';
|
148 |
-
}
|
149 |
}
|
150 |
|
151 |
if ( 'searching' === $_REQUEST['tab'] ) {
|
152 |
-
|
153 |
-
$_REQUEST
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
if ( ! isset( $_REQUEST['relevanssi_wpml_only_current'] ) ) {
|
169 |
-
$_REQUEST['relevanssi_wpml_only_current'] = 'off';
|
170 |
-
}
|
171 |
-
|
172 |
-
if ( ! isset( $_REQUEST['relevanssi_polylang_all_languages'] ) ) {
|
173 |
-
$_REQUEST['relevanssi_polylang_all_languages'] = 'off';
|
174 |
-
}
|
175 |
-
|
176 |
-
if ( ! isset( $_REQUEST['relevanssi_exact_match_bonus'] ) ) {
|
177 |
-
$_REQUEST['relevanssi_exact_match_bonus'] = 'off';
|
178 |
-
}
|
179 |
}
|
180 |
|
181 |
if ( 'logging' === $_REQUEST['tab'] ) {
|
182 |
-
|
183 |
-
$_REQUEST
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
}
|
190 |
|
191 |
if ( 'excerpts' === $_REQUEST['tab'] ) {
|
192 |
-
|
193 |
-
$_REQUEST
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
if (
|
205 |
-
$_REQUEST['
|
206 |
-
|
207 |
-
|
208 |
-
if ( ! isset( $_REQUEST['relevanssi_highlight_comments'] ) ) {
|
209 |
-
$_REQUEST['relevanssi_highlight_comments'] = 'off';
|
210 |
-
}
|
211 |
-
|
212 |
-
if ( ! isset( $_REQUEST['relevanssi_excerpt_custom_fields'] ) ) {
|
213 |
-
$_REQUEST['relevanssi_excerpt_custom_fields'] = 'off';
|
214 |
-
}
|
215 |
-
|
216 |
-
if ( ! isset( $_REQUEST['relevanssi_word_boundaries'] ) ) {
|
217 |
-
$_REQUEST['relevanssi_word_boundaries'] = 'off';
|
218 |
-
}
|
219 |
-
}
|
220 |
-
|
221 |
-
if ( isset( $_REQUEST['relevanssi_excerpt_length'] ) ) {
|
222 |
-
$value = intval( $_REQUEST['relevanssi_excerpt_length'] );
|
223 |
-
if ( 0 !== $value ) {
|
224 |
-
update_option( 'relevanssi_excerpt_length', $value );
|
225 |
}
|
226 |
}
|
227 |
|
@@ -232,15 +175,6 @@ function update_relevanssi_options() {
|
|
232 |
update_option( 'relevanssi_synonyms', $value );
|
233 |
}
|
234 |
|
235 |
-
if ( isset( $_REQUEST['relevanssi_show_matches'] ) ) {
|
236 |
-
update_option( 'relevanssi_show_matches', $_REQUEST['relevanssi_show_matches'] );
|
237 |
-
}
|
238 |
-
if ( isset( $_REQUEST['relevanssi_show_matches_text'] ) ) {
|
239 |
-
$value = $_REQUEST['relevanssi_show_matches_text'];
|
240 |
-
$value = str_replace( '"', "'", $value );
|
241 |
-
update_option( 'relevanssi_show_matches_text', $value );
|
242 |
-
}
|
243 |
-
|
244 |
$relevanssi_punct = array();
|
245 |
if ( isset( $_REQUEST['relevanssi_punct_quotes'] ) ) {
|
246 |
$relevanssi_punct['quotes'] = $_REQUEST['relevanssi_punct_quotes'];
|
@@ -374,103 +308,57 @@ function update_relevanssi_options() {
|
|
374 |
}
|
375 |
}
|
376 |
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
if ( isset( $_REQUEST['relevanssi_class'] ) ) {
|
414 |
-
update_option( 'relevanssi_class', $_REQUEST['relevanssi_class'] );
|
415 |
-
}
|
416 |
if ( isset( $_REQUEST['relevanssi_expst'] ) ) {
|
417 |
-
|
418 |
-
}
|
419 |
-
if ( isset( $_REQUEST['relevanssi_hilite_title'] ) ) {
|
420 |
-
update_option( 'relevanssi_hilite_title', $_REQUEST['relevanssi_hilite_title'] );
|
421 |
-
}
|
422 |
-
if ( isset( $_REQUEST['relevanssi_index_comments'] ) ) {
|
423 |
-
update_option( 'relevanssi_index_comments', $_REQUEST['relevanssi_index_comments'], false );
|
424 |
-
}
|
425 |
-
if ( isset( $_REQUEST['relevanssi_index_author'] ) ) {
|
426 |
-
update_option( 'relevanssi_index_author', $_REQUEST['relevanssi_index_author'], false );
|
427 |
-
}
|
428 |
-
if ( isset( $_REQUEST['relevanssi_index_excerpt'] ) ) {
|
429 |
-
update_option( 'relevanssi_index_excerpt', $_REQUEST['relevanssi_index_excerpt'], false );
|
430 |
-
}
|
431 |
-
if ( isset( $_REQUEST['relevanssi_index_image_files'] ) ) {
|
432 |
-
update_option( 'relevanssi_index_image_files', $_REQUEST['relevanssi_index_image_files'], false );
|
433 |
-
}
|
434 |
-
if ( isset( $_REQUEST['relevanssi_fuzzy'] ) ) {
|
435 |
-
update_option( 'relevanssi_fuzzy', $_REQUEST['relevanssi_fuzzy'] );
|
436 |
-
}
|
437 |
-
if ( isset( $_REQUEST['relevanssi_expand_shortcodes'] ) ) {
|
438 |
-
update_option( 'relevanssi_expand_shortcodes', $_REQUEST['relevanssi_expand_shortcodes'], false );
|
439 |
-
}
|
440 |
-
if ( isset( $_REQUEST['relevanssi_implicit_operator'] ) ) {
|
441 |
-
update_option( 'relevanssi_implicit_operator', $_REQUEST['relevanssi_implicit_operator'] );
|
442 |
-
}
|
443 |
-
if ( isset( $_REQUEST['relevanssi_omit_from_logs'] ) ) {
|
444 |
-
update_option( 'relevanssi_omit_from_logs', $_REQUEST['relevanssi_omit_from_logs'] );
|
445 |
-
}
|
446 |
-
if ( isset( $_REQUEST['relevanssi_disable_or_fallback'] ) ) {
|
447 |
-
update_option( 'relevanssi_disable_or_fallback', $_REQUEST['relevanssi_disable_or_fallback'] );
|
448 |
-
}
|
449 |
-
if ( isset( $_REQUEST['relevanssi_respect_exclude'] ) ) {
|
450 |
-
update_option( 'relevanssi_respect_exclude', $_REQUEST['relevanssi_respect_exclude'] );
|
451 |
-
}
|
452 |
-
if ( isset( $_REQUEST['relevanssi_throttle'] ) ) {
|
453 |
-
update_option( 'relevanssi_throttle', $_REQUEST['relevanssi_throttle'] );
|
454 |
-
}
|
455 |
-
if ( isset( $_REQUEST['relevanssi_wpml_only_current'] ) ) {
|
456 |
-
update_option( 'relevanssi_wpml_only_current', $_REQUEST['relevanssi_wpml_only_current'] );
|
457 |
-
}
|
458 |
-
if ( isset( $_REQUEST['relevanssi_polylang_all_languages'] ) ) {
|
459 |
-
update_option( 'relevanssi_polylang_all_languages', $_REQUEST['relevanssi_polylang_all_languages'] );
|
460 |
-
}
|
461 |
-
if ( isset( $_REQUEST['relevanssi_word_boundaries'] ) ) {
|
462 |
-
update_option( 'relevanssi_word_boundaries', $_REQUEST['relevanssi_word_boundaries'] );
|
463 |
-
}
|
464 |
-
if ( isset( $_REQUEST['relevanssi_default_orderby'] ) ) {
|
465 |
-
update_option( 'relevanssi_default_orderby', $_REQUEST['relevanssi_default_orderby'] );
|
466 |
-
}
|
467 |
-
if ( isset( $_REQUEST['relevanssi_excerpt_custom_fields'] ) ) {
|
468 |
-
update_option( 'relevanssi_excerpt_custom_fields', $_REQUEST['relevanssi_excerpt_custom_fields'] );
|
469 |
-
}
|
470 |
-
if ( isset( $_REQUEST['relevanssi_exact_match_bonus'] ) ) {
|
471 |
-
update_option( 'relevanssi_exact_match_bonus', $_REQUEST['relevanssi_exact_match_bonus'] );
|
472 |
}
|
473 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
474 |
if ( function_exists( 'relevanssi_update_premium_options' ) ) {
|
475 |
relevanssi_update_premium_options();
|
476 |
}
|
@@ -883,7 +771,7 @@ function relevanssi_options_form() {
|
|
883 |
),
|
884 |
array(
|
885 |
'slug' => 'excerpts',
|
886 |
-
'name' => __( 'Excerpts and
|
887 |
'require' => 'tabs/excerpts-tab.php',
|
888 |
'callback' => 'relevanssi_excerpts_tab',
|
889 |
'save' => true,
|
@@ -909,6 +797,13 @@ function relevanssi_options_form() {
|
|
909 |
'callback' => 'relevanssi_redirects_tab',
|
910 |
'save' => false,
|
911 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
912 |
);
|
913 |
|
914 |
/**
|
@@ -1110,3 +1005,178 @@ function relevanssi_form_tag_weight() {
|
|
1110 |
</tr>
|
1111 |
<?php
|
1112 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
*/
|
108 |
function update_relevanssi_options() {
|
109 |
// phpcs:disable WordPress.Security.NonceVerification
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
if ( 'indexing' === $_REQUEST['tab'] ) {
|
111 |
+
relevanssi_turn_off_options(
|
112 |
+
$_REQUEST,
|
113 |
+
array(
|
114 |
+
'relevanssi_expand_shortcodes',
|
115 |
+
'relevanssi_index_author',
|
116 |
+
'relevanssi_index_excerpt',
|
117 |
+
'relevanssi_index_image_files',
|
118 |
+
)
|
119 |
+
);
|
120 |
+
relevanssi_update_intval( $_REQUEST, 'relevanssi_min_word_length', true, 3 );
|
|
|
|
|
|
|
|
|
|
|
121 |
}
|
122 |
|
123 |
if ( 'searching' === $_REQUEST['tab'] ) {
|
124 |
+
relevanssi_turn_off_options(
|
125 |
+
$_REQUEST,
|
126 |
+
array(
|
127 |
+
'relevanssi_admin_search',
|
128 |
+
'relevanssi_disable_or_fallback',
|
129 |
+
'relevanssi_exact_match_bonus',
|
130 |
+
'relevanssi_polylang_all_languages',
|
131 |
+
'relevanssi_respect_exclude',
|
132 |
+
'relevanssi_throttle',
|
133 |
+
'relevanssi_wpml_only_current',
|
134 |
+
)
|
135 |
+
);
|
136 |
+
relevanssi_update_floatval( $_REQUEST, 'relevanssi_content_boost', true, 1 );
|
137 |
+
relevanssi_update_floatval( $_REQUEST, 'relevanssi_title_boost', true, 1 );
|
138 |
+
relevanssi_update_floatval( $_REQUEST, 'relevanssi_comment_boost', true, 1 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
139 |
}
|
140 |
|
141 |
if ( 'logging' === $_REQUEST['tab'] ) {
|
142 |
+
relevanssi_turn_off_options(
|
143 |
+
$_REQUEST,
|
144 |
+
array(
|
145 |
+
'relevanssi_log_queries',
|
146 |
+
'relevanssi_log_queries_with_ip',
|
147 |
+
)
|
148 |
+
);
|
149 |
}
|
150 |
|
151 |
if ( 'excerpts' === $_REQUEST['tab'] ) {
|
152 |
+
relevanssi_turn_off_options(
|
153 |
+
$_REQUEST,
|
154 |
+
array(
|
155 |
+
'relevanssi_excerpt_custom_fields',
|
156 |
+
'relevanssi_excerpts',
|
157 |
+
'relevanssi_expand_highlights',
|
158 |
+
'relevanssi_highlight_comments',
|
159 |
+
'relevanssi_highlight_docs',
|
160 |
+
'relevanssi_hilite_title',
|
161 |
+
'relevanssi_show_matches',
|
162 |
+
)
|
163 |
+
);
|
164 |
+
if ( isset( $_REQUEST['relevanssi_show_matches_text'] ) ) {
|
165 |
+
$value = $_REQUEST['relevanssi_show_matches_text'];
|
166 |
+
$value = str_replace( '"', "'", $value );
|
167 |
+
update_option( 'relevanssi_show_matches_text', $value );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
168 |
}
|
169 |
}
|
170 |
|
175 |
update_option( 'relevanssi_synonyms', $value );
|
176 |
}
|
177 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
178 |
$relevanssi_punct = array();
|
179 |
if ( isset( $_REQUEST['relevanssi_punct_quotes'] ) ) {
|
180 |
$relevanssi_punct['quotes'] = $_REQUEST['relevanssi_punct_quotes'];
|
308 |
}
|
309 |
}
|
310 |
|
311 |
+
$options = array(
|
312 |
+
'relevanssi_admin_search' => false,
|
313 |
+
'relevanssi_bg_col' => true,
|
314 |
+
'relevanssi_class' => true,
|
315 |
+
'relevanssi_css' => true,
|
316 |
+
'relevanssi_default_orderby' => true,
|
317 |
+
'relevanssi_disable_or_fallback' => true,
|
318 |
+
'relevanssi_exact_match_bonus' => true,
|
319 |
+
'relevanssi_excerpt_allowable_tags' => true,
|
320 |
+
'relevanssi_excerpt_custom_fields' => true,
|
321 |
+
'relevanssi_excerpt_type' => true,
|
322 |
+
'relevanssi_excerpts' => true,
|
323 |
+
'relevanssi_expand_shortcodes' => false,
|
324 |
+
'relevanssi_expand_highlights' => true,
|
325 |
+
'relevanssi_expst' => true,
|
326 |
+
'relevanssi_fuzzy' => true,
|
327 |
+
'relevanssi_highlight_comments' => true,
|
328 |
+
'relevanssi_highlight_docs' => true,
|
329 |
+
'relevanssi_highlight' => true,
|
330 |
+
'relevanssi_hilite_title' => true,
|
331 |
+
'relevanssi_implicit_operator' => true,
|
332 |
+
'relevanssi_index_author' => false,
|
333 |
+
'relevanssi_index_comments' => false,
|
334 |
+
'relevanssi_index_excerpt' => false,
|
335 |
+
'relevanssi_index_image_files' => false,
|
336 |
+
'relevanssi_log_queries_with_ip' => true,
|
337 |
+
'relevanssi_log_queries' => true,
|
338 |
+
'relevanssi_omit_from_logs' => true,
|
339 |
+
'relevanssi_polylang_all_languages' => true,
|
340 |
+
'relevanssi_respect_exclude' => true,
|
341 |
+
'relevanssi_show_matches' => true,
|
342 |
+
'relevanssi_throttle' => true,
|
343 |
+
'relevanssi_txt_col' => true,
|
344 |
+
'relevanssi_wpml_only_current' => true,
|
345 |
+
);
|
346 |
+
|
|
|
|
|
|
|
347 |
if ( isset( $_REQUEST['relevanssi_expst'] ) ) {
|
348 |
+
$_REQUEST['relevanssi_expst'] = trim( $_REQUEST['relevanssi_expst'], ' ,' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
349 |
}
|
350 |
|
351 |
+
array_walk(
|
352 |
+
$options,
|
353 |
+
function( $autoload, $option ) {
|
354 |
+
if ( isset( $_REQUEST[ $option ] ) ) {
|
355 |
+
update_option( $option, $_REQUEST[ $option ], $autoload );
|
356 |
+
}
|
357 |
+
}
|
358 |
+
);
|
359 |
+
|
360 |
+
relevanssi_update_intval( $_REQUEST, 'relevanssi_excerpt_length', true, 10 );
|
361 |
+
|
362 |
if ( function_exists( 'relevanssi_update_premium_options' ) ) {
|
363 |
relevanssi_update_premium_options();
|
364 |
}
|
771 |
),
|
772 |
array(
|
773 |
'slug' => 'excerpts',
|
774 |
+
'name' => __( 'Excerpts and highlights', 'relevanssi' ),
|
775 |
'require' => 'tabs/excerpts-tab.php',
|
776 |
'callback' => 'relevanssi_excerpts_tab',
|
777 |
'save' => true,
|
797 |
'callback' => 'relevanssi_redirects_tab',
|
798 |
'save' => false,
|
799 |
),
|
800 |
+
array(
|
801 |
+
'slug' => 'debugging',
|
802 |
+
'name' => __( 'Debugging', 'relevanssi' ),
|
803 |
+
'require' => 'tabs/debugging-tab.php',
|
804 |
+
'callback' => 'relevanssi_debugging_tab',
|
805 |
+
'save' => false,
|
806 |
+
),
|
807 |
);
|
808 |
|
809 |
/**
|
1005 |
</tr>
|
1006 |
<?php
|
1007 |
}
|
1008 |
+
|
1009 |
+
/**
|
1010 |
+
* Turns off options, ie. sets them to "off".
|
1011 |
+
*
|
1012 |
+
* If the specified options don't exist in the request array, they are set to
|
1013 |
+
* "off".
|
1014 |
+
*
|
1015 |
+
* @param array $request The _REQUEST array, passed as reference.
|
1016 |
+
* @param array $options An array of option names.
|
1017 |
+
*/
|
1018 |
+
function relevanssi_turn_off_options( &$request, $options ) {
|
1019 |
+
array_walk(
|
1020 |
+
$options,
|
1021 |
+
function( $option ) use ( &$request ) {
|
1022 |
+
if ( ! isset( $request[ $option ] ) ) {
|
1023 |
+
$request[ $option ] = 'off';
|
1024 |
+
}
|
1025 |
+
}
|
1026 |
+
);
|
1027 |
+
}
|
1028 |
+
|
1029 |
+
/**
|
1030 |
+
* Returns 'on' if option exists and value is not 'off', otherwise 'off'.
|
1031 |
+
*
|
1032 |
+
* @param array $request An array of option values.
|
1033 |
+
* @param string $option The key to check.
|
1034 |
+
*
|
1035 |
+
* @return string 'on' or 'off'.
|
1036 |
+
*/
|
1037 |
+
function relevanssi_off_or_on( $request, $option ) {
|
1038 |
+
if ( isset( $request[ $option ] ) && 'off' !== $request[ $option ] ) {
|
1039 |
+
return 'on';
|
1040 |
+
}
|
1041 |
+
return 'off';
|
1042 |
+
}
|
1043 |
+
|
1044 |
+
/**
|
1045 |
+
* Returns an imploded string if the option exists and is an array, an empty
|
1046 |
+
* string otherwise.
|
1047 |
+
*
|
1048 |
+
* @param array $request An array of option values.
|
1049 |
+
* @param string $option The key to check.
|
1050 |
+
* @param string $glue The glue string for implode(), default ','.
|
1051 |
+
*
|
1052 |
+
* @return string Imploded string or an empty string.
|
1053 |
+
*/
|
1054 |
+
function relevanssi_implode( $request, $option, $glue = ',' ) {
|
1055 |
+
if ( isset( $request[ $option ] ) && is_array( $request[ $option ] ) ) {
|
1056 |
+
return implode( $glue, $request[ $option ] );
|
1057 |
+
}
|
1058 |
+
return '';
|
1059 |
+
}
|
1060 |
+
|
1061 |
+
/**
|
1062 |
+
* Returns the intval of the option if it exists, null otherwise.
|
1063 |
+
*
|
1064 |
+
* @param array $request An array of option values.
|
1065 |
+
* @param string $option The key to check.
|
1066 |
+
*
|
1067 |
+
* @return int|null Integer value of the option, or null.
|
1068 |
+
*/
|
1069 |
+
function relevanssi_intval( $request, $option ) {
|
1070 |
+
if ( isset( $request[ $option ] ) ) {
|
1071 |
+
return intval( $request[ $option ] );
|
1072 |
+
}
|
1073 |
+
return null;
|
1074 |
+
}
|
1075 |
+
|
1076 |
+
/**
|
1077 |
+
* Returns a legal value.
|
1078 |
+
*
|
1079 |
+
* @param array $request An array of option values.
|
1080 |
+
* @param string $option The key to check.
|
1081 |
+
* @param array $values The legal values.
|
1082 |
+
* @param string $default The default value.
|
1083 |
+
*
|
1084 |
+
* @return string|null A legal value or the default value, null if the option
|
1085 |
+
* isn't set.
|
1086 |
+
*/
|
1087 |
+
function relevanssi_legal_value( $request, $option, $values, $default ) {
|
1088 |
+
$value = null;
|
1089 |
+
if ( isset( $request[ $option ] ) ) {
|
1090 |
+
$value = $default;
|
1091 |
+
if ( in_array( $request[ $option ], $values, true ) ) {
|
1092 |
+
$value = $request[ $option ];
|
1093 |
+
}
|
1094 |
+
}
|
1095 |
+
return $value;
|
1096 |
+
}
|
1097 |
+
|
1098 |
+
/**
|
1099 |
+
* Sets an on/off option according to the request value.
|
1100 |
+
*
|
1101 |
+
* @param array $request An array of option values.
|
1102 |
+
* @param string $option The key to check.
|
1103 |
+
* @param boolean $autoload Should the option autoload, default true.
|
1104 |
+
*/
|
1105 |
+
function relevanssi_update_off_or_on( $request, $option, $autoload = true ) {
|
1106 |
+
relevanssi_update_legal_value(
|
1107 |
+
$request,
|
1108 |
+
$option,
|
1109 |
+
array( 'off', 'on' ),
|
1110 |
+
'off',
|
1111 |
+
$autoload
|
1112 |
+
);
|
1113 |
+
}
|
1114 |
+
|
1115 |
+
/**
|
1116 |
+
* Sets an option after sanitizing and unslashing the value.
|
1117 |
+
*
|
1118 |
+
* @param array $request An array of option values.
|
1119 |
+
* @param string $option The key to check.
|
1120 |
+
* @param boolean $autoload Should the option autoload, default true.
|
1121 |
+
*/
|
1122 |
+
function relevanssi_update_sanitized( $request, $option, $autoload = true ) {
|
1123 |
+
if ( isset( $request[ $option ] ) ) {
|
1124 |
+
$value = sanitize_text_field( wp_unslash( $request[ $option ] ) );
|
1125 |
+
update_option( $option, $value, $autoload );
|
1126 |
+
}
|
1127 |
+
}
|
1128 |
+
|
1129 |
+
/**
|
1130 |
+
* Sets an option after doing intval.
|
1131 |
+
*
|
1132 |
+
* @param array $request An array of option values.
|
1133 |
+
* @param string $option The key to check.
|
1134 |
+
* @param boolean $autoload Should the option autoload, default true.
|
1135 |
+
* @param int $default The default value if intval() fails, default 0.
|
1136 |
+
*/
|
1137 |
+
function relevanssi_update_intval( $request, $option, $autoload = true, $default = 0 ) {
|
1138 |
+
if ( isset( $request[ $option ] ) ) {
|
1139 |
+
$value = intval( $request[ $option ] );
|
1140 |
+
if ( ! $value ) {
|
1141 |
+
$value = $default;
|
1142 |
+
}
|
1143 |
+
update_option( $option, $value, $autoload );
|
1144 |
+
}
|
1145 |
+
}
|
1146 |
+
|
1147 |
+
/**
|
1148 |
+
* Sets an option after doing floatval.
|
1149 |
+
*
|
1150 |
+
* @param array $request An array of option values.
|
1151 |
+
* @param string $option The key to check.
|
1152 |
+
* @param boolean $autoload Should the option autoload, default true.
|
1153 |
+
* @param int $default The default value if floatval() fails, default 0.
|
1154 |
+
*/
|
1155 |
+
function relevanssi_update_floatval( $request, $option, $autoload = true, $default = 0 ) {
|
1156 |
+
if ( isset( $request[ $option ] ) ) {
|
1157 |
+
$value = floatval( $request[ $option ] );
|
1158 |
+
if ( ! $value ) {
|
1159 |
+
$value = $default;
|
1160 |
+
}
|
1161 |
+
update_option( $option, $value, $autoload );
|
1162 |
+
}
|
1163 |
+
}
|
1164 |
+
|
1165 |
+
/**
|
1166 |
+
* Sets an option with one of the listed legal values.
|
1167 |
+
*
|
1168 |
+
* @param array $request An array of option values.
|
1169 |
+
* @param string $option The key to check.
|
1170 |
+
* @param array $values The legal values.
|
1171 |
+
* @param string $default The default value.
|
1172 |
+
* @param boolean $autoload Should the option autoload, default true.
|
1173 |
+
*/
|
1174 |
+
function relevanssi_update_legal_value( $request, $option, $values, $default, $autoload = true ) {
|
1175 |
+
if ( isset( $request[ $option ] ) ) {
|
1176 |
+
$value = $default;
|
1177 |
+
if ( in_array( $request[ $option ], $values, true ) ) {
|
1178 |
+
$value = $request[ $option ];
|
1179 |
+
}
|
1180 |
+
update_option( $option, $value, $autoload );
|
1181 |
+
}
|
1182 |
+
}
|
lib/search-query-restrictions.php
CHANGED
@@ -36,7 +36,7 @@ function relevanssi_process_query_args( $args ) {
|
|
36 |
}
|
37 |
|
38 |
if ( $args['sentence'] ) {
|
39 |
-
$query =
|
40 |
$query = '"' . $query . '"';
|
41 |
}
|
42 |
|
@@ -79,13 +79,11 @@ function relevanssi_process_query_args( $args ) {
|
|
79 |
$phrase_query_restrictions = $phrases;
|
80 |
}
|
81 |
|
82 |
-
|
83 |
-
$
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
);
|
88 |
-
}
|
89 |
|
90 |
if ( $args['post_status'] ) {
|
91 |
$query_restrictions .= relevanssi_process_post_status( $args['post_status'] );
|
@@ -560,10 +558,17 @@ function relevanssi_process_post_status( $post_status ) {
|
|
560 |
*/
|
561 |
function relevanssi_add_phrase_restrictions( $query_restrictions, $phrase_queries, $term, $operator ) {
|
562 |
if ( 'OR' === $operator ) {
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
567 |
}
|
568 |
} else {
|
569 |
$query_restrictions .= $phrase_queries['and'];
|
36 |
}
|
37 |
|
38 |
if ( $args['sentence'] ) {
|
39 |
+
$query = relevanssi_remove_quotes( $query );
|
40 |
$query = '"' . $query . '"';
|
41 |
}
|
42 |
|
79 |
$phrase_query_restrictions = $phrases;
|
80 |
}
|
81 |
|
82 |
+
$query_restrictions .= relevanssi_process_post_type(
|
83 |
+
$args['post_type'],
|
84 |
+
$args['admin_search'],
|
85 |
+
$args['include_attachments']
|
86 |
+
);
|
|
|
|
|
87 |
|
88 |
if ( $args['post_status'] ) {
|
89 |
$query_restrictions .= relevanssi_process_post_status( $args['post_status'] );
|
558 |
*/
|
559 |
function relevanssi_add_phrase_restrictions( $query_restrictions, $phrase_queries, $term, $operator ) {
|
560 |
if ( 'OR' === $operator ) {
|
561 |
+
$or_queries = array_filter(
|
562 |
+
$phrase_queries['or'],
|
563 |
+
function ( $terms ) use ( $term ) {
|
564 |
+
return relevanssi_stripos( $terms, $term ) !== false;
|
565 |
+
},
|
566 |
+
ARRAY_FILTER_USE_KEY
|
567 |
+
);
|
568 |
+
if ( $or_queries ) {
|
569 |
+
$query_restrictions .= ' AND ( '
|
570 |
+
. implode( ' OR ', array_values( $or_queries ) )
|
571 |
+
. ' ) ';
|
572 |
}
|
573 |
} else {
|
574 |
$query_restrictions .= $phrase_queries['and'];
|
lib/search.php
CHANGED
@@ -497,7 +497,7 @@ function relevanssi_search( $args ) {
|
|
497 |
|
498 |
if ( $exact_match_bonus ) {
|
499 |
$post = relevanssi_get_post( $match->doc );
|
500 |
-
$clean_q =
|
501 |
if ( $post && $clean_q ) {
|
502 |
if ( stristr( $post->post_title, $clean_q ) !== false ) {
|
503 |
$match->weight *= $exact_match_boost['title'];
|
@@ -1529,7 +1529,6 @@ function relevanssi_wp_date_query_from_query_vars( $query ) {
|
|
1529 |
* @return array|boolean The meta query object or false, if no meta query
|
1530 |
* parameters can be parsed.
|
1531 |
*/
|
1532 |
-
|
1533 |
function relevanssi_meta_query_from_query_vars( $query ) {
|
1534 |
$meta_query = false;
|
1535 |
if ( ! empty( $query->query_vars['meta_query'] ) ) {
|
@@ -1585,4 +1584,4 @@ function relevanssi_meta_query_from_query_vars( $query ) {
|
|
1585 |
$meta_query[] = $build_meta_query;
|
1586 |
}
|
1587 |
return $meta_query;
|
1588 |
-
}
|
497 |
|
498 |
if ( $exact_match_bonus ) {
|
499 |
$post = relevanssi_get_post( $match->doc );
|
500 |
+
$clean_q = relevanssi_remove_quotes( $q_no_synonyms );
|
501 |
if ( $post && $clean_q ) {
|
502 |
if ( stristr( $post->post_title, $clean_q ) !== false ) {
|
503 |
$match->weight *= $exact_match_boost['title'];
|
1529 |
* @return array|boolean The meta query object or false, if no meta query
|
1530 |
* parameters can be parsed.
|
1531 |
*/
|
|
|
1532 |
function relevanssi_meta_query_from_query_vars( $query ) {
|
1533 |
$meta_query = false;
|
1534 |
if ( ! empty( $query->query_vars['meta_query'] ) ) {
|
1584 |
$meta_query[] = $build_meta_query;
|
1585 |
}
|
1586 |
return $meta_query;
|
1587 |
+
}
|
lib/tabs/debugging-tab.php
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* /lib/tabs/debugging-tab.php
|
4 |
+
*
|
5 |
+
* Prints out the Debugging tab in Relevanssi settings.
|
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 |
+
/**
|
14 |
+
* Prints out the debugging tab in Relevanssi settings.
|
15 |
+
*/
|
16 |
+
function relevanssi_debugging_tab() {
|
17 |
+
$how_relevanssi_sees = '';
|
18 |
+
$current_post_id = 0;
|
19 |
+
if ( isset( $_REQUEST['post_id'] ) ) {
|
20 |
+
wp_verify_nonce( '_relevanssi_nonce', 'relevanssi_how_relevanssi_sees' );
|
21 |
+
if ( intval( $_REQUEST['post_id'] ) > 0 ) {
|
22 |
+
$current_post_id = intval( $_REQUEST['post_id'] );
|
23 |
+
$how_relevanssi_sees = relevanssi_generate_how_relevanssi_sees( intval( $current_post_id ) );
|
24 |
+
}
|
25 |
+
}
|
26 |
+
wp_nonce_field( 'relevanssi_how_relevanssi_sees', '_relevanssi_nonce', true, true );
|
27 |
+
?>
|
28 |
+
<h2><?php esc_html_e( 'Debugging', 'relevanssi' ); ?></h2>
|
29 |
+
|
30 |
+
<p><?php esc_html_e( 'In order to figure out problems with indexing posts, you can test how Relevanssi sees the post by entering the post ID number in the field below.', 'relevanssi' ); ?></p>
|
31 |
+
<?php // Translators: %1$s starts the link, %2$s closes it. ?>
|
32 |
+
<p><?php printf( esc_html__( 'In Relevanssi Premium, you can find this feature for each post on the post edit page. %1$sBuy Relevanssi Premium here%2$s.', 'relevanssi' ), '<a href="https://www.relevanssi.com/buy-premium/">', '</a>' ); ?></p>
|
33 |
+
<p><label for="post_id"><?php esc_html_e( 'The post ID', 'relevanssi' ); ?></label>:
|
34 |
+
<input type="text" name="post_id" id="post_id"
|
35 |
+
<?php
|
36 |
+
if ( $current_post_id > 0 ) {
|
37 |
+
echo 'value="' . esc_attr( $current_post_id ) . '"';
|
38 |
+
}
|
39 |
+
?>
|
40 |
+
/></p>
|
41 |
+
<p>
|
42 |
+
<input
|
43 |
+
type='submit' name='submit'
|
44 |
+
value='<?php esc_attr_e( 'Check the post', 'relevanssi' ); ?>'
|
45 |
+
class='button button-primary' />
|
46 |
+
</p>
|
47 |
+
<?php echo $how_relevanssi_sees; // phpcs:ignore WordPress.Security.EscapeOutput ?>
|
48 |
+
<?php
|
49 |
+
}
|
lib/tabs/excerpts-tab.php
CHANGED
@@ -29,8 +29,8 @@ function relevanssi_excerpts_tab() {
|
|
29 |
$highlight_coms = get_option( 'relevanssi_highlight_comments' );
|
30 |
$show_matches = get_option( 'relevanssi_show_matches' );
|
31 |
$show_matches_text = get_option( 'relevanssi_show_matches_text' );
|
32 |
-
$word_boundaries = get_option( 'relevanssi_word_boundaries' );
|
33 |
$index_fields = get_option( 'relevanssi_index_fields' );
|
|
|
34 |
|
35 |
if ( '#' !== substr( $txt_col, 0, 1 ) ) {
|
36 |
$txt_col = '#' . $txt_col;
|
@@ -49,7 +49,7 @@ function relevanssi_excerpts_tab() {
|
|
49 |
$highlight_docs = relevanssi_check( $highlight_docs );
|
50 |
$highlight_coms = relevanssi_check( $highlight_coms );
|
51 |
$show_matches = relevanssi_check( $show_matches );
|
52 |
-
$
|
53 |
$excerpt_chars = relevanssi_select( $excerpt_type, 'chars' );
|
54 |
$excerpt_words = relevanssi_select( $excerpt_type, 'words' );
|
55 |
$highlight_none = relevanssi_select( $highlight, 'no' );
|
@@ -136,6 +136,11 @@ function relevanssi_excerpts_tab() {
|
|
136 |
<p class="description"><?php esc_html_e( "Using words is much faster than characters. Don't use characters, unless you have a really good reason and your posts are short.", 'relevanssi' ); ?></p>
|
137 |
</td>
|
138 |
</tr>
|
|
|
|
|
|
|
|
|
|
|
139 |
<tr id="tr_excerpt_allowable_tags"
|
140 |
<?php
|
141 |
if ( empty( $excerpts ) ) {
|
@@ -356,20 +361,20 @@ function relevanssi_excerpts_tab() {
|
|
356 |
</tr>
|
357 |
<tr>
|
358 |
<th scope="row">
|
359 |
-
<?php esc_html_e( '
|
360 |
</th>
|
361 |
<td>
|
362 |
-
<label for='
|
363 |
-
<input type='checkbox' name='
|
364 |
<?php
|
365 |
if ( empty( $excerpts ) ) {
|
366 |
echo "disabled='disabled'";
|
367 |
}
|
368 |
?>
|
369 |
/>
|
370 |
-
<?php esc_html_e( '
|
371 |
</label>
|
372 |
-
<p class="description"><?php esc_html_e(
|
373 |
</td>
|
374 |
</tr>
|
375 |
</table>
|
29 |
$highlight_coms = get_option( 'relevanssi_highlight_comments' );
|
30 |
$show_matches = get_option( 'relevanssi_show_matches' );
|
31 |
$show_matches_text = get_option( 'relevanssi_show_matches_text' );
|
|
|
32 |
$index_fields = get_option( 'relevanssi_index_fields' );
|
33 |
+
$expand_highlights = get_option( 'relevanssi_expand_highlights' );
|
34 |
|
35 |
if ( '#' !== substr( $txt_col, 0, 1 ) ) {
|
36 |
$txt_col = '#' . $txt_col;
|
49 |
$highlight_docs = relevanssi_check( $highlight_docs );
|
50 |
$highlight_coms = relevanssi_check( $highlight_coms );
|
51 |
$show_matches = relevanssi_check( $show_matches );
|
52 |
+
$expand_highlights = relevanssi_check( $expand_highlights );
|
53 |
$excerpt_chars = relevanssi_select( $excerpt_type, 'chars' );
|
54 |
$excerpt_words = relevanssi_select( $excerpt_type, 'words' );
|
55 |
$highlight_none = relevanssi_select( $highlight, 'no' );
|
136 |
<p class="description"><?php esc_html_e( "Using words is much faster than characters. Don't use characters, unless you have a really good reason and your posts are short.", 'relevanssi' ); ?></p>
|
137 |
</td>
|
138 |
</tr>
|
139 |
+
<?php
|
140 |
+
if ( function_exists( 'relevanssi_form_max_excerpts' ) ) {
|
141 |
+
relevanssi_form_max_excerpts( $excerpts );
|
142 |
+
}
|
143 |
+
?>
|
144 |
<tr id="tr_excerpt_allowable_tags"
|
145 |
<?php
|
146 |
if ( empty( $excerpts ) ) {
|
361 |
</tr>
|
362 |
<tr>
|
363 |
<th scope="row">
|
364 |
+
<?php esc_html_e( 'Expand highlights', 'relevanssi' ); ?>
|
365 |
</th>
|
366 |
<td>
|
367 |
+
<label for='relevanssi_expand_highlights'>
|
368 |
+
<input type='checkbox' name='relevanssi_expand_highlights' id='relevanssi_expand_highlights' <?php echo esc_html( $expand_highlights ); ?>
|
369 |
<?php
|
370 |
if ( empty( $excerpts ) ) {
|
371 |
echo "disabled='disabled'";
|
372 |
}
|
373 |
?>
|
374 |
/>
|
375 |
+
<?php esc_html_e( 'Expand highlights to cover full words', 'relevanssi' ); ?>
|
376 |
</label>
|
377 |
+
<p class="description"><?php esc_html_e( 'When a highlight matches part of the word, if this option is enabled, the highlight will be expanded to highlight the whole word.', 'relevanssi' ); ?></p>
|
378 |
</td>
|
379 |
</tr>
|
380 |
</table>
|
lib/uninstall.php
CHANGED
@@ -70,6 +70,7 @@ function relevanssi_uninstall_free() {
|
|
70 |
delete_option( 'relevanssi_excerpt_type' );
|
71 |
delete_option( 'relevanssi_excerpts' );
|
72 |
delete_option( 'relevanssi_exclude_posts' );
|
|
|
73 |
delete_option( 'relevanssi_expand_shortcodes' );
|
74 |
delete_option( 'relevanssi_extag' );
|
75 |
delete_option( 'relevanssi_fuzzy' );
|
@@ -111,7 +112,6 @@ function relevanssi_uninstall_free() {
|
|
111 |
delete_option( 'relevanssi_title_boost' );
|
112 |
delete_option( 'relevanssi_trim_logs' );
|
113 |
delete_option( 'relevanssi_txt_col' );
|
114 |
-
delete_option( 'relevanssi_word_boundaries' );
|
115 |
delete_option( 'relevanssi_wpml_only_current' );
|
116 |
|
117 |
// Unused options, removed in case they are still left.
|
@@ -130,6 +130,7 @@ function relevanssi_uninstall_free() {
|
|
130 |
delete_option( 'relevanssi_custom_taxonomies' );
|
131 |
delete_option( 'relevanssi_taxonomies_to_index' );
|
132 |
delete_option( 'relevanssi_highlight_docs_external' );
|
|
|
133 |
|
134 |
global $wpdb;
|
135 |
$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_noindex_reason'" );
|
70 |
delete_option( 'relevanssi_excerpt_type' );
|
71 |
delete_option( 'relevanssi_excerpts' );
|
72 |
delete_option( 'relevanssi_exclude_posts' );
|
73 |
+
delete_option( 'relevanssi_expand_highlights' );
|
74 |
delete_option( 'relevanssi_expand_shortcodes' );
|
75 |
delete_option( 'relevanssi_extag' );
|
76 |
delete_option( 'relevanssi_fuzzy' );
|
112 |
delete_option( 'relevanssi_title_boost' );
|
113 |
delete_option( 'relevanssi_trim_logs' );
|
114 |
delete_option( 'relevanssi_txt_col' );
|
|
|
115 |
delete_option( 'relevanssi_wpml_only_current' );
|
116 |
|
117 |
// Unused options, removed in case they are still left.
|
130 |
delete_option( 'relevanssi_custom_taxonomies' );
|
131 |
delete_option( 'relevanssi_taxonomies_to_index' );
|
132 |
delete_option( 'relevanssi_highlight_docs_external' );
|
133 |
+
delete_option( 'relevanssi_word_boundaries' );
|
134 |
|
135 |
global $wpdb;
|
136 |
$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_noindex_reason'" );
|
readme.txt
CHANGED
@@ -3,9 +3,9 @@ Contributors: msaari
|
|
3 |
Donate link: https://www.relevanssi.com/buy-premium/
|
4 |
Tags: search, relevance, better search, product search, woocommerce search
|
5 |
Requires at least: 4.9
|
6 |
-
Tested up to: 5.5.
|
7 |
Requires PHP: 7.0
|
8 |
-
Stable tag: 4.
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
@@ -133,6 +133,23 @@ Each document database is full of useless words. All the little words that appea
|
|
133 |
* John Calahan for extensive 4.0 beta testing.
|
134 |
|
135 |
== Changelog ==
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
136 |
= 4.8.3 =
|
137 |
* New feature: Both `relevanssi_fuzzy_query` and `relevanssi_term_where` now get the current search term as a parameter.
|
138 |
* Minor fix: Relevanssi database tables don't have PRIMARY keys, only UNIQUE keys. In case this is a problem (for example on Digital Ocean servers), deactivate and activate Relevanssi to fix the problem.
|
@@ -186,6 +203,9 @@ Each document database is full of useless words. All the little words that appea
|
|
186 |
* Minor fix: User Access Manager showed drafts in search results for all users. This is now fixed.
|
187 |
|
188 |
== Upgrade notice ==
|
|
|
|
|
|
|
189 |
= 4.8.3 =
|
190 |
* Small bug fixes and database improvements.
|
191 |
|
3 |
Donate link: https://www.relevanssi.com/buy-premium/
|
4 |
Tags: search, relevance, better search, product search, woocommerce search
|
5 |
Requires at least: 4.9
|
6 |
+
Tested up to: 5.5.3
|
7 |
Requires PHP: 7.0
|
8 |
+
Stable tag: 4.9.0
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
133 |
* John Calahan for extensive 4.0 beta testing.
|
134 |
|
135 |
== Changelog ==
|
136 |
+
= 4.9.0 =
|
137 |
+
* New feature: There's now a "Debugging" tab in the Relevanssi settings, letting you see how the Relevanssi index sees posts. This is familiar to Premium users, but is now available in the free version as well.
|
138 |
+
* New feature: The SEO Framework plugin is now supported and posts set excluded from the search in SEO Framework settings will be excluded from the index.
|
139 |
+
* New feature: There's a new option, "Expand highlights". Enabling it makes Relevanssi expand partial-word highlights to cover the full word. This is useful when doing partial matching and when using a stemmer.
|
140 |
+
* New feature: New filter hook `relevanssi_excerpt_part` allows you to modify the excerpt parts before they are combined together. This doesn't do much in the free version.
|
141 |
+
* New feature: Improved compatibility with Oxygen Builder. Relevanssi automatically indexes the Oxygen Builder content and cleans it up. New filter hooks `relevanssi_oxygen_section_filters` and `relevanssi_oxygen_section_content` allow easier filtering of Oxygen content to eg. remove unwanted sections.
|
142 |
+
* Changed behaviour: The "Uncheck this for non-ASCII highlights" option has been removed. Highlights are now done in a slightly different way that should work in all cases, including for example Cyrillic text, thus this option is no longer necessary.
|
143 |
+
* Minor fix: Fixes phrase searching using non-US alphabet.
|
144 |
+
* Minor fix: Relevanssi would break admin searching for hierarchical post types. This is now fixed, Relevanssi won't do that anymore.
|
145 |
+
* Minor fix: Relevanssi indexing now survives better shortcodes that change the global `$post`.
|
146 |
+
* Minor fix: Warnings about missing `relevanssi_update_counts` function are now removed.
|
147 |
+
* Minor fix: Paid Membership Pro support now takes notice of the "filter queries" setting.
|
148 |
+
* Minor fix: OR logic didn't work correctly when two phrases both had the same word (for example "freedom of speech" and "free speech"). The search would always be an AND search in those cases. That has been fixed.
|
149 |
+
* Minor fix: Relevanssi no longer blocks the Pretty Links admin page search.
|
150 |
+
* Minor fix: The "Respect 'exclude_from_search'" setting did not work if no post type parameter was included in the search parameters.
|
151 |
+
* Minor fix: The category inclusion and exclusion setting checkboxes on the Searching tab didn't work. The setting was saved, but the checkboxes wouldn't appear.
|
152 |
+
|
153 |
= 4.8.3 =
|
154 |
* New feature: Both `relevanssi_fuzzy_query` and `relevanssi_term_where` now get the current search term as a parameter.
|
155 |
* Minor fix: Relevanssi database tables don't have PRIMARY keys, only UNIQUE keys. In case this is a problem (for example on Digital Ocean servers), deactivate and activate Relevanssi to fix the problem.
|
203 |
* Minor fix: User Access Manager showed drafts in search results for all users. This is now fixed.
|
204 |
|
205 |
== Upgrade notice ==
|
206 |
+
= 4.9.0 =
|
207 |
+
* New debugging feature, lots of minor fixes.
|
208 |
+
|
209 |
= 4.8.3 =
|
210 |
* Small bug fixes and database improvements.
|
211 |
|
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
|
@@ -67,7 +67,7 @@ $relevanssi_variables['database_version'] = 5;
|
|
67 |
$relevanssi_variables['file'] = __FILE__;
|
68 |
$relevanssi_variables['plugin_dir'] = plugin_dir_path( __FILE__ );
|
69 |
$relevanssi_variables['plugin_basename'] = plugin_basename( __FILE__ );
|
70 |
-
$relevanssi_variables['plugin_version'] = '4.
|
71 |
|
72 |
require_once 'lib/admin-ajax.php';
|
73 |
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.9.0
|
17 |
* Author: Mikko Saari
|
18 |
* Author URI: http://www.mikkosaari.fi/
|
19 |
* Text Domain: relevanssi
|
67 |
$relevanssi_variables['file'] = __FILE__;
|
68 |
$relevanssi_variables['plugin_dir'] = plugin_dir_path( __FILE__ );
|
69 |
$relevanssi_variables['plugin_basename'] = plugin_basename( __FILE__ );
|
70 |
+
$relevanssi_variables['plugin_version'] = '4.9.0';
|
71 |
|
72 |
require_once 'lib/admin-ajax.php';
|
73 |
require_once 'lib/common.php';
|