plugin updates

This commit is contained in:
Tony Volpe
2024-06-17 15:33:26 -04:00
parent 3751a5a1a6
commit e4e274a9a7
2674 changed files with 0 additions and 507851 deletions

View File

@@ -1,284 +0,0 @@
<?php
/**
* /lib/compatibility/acf.php
*
* Advanced Custom Fields compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_action( 'acf/render_field_settings', 'relevanssi_acf_exclude_setting' );
add_filter( 'relevanssi_search_ok', 'relevanssi_acf_relationship_fields' );
add_filter( 'relevanssi_index_custom_fields', 'relevanssi_acf_exclude_fields', 10, 2 );
/**
* Disables Relevanssi in the ACF Relationship field post search.
*
* We don't want to use Relevanssi on the ACF Relationship field post searches, so
* this function disables it (on the 'relevanssi_search_ok' hook).
*
* @param boolean $search_ok Block the search or not.
*
* @return boolean False, if this is an ACF Relationship field search, pass the
* parameter unchanged otherwise.
*/
function relevanssi_acf_relationship_fields( $search_ok ) {
// phpcs:disable WordPress.Security.NonceVerification
if ( isset( $_REQUEST['action'] )
&& is_string( $_REQUEST['action'] )
&& 'acf' === substr( $_REQUEST['action'], 0, 3 ) ) {
$search_ok = false;
}
return $search_ok;
}
/**
* Indexes the human-readable value of "choice" options list from ACF.
*
* @author Droz Raphaël
*
* @param array $insert_data The insert data array.
* @param int $post_id The post ID.
* @param string $field_name Name of the field.
* @param string $field_value The field value.
*
* @return int Number of tokens indexed.
*/
function relevanssi_index_acf( &$insert_data, $post_id, $field_name, $field_value ) {
if ( ! is_admin() ) {
include_once ABSPATH . 'wp-admin/includes/plugin.php'; // Otherwise is_plugin_active() will cause a fatal error.
}
if ( ! function_exists( 'is_plugin_active' ) ) {
return 0;
}
if ( ! is_plugin_active( 'advanced-custom-fields/acf.php' ) && ! is_plugin_active( 'advanced-custom-fields-pro/acf.php' ) ) {
return 0;
}
if ( ! function_exists( 'get_field_object' ) ) {
return 0; // ACF is active, but not loaded.
}
$field_object = get_field_object( $field_name, $post_id );
if ( ! isset( $field_object['choices'] ) ) {
return 0; // Not a "select" field.
}
if ( is_array( $field_value ) ) {
return 0; // Not handled (currently).
}
if ( ! isset( $field_object['choices'][ $field_value ] ) ) {
return 0; // Value does not exist.
}
$n = 0;
/**
* Filters the field value before it is used to save the insert data.
*
* The value is used as an array key, so it needs to be an integer or a
* string. If your custom field values are arrays or objects, use this
* filter hook to convert them into strings.
*
* @param mixed $field_content The ACF field value.
* @param string $field_name The ACF field name.
* @param int $post_id The post ID.
*
* @return string|int The field value.
*/
$value = apply_filters(
'relevanssi_acf_field_value',
$field_object['choices'][ $field_value ],
$field_name,
$post_id
);
if ( $value && ( is_integer( $value ) || is_string( $value ) ) ) {
$min_word_length = get_option( 'relevanssi_min_word_length', 3 );
/** This filter is documented in lib/indexing.php */
$value_tokens = apply_filters( 'relevanssi_indexing_tokens', relevanssi_tokenize( $value, true, $min_word_length, 'indexing' ), 'custom_field' );
foreach ( $value_tokens as $token => $count ) {
++$n;
if ( ! isset( $insert_data[ $token ]['customfield'] ) ) {
$insert_data[ $token ]['customfield'] = 0;
}
$insert_data[ $token ]['customfield'] += $count;
// Premium indexes more detail about custom fields.
if ( function_exists( 'relevanssi_customfield_detail' ) ) {
$insert_data = relevanssi_customfield_detail( $insert_data, $token, $count, $field_name );
}
}
}
return $n;
}
/**
* Adds a Relevanssi exclude setting to ACF fields.
*
* @param array $field The field object array.
*/
function relevanssi_acf_exclude_setting( $field ) {
if ( ! function_exists( 'acf_render_field_setting' ) ) {
return;
}
if ( 'clone' === $field['type'] ) {
return;
}
acf_render_field_setting(
$field,
array(
'label' => __( 'Exclude from Relevanssi index', 'relevanssi' ),
'instructions' => __( 'If this setting is enabled, Relevanssi will not index the value of this field for posts.', 'relevanssi' ),
'name' => 'relevanssi_exclude',
'type' => 'true_false',
'ui' => 1,
),
true
);
}
/**
* Excludes ACF fields based on the exclude setting.
*
* Hooks on to relevanssi_index_custom_fields.
*
* @param array $fields The list of custom fields to index.
* @param int $post_id The post ID.
*
* @return array Filtered list of custom fields.
*/
function relevanssi_acf_exclude_fields( $fields, $post_id ) {
$included_fields = array();
$excluded_fields = array();
/**
* Filters the types of ACF fields to exclude from indexing.
*
* By default, blocks 'repeater', 'flexible_content' and 'group' are
* excluded from Relevanssi indexing. You can add other field types here.
*
* @param array $excluded_field_types The field types to exclude.
*/
$blocked_field_types = apply_filters(
'relevanssi_blocked_field_types',
array( 'repeater', 'flexible_content', 'group' )
);
global $post;
foreach ( $fields as $field ) {
$global_post = $post; // ACF fields can change the global $post.
$field_object = get_field_object( $field );
$post = $global_post; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
if ( ! $field_object || ! is_array( $field_object ) ) {
$field_id = relevanssi_acf_get_field_id( $field, $post_id );
if ( ! $field_id ) {
// No field ID -> not an ACF field. Include.
$included_fields[] = $field;
} else {
/*
* This field has a field ID, but get_field_object() does not
* return a field object. This may be a clone field, in which
* case we can try to get the field object from the field ID.
* Clone fields have keys like field_xxx_field_yyy, where the
* field_yyy is the part we need.
*/
$field_id = preg_replace( '/.*_(field_.*)/', '$1', $field_id );
$field_object = get_field_object( $field_id );
}
}
if ( $field_object ) {
/**
* Filters the ACF field object.
*
* If the filter returns a false value, Relevanssi will not index
* the field.
*
* @param array $field_object The field object.
* @param int $post_id The post ID.
*
* @return array The filtered field object.
*/
$field_object = apply_filters(
'relevanssi_acf_field_object',
$field_object,
$post_id
);
if ( ! $field_object ) {
continue;
}
if ( isset( $field_object['relevanssi_exclude'] ) && 1 === $field_object['relevanssi_exclude'] ) {
continue;
}
if ( relevanssi_acf_is_parent_excluded( $field_object ) ) {
continue;
}
if ( isset( $field_object['type'] ) && in_array( $field_object['type'], $blocked_field_types, true ) ) {
continue;
}
$included_fields[] = $field;
}
}
return $included_fields;
}
/**
* Checks if the field has an excluded parent field.
*
* If the field has a "parent" value set, this function gets the parent field
* post based on the post ID in the "parent" value. This is done recursively
* until we reach the top or find an excluded parent.
*
* @param array $field_object The field object.
*
* @return bool Returns true if the post has an excluded parent.
*/
function relevanssi_acf_is_parent_excluded( $field_object ) {
if ( isset( $field_object['parent'] ) ) {
$parent = $field_object['parent'];
if ( $parent ) {
$parent_field_post = get_post( $parent );
if ( $parent_field_post ) {
$parent_object = get_field_object( $parent_field_post->post_name );
if ( $parent_object ) {
if ( isset( $parent_object['relevanssi_exclude'] ) && 1 === $parent_object['relevanssi_exclude'] ) {
return true;
}
return relevanssi_acf_is_parent_excluded( $parent_object );
}
}
}
}
return false;
}
/**
* Gets the field ID from the field name.
*
* The field ID is stored in the postmeta table with the field name prefixed
* with an underscore as the key.
*
* @param string $field_name The field name.
* @param int $post_id The post ID.
*
* @return string The field ID.
*/
function relevanssi_acf_get_field_id( $field_name, $post_id ) {
global $wpdb;
$field_id = $wpdb->get_var(
$wpdb->prepare(
"SELECT meta_value FROM $wpdb->postmeta
WHERE post_id = %d
AND meta_key = %s",
$post_id,
'_' . $field_name
)
);
return $field_id;
}

View File

@@ -1,108 +0,0 @@
<?php
/**
* /lib/compatibility/aioseo.php
*
* All-in-One SEO noindex filtering function.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_do_not_index', 'relevanssi_aioseo_noindex', 10, 2 );
add_filter( 'relevanssi_indexing_restriction', 'relevanssi_aioseo_exclude' );
add_action( 'relevanssi_indexing_tab_advanced', 'relevanssi_aioseo_form', 20 );
add_action( 'relevanssi_indexing_options', 'relevanssi_aioseo_options' );
/**
* Blocks indexing of posts marked "noindex" in the All-in-One SEO settings.
*
* Attaches to the 'relevanssi_do_not_index' filter hook.
*
* @param boolean $do_not_index True, if the post shouldn't be indexed.
* @param integer $post_id The post ID number.
*
* @return string|boolean If the post shouldn't be indexed, this returns
* 'aioseo_seo'. The value may also be a boolean.
*/
function relevanssi_aioseo_noindex( bool $do_not_index, int $post_id ) {
if ( 'on' !== get_option( 'relevanssi_seo_noindex' ) ) {
return $do_not_index;
}
$noindex_posts = relevanssi_aioseo_get_noindex_posts();
if ( in_array( $post_id, $noindex_posts, true ) ) {
$do_not_index = 'All-in-One SEO';
}
return $do_not_index;
}
/**
* Excludes the "noindex" posts from Relevanssi indexing.
*
* Adds a MySQL query restriction that blocks posts that have the aioseo SEO
* "noindex" setting set to "1" from indexing.
*
* @param array $restriction An array with two values: 'mysql' for the MySQL
* query restriction to modify, 'reason' for the reason of restriction.
*/
function relevanssi_aioseo_exclude( array $restriction ) {
if ( 'on' !== get_option( 'relevanssi_seo_noindex' ) ) {
return $restriction;
}
global $wpdb;
$restriction['mysql'] .= " AND post.ID NOT IN (SELECT post_id FROM
{$wpdb->prefix}aioseo_posts WHERE robots_noindex = '1' ) ";
$restriction['reason'] .= ' All-in-One SEO';
return $restriction;
}
/**
* Fetches the post IDs where robots_noindex is set to 1 in the aioseo_posts
* table.
*
* @return array An array of post IDs.
*/
function relevanssi_aioseo_get_noindex_posts() {
global $wpdb, $relevanssi_aioseo_noindex_cache;
if ( ! empty( $relevanssi_aioseo_noindex_cache ) ) {
return $relevanssi_aioseo_noindex_cache;
}
$relevanssi_aioseo_noindex_cache = $wpdb->get_col( "SELECT post_id FROM {$wpdb->prefix}aioseo_posts WHERE 'robots_noindex' = '1'" );
return $relevanssi_aioseo_noindex_cache;
}
/**
* Prints out the form fields for disabling the feature.
*/
function relevanssi_aioseo_form() {
$seo_noindex = get_option( 'relevanssi_seo_noindex' );
$seo_noindex = relevanssi_check( $seo_noindex );
?>
<tr>
<th scope="row">
<label for='relevanssi_seo_noindex'><?php esc_html_e( 'Use All-in-One SEO noindex', 'relevanssi' ); ?></label>
</th>
<td>
<label for='relevanssi_seo_noindex'>
<input type='checkbox' name='relevanssi_seo_noindex' id='relevanssi_seo_noindex' <?php echo esc_attr( $seo_noindex ); ?> />
<?php esc_html_e( 'Use All-in-One SEO noindex.', 'relevanssi' ); ?>
</label>
<p class="description"><?php esc_html_e( 'If checked, Relevanssi will not index posts marked as "No index" in All-in-One SEO settings.', 'relevanssi' ); ?></p>
</td>
</tr>
<?php
}
/**
* Saves the SEO No index option.
*
* @param array $request An array of option values from the request.
*/
function relevanssi_aioseo_options( array $request ) {
relevanssi_update_off_or_on( $request, 'relevanssi_seo_noindex', true );
}

View File

@@ -1,19 +0,0 @@
<?php
/**
* /lib/compatibility/avada.php
*
* Avada theme compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter(
'fusion_live_search_query_args',
function ( $args ) {
$args['relevanssi'] = true;
return $args;
}
);

View File

@@ -1,97 +0,0 @@
<?php
/**
* /lib/compatibility/bricks.php
*
* Bricks theme compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'bricks/posts/query_vars', 'relevanssi_bricks_enable', 10 );
add_filter( 'relevanssi_custom_field_value', 'relevanssi_bricks_values', 10, 2 );
add_filter( 'relevanssi_index_custom_fields', 'relevanssi_add_bricks' );
add_filter( 'option_relevanssi_index_fields', 'relevanssi_bricks_fix_none_setting' );
add_action( 'save_post', 'relevanssi_insert_edit', 99, 1 );
/**
* Enables Relevanssi in the query when the 's' query var is set.
*
* @param array $query_vars The query variables.
*
* @return array The query variables with the Relevanssi toggle enabled.
*/
function relevanssi_bricks_enable( $query_vars ) {
if ( isset( $query_vars['s'] ) ) {
$query_vars['relevanssi'] = true;
}
return $query_vars;
}
/**
* Adds the `_bricks_page_content_2` to the list of indexed custom fields.
*
* @param array|boolean $fields An array of custom fields to index, or false.
*
* @return array An array of custom fields, including `_bricks_page_content_2`.
*/
function relevanssi_add_bricks( $fields ) {
if ( ! is_array( $fields ) ) {
$fields = array();
}
if ( ! in_array( '_bricks_page_content_2', $fields, true ) ) {
$fields[] = '_bricks_page_content_2';
}
return $fields;
}
/**
* Includes only text from _bricks_page_content_2 custom field.
*
* This function goes through the multilevel array of _bricks_page_content_2
* and only picks up the "text" elements inside it, discarding everything else.
*
* @param array $value An array of custom field values.
* @param string $field The name of the custom field.
*
* @return array An array containing a string with all the values concatenated
* together.
*/
function relevanssi_bricks_values( $value, $field ) {
if ( '_bricks_page_content_2' !== $field ) {
return $value;
}
$content = '';
array_walk_recursive(
$value,
function ( $text, $key ) use ( &$content ) {
if ( 'text' === $key ) {
$content .= ' ' . $text;
}
}
);
return array( $content );
}
/**
* Makes sure the Bricks builder shortcode is included in the index, even when
* the custom field setting is set to 'none'.
*
* @param string $value The custom field indexing setting value. The parameter
* is ignored, Relevanssi disables this filter and then checks the option to
* see what the value is.
*
* @return string If value is undefined, it's set to '_bricks_page_content_2'.
*/
function relevanssi_bricks_fix_none_setting( $value ) {
if ( ! $value ) {
$value = '_bricks_page_content_2';
}
return $value;
}

View File

@@ -1,28 +0,0 @@
<?php
/**
* /lib/compatibility/elementor.php
*
* Elementor page builder compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_search_ok', 'relevanssi_block_elementor_library', 10, 2 );
/**
* Blocks Relevanssi from interfering with the Elementor Library searches.
*
* @param bool $ok Should Relevanssi be allowed to process the query.
* @param WP_Query $query The WP_Query object.
*
* @return bool Returns false, if this is an Elementor library search.
*/
function relevanssi_block_elementor_library( bool $ok, WP_Query $query ): bool {
if ( 'elementor_library' === $query->query_vars['post_type'] ) {
$ok = false;
}
return $ok;
}

View File

@@ -1,27 +0,0 @@
<?php
/**
* /lib/compatibility/fibosearch.php
*
* Fibo Search compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'dgwt/wcas/search_query/args', 'relevanssi_enable_relevanssi_in_fibo' );
/**
* Adds the 'relevanssi' parameter to the Fibo Search.
*
* Uses the dgwt/wcas/search_query_args filter hook to modify the search query.
*
* @param array $args The search arguments.
*
* @return array
*/
function relevanssi_enable_relevanssi_in_fibo( $args ) {
$args['relevanssi'] = true;
return $args;
}

View File

@@ -1,36 +0,0 @@
<?php
/**
* /lib/compatibility/groups.php
*
* Groups compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_post_ok', 'relevanssi_groups_compatibility', 10, 2 );
/**
* Checks whether the user is allowed to see the post.
*
* Only applies to published posts.
*
* @param boolean $post_ok Can the post be shown to the user.
* @param int $post_id The post ID.
*
* @return boolean $post_ok True if the user is allowed to see the post,
* otherwise false.
*/
function relevanssi_groups_compatibility( $post_ok, $post_id ) {
$status = relevanssi_get_post_status( $post_id );
if ( 'publish' === $status ) {
// Only apply to published posts, don't apply to drafts.
$current_user = wp_get_current_user();
$post_ok = Groups_Post_Access::user_can_read_post( $post_id, $current_user->ID );
}
return $post_ok;
}

View File

@@ -1,173 +0,0 @@
<?php
/**
* /lib/compatibility/gutenberg.php
*
* Gutenberg compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_post_content', 'relevanssi_gutenberg_block_rendering', 10, 2 );
/**
* Registers rest_after_insert_{post_type} actions for all indexed post types.
*
* Runs on `admin_init` action hook and registers the function
* `relevanssi_save_gutenberg_postdata` for all indexed post types.
*
* @see relevanssi_save_gutenberg_postdata
*/
function relevanssi_register_gutenberg_actions() {
if ( ! RELEVANSSI_PREMIUM ) {
return;
}
$index_post_types = get_option( 'relevanssi_index_post_types', array() );
array_walk(
$index_post_types,
function ( $post_type ) {
if ( 'bogus' !== $post_type ) {
add_action(
'rest_after_insert_' . $post_type,
'relevanssi_save_gutenberg_postdata'
);
}
}
);
}
/**
* Renders Gutenberg blocks.
*
* Renders all sorts of Gutenberg blocks, including reusable blocks and ACF
* blocks. Also enables basic Gutenberg deindexing: you can add an extra CSS
* class 'relevanssi_noindex' to a block to stop it from being indexed by
* Relevanssi. This function is essentially the same as core do_blocks().
*
* @see do_blocks()
*
* @param string $content The post content.
* @param object $post_object The post object.
*
* @return string The post content with the rendered content added.
*/
function relevanssi_gutenberg_block_rendering( $content, $post_object ) {
/**
* Filters whether the blocks are rendered or not.
*
* If this filter returns false, the blocks in this post are not rendered,
* and the post content is returned as such.
*
* @param boolean If true, render the blocks. Default true.
* @param object The post object.
*/
if ( ! apply_filters( 'relevanssi_render_blocks', true, $post_object ) ) {
return $content;
}
$blocks = parse_blocks( $content );
$output = '';
foreach ( $blocks as $block ) {
/**
* Filters the Gutenberg block before it is rendered.
*
* If the block is non-empty after the filter and it's className
* parameter is not 'relevanssi_noindex', it will be passed on to the
* render_block() function for rendering.
*
* @see render_block
*
* @param array $block The Gutenberg block element.
*/
$block = apply_filters( 'relevanssi_block_to_render', $block );
if ( ! $block ) {
continue;
}
if (
isset( $block['attrs']['className'] )
&& false !== strstr( $block['attrs']['className'], 'relevanssi_noindex' )
) {
continue;
}
$block = relevanssi_process_inner_blocks( $block );
/**
* Filters the Gutenberg block after it is rendered.
*
* The value is the output from render_block( $block ). Feel free to
* modify it as you wish.
*
* @see render_block
*
* @param string The rendered block content.
* @param array $block The Gutenberg block being rendered.
*
* @return string The filtered block content.
*/
$output .= apply_filters( 'relevanssi_rendered_block', render_block( $block ), $block );
}
// If there are blocks in this content, we shouldn't run wpautop() on it later.
$priority = has_filter( 'the_content', 'wpautop' );
if ( false !== $priority && doing_filter( 'the_content' ) && has_blocks( $content ) ) {
remove_filter( 'the_content', 'wpautop', $priority );
add_filter( 'the_content', '_restore_wpautop_hook', $priority + 1 );
}
return $output;
}
/**
* Runs recursively through inner blocks to filter them.
*
* Runs relevanssi_block_to_render and the relevanssi_noindex CSS class check
* on all inner blocks. If inner blocks are filtered out, they will be removed
* with empty blocks of the type "core/fake". Removing the inner blocks causes
* problems; that's why they are replaced. The blocks are rendered here;
* everything will be rendered once at the top level.
*
* @param array $block A Gutenberg block.
*
* @return array The filtered block.
*/
function relevanssi_process_inner_blocks( $block ) {
$innerblocks_to_keep = array();
$empty_block = array(
'blockName' => 'core/fake',
'attrs' => array(),
'innerHTML' => '',
'innerBlocks' => array(),
);
foreach ( $block['innerBlocks'] as $inner_block ) {
/* Filter documented in /lib/compatibility/gutenberg.php. */
$inner_block = apply_filters( 'relevanssi_block_to_render', $inner_block );
if ( ! $inner_block ) {
$innerblocks_to_keep[] = $empty_block;
continue;
}
if (
isset( $inner_block['attrs']['className'] )
&& false !== strstr( $inner_block['attrs']['className'], 'relevanssi_noindex' )
) {
$innerblocks_to_keep[] = $empty_block;
continue;
}
$inner_block = relevanssi_process_inner_blocks( $inner_block );
$innerblocks_to_keep[] = $inner_block;
}
$block['innerBlocks'] = $innerblocks_to_keep;
return $block;
}

View File

@@ -1,47 +0,0 @@
<?php
/**
* /lib/compatibility/jetsmartfilters.php
*
* JetSmartFilters compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_action( 'pre_get_posts', 'relevanssi_jetsmartfilters', 9999 );
/**
* Makes JetSmartFilters use posts from Relevanssi.
*
* @param WP_Query $wp_query The wp_query object.
*/
function relevanssi_jetsmartfilters( $wp_query ) {
if (
! isset( $wp_query->query['jet_smart_filters'] )
|| empty( $wp_query->query['s'] )
) {
return;
}
$args = array(
's' => $wp_query->query['s'],
'fields' => 'ids',
'posts_per_page' => -1,
'relevanssi' => true,
);
$relevanssi_query = new WP_Query( $args );
$results = ! empty( $relevanssi_query->posts )
? $relevanssi_query->posts
: array( 0 );
$wp_query->set( 'post__in', $results );
$wp_query->set( 'post_type', 'any' );
$wp_query->set( 'post_status', 'any' );
$wp_query->set( 'orderby', 'post__in' );
$wp_query->set( 'order', 'DESC' );
$wp_query->set( 's', false );
}

View File

@@ -1,31 +0,0 @@
<?php
/**
* /lib/compatibility/memberpress.php
*
* Memberpress compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_post_ok', 'relevanssi_memberpress_compatibility', 10, 2 );
/**
* Checks whether the user is allowed to see the post.
*
* @param boolean $post_ok Can the post be shown to the user.
* @param int $post_id The post ID.
*
* @return boolean $post_ok True if the user is allowed to see the post,
* otherwise false.
*/
function relevanssi_memberpress_compatibility( $post_ok, $post_id ) {
$post = get_post( $post_id );
if ( MeprRule::is_locked( $post ) ) {
$post_ok = false;
}
return $post_ok;
}

View File

@@ -1,37 +0,0 @@
<?php
/**
* /lib/compatibility/members.php
*
* Members compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_post_ok', 'relevanssi_members_compatibility', 10, 2 );
/**
* Checks whether the user is allowed to see the post.
*
* Only applies to private posts and only if the "content permissions" feature
* is enabled.
*
* @param boolean $post_ok Can the post be shown to the user.
* @param int $post_id The post ID.
*
* @return boolean $post_ok True if the user is allowed to see the post,
* otherwise false.
*/
function relevanssi_members_compatibility( $post_ok, $post_id ) {
$status = relevanssi_get_post_status( $post_id );
if ( 'private' === $status ) {
if ( members_content_permissions_enabled() ) {
$post_ok = members_can_current_user_view_post( $post_id );
}
}
return $post_ok;
}

View File

@@ -1,101 +0,0 @@
<?php
/**
* /lib/compatibility/ninjatables.php
*
* Ninja Tables compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_post_content', 'relevanssi_index_ninja_tables' );
/**
* Indexes Ninja Tables table contents.
*
* Uses regular expression matching to find all the Ninja Tables shortcodes in
* the post content and then uses relevanssi_index_ninja_table() to convert the
* tables into strings.
*
* @uses $wpdb WordPress database abstraction.
* @see relevanssi_index_ninja_table()
*
* @param string $content The post content.
*
* @return string Post content with the Ninja Tables data.
*/
function relevanssi_index_ninja_tables( $content ) {
$m = preg_match_all(
'/.*\[ninja_tables.*?id=["\'](\d+)["\'].*?\]/im',
$content,
$matches,
PREG_PATTERN_ORDER
);
if ( ! $m ) {
return $content;
}
foreach ( $matches[1] as $table_id ) {
$content .= ' ' . relevanssi_index_ninja_table( $table_id );
}
return $content;
}
/**
* Creates a string containing a Ninja Table table contents.
*
* The string contains the caption and the values from each row. The table
* title and description are also included, if they are set visible on the
* frontend.
*
* @uses $wpdb WordPress database abstraction.
*
* @param int $table_id The table ID.
*
* @return string The table content as a string.
*/
function relevanssi_index_ninja_table( $table_id ) {
global $wpdb;
$table_post = get_post( $table_id );
$table_settings = get_post_meta( $table_id, '_ninja_table_settings', true );
$table_contents = '';
if ( isset( $table_settings['show_description'] ) && '1' === $table_settings['show_description'] ) {
$table_contents .= ' ' . $table_post->post_content;
}
if ( isset( $table_settings['show_title'] ) && '1' === $table_settings['show_title'] ) {
$table_contents .= ' ' . $table_post->post_title;
}
$table_contents .= ' ' . get_post_meta( $table_id, '_ninja_table_caption', true );
$rows = $wpdb->get_results(
$wpdb->prepare(
"SELECT value FROM {$wpdb->prefix}ninja_table_items WHERE table_id=%d",
$table_id
)
);
foreach ( $rows as $row ) {
if ( empty( $row->value ) ) {
continue;
}
$json_decoded = json_decode( $row->value );
if ( ! is_object( $json_decoded ) ) {
continue;
}
$array_values = array_map(
function ( $value ) {
if ( is_object( $value ) ) {
return '';
}
return strval( $value );
},
array_values( get_object_vars( $json_decoded ) )
);
$table_contents .= ' ' . implode( ' ', $array_values );
}
return $table_contents;
}

View File

@@ -1,259 +0,0 @@
<?php
/**
* /lib/compatibility/oxygen.php
*
* Oxygen Builder compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_custom_field_value', 'relevanssi_oxygen_compatibility', 10, 3 );
add_filter( 'relevanssi_index_custom_fields', 'relevanssi_add_oxygen' );
add_filter( 'option_relevanssi_index_fields', 'relevanssi_oxygen_fix_none_setting' );
add_filter( 'relevanssi_oxygen_section_content', 'relevanssi_oxygen_code_block' );
add_filter( 'relevanssi_oxygen_section_content', 'relevanssi_oxygen_rich_text' );
add_action( 'save_post', 'relevanssi_insert_edit', 99, 1 );
/**
* Cleans up the Oxygen Builder custom field for Relevanssi consumption.
*
* Splits up the big custom field content from ct_builder_shortcodes into
* sections ([ct_section] tags). Each section can be processed with filters
* defined with `relevanssi_oxygen_section_filters`, for example to remove
* sections based on their "nicename" or "ct_category" values. After that the
* section is passed through the `relevanssi_oxygen_section_content` filter.
* Finally all shortcode tags are removed, leaving just the content.
*
* @param array $value An array of custom field values.
* @param string $field The name of the custom field. This function only looks
* at `ct_builder_shortcodes` fields.
* @param int $post_id The post ID.
*
* @return array|null An array of custom field values, null if no value exists.
*/
function relevanssi_oxygen_compatibility( $value, $field, $post_id ) {
if ( 'ct_builder_json' === $field ) {
$json = array();
foreach ( $value as $row ) {
$json[] = json_decode( $row );
}
$content = '';
if ( isset( $json[0]->children ) ) {
foreach ( $json[0]->children as $child ) {
$content .= relevanssi_process_oxygen_child( $child );
}
}
$value[0] = $content;
return $value;
}
if ( 'ct_builder_shortcodes_revisions_dates' === $field ) {
return '';
}
if ( 'ct_builder_shortcodes_revisions' === $field ) {
return '';
}
if ( 'ct_builder_shortcodes' === $field ) {
if ( version_compare( CT_VERSION, '4.0', '>=' ) ) {
return null;
}
if ( empty( $value ) ) {
return null;
}
$content_tags = explode( '[ct_section', $value[0] );
$page_content = '';
foreach ( $content_tags as $content ) {
if ( empty( $content ) ) {
continue;
}
if ( '[' !== substr( $content, 0, 1 ) ) {
$content = '[ct_section' . $content;
}
/**
* Allows defining filters to remove Oxygen Builder sections.
*
* The filters are arrays, with the array key defining the key and
* the value defining the value. If the filter array is
* array( 'nicename' => 'Hero BG' ), Relevanssi will look for
* sections that have "nicename":"Hero BG" in their settings and
* will remove those.
*
* @param array An array of filtering rules, defaults empty.
*
* @return array
*/
$filters = apply_filters(
'relevanssi_oxygen_section_filters',
array()
);
array_walk(
$filters,
function ( $filter ) use ( &$content ) {
foreach ( $filter as $key => $value ) {
if ( stristr( $content, '"' . $key . '":"' . $value . '"' ) !== false ) {
$content = '';
}
}
}
);
$content = preg_replace(
array(
'/\[oxygen.*?\]/',
'/\[\/?ct_.*?\]/',
'/\[\/?oxy_.*?\]/',
),
' ',
/**
* Filters the Oxygen Builder section content before the
* Oxygen Builder shortcode tags are removed.
*
* @param string $content The single section content.
* @param int $post_id The post ID.
*
* @return string
*/
apply_filters(
'relevanssi_oxygen_section_content',
$content,
$post_id
)
);
$page_content .= $content;
}
$page_content = relevanssi_do_shortcode( $page_content );
$value[0] = $page_content;
}
return $value;
}
/**
* Recursively processes the Oxygen JSON data.
*
* This function extracts all the ct_content data from the JSON. All elements
* are run through the relevanssi_oxygen_element filter hook. You can use that
* filter hook to modify or to eliminate elements from the JSON.
*
* @param array $child The child element array.
*
* @return string The content from the child and the grandchildren.
*/
function relevanssi_process_oxygen_child( $child ): string {
/**
* Filters the Oxygen JSON child element.
*
* If the filter returns an empty value, the child element and all its
* children will be ignored.
*
* @param array $child The JSON child element.
*/
$child = apply_filters( 'relevanssi_oxygen_element', $child );
if ( empty( $child ) ) {
return '';
}
$child_content = ' ';
if ( isset( $child->options->ct_content ) ) {
$child_content .= $child->options->ct_content;
}
if ( isset( $child->options->original->{'code-php'} ) ) {
// For code and HTML blocks, strip all tags.
$child_content .= wp_strip_all_tags( $child->options->original->{'code-php'} );
}
if ( isset( $child->children ) ) {
foreach ( $child->children as $grandchild ) {
$child_content .= relevanssi_process_oxygen_child( $grandchild );
}
}
return $child_content;
}
/**
* Adds the Oxygen custom field to the list of indexed custom fields.
*
* @param array|boolean $fields An array of custom fields to index, or false.
*
* @return array An array of custom fields, including `ct_builder_json` or
* `ct_builder_shortcodes`.
*/
function relevanssi_add_oxygen( $fields ) {
$oxygen_field = version_compare( CT_VERSION, '4.0', '>=' )
? 'ct_builder_json'
: 'ct_builder_shortcodes';
if ( ! is_array( $fields ) ) {
$fields = array();
}
if ( ! in_array( $oxygen_field, $fields, true ) ) {
$fields[] = $oxygen_field;
}
return $fields;
}
/**
* Makes sure the Oxygen builder shortcode is included in the index, even when
* the custom field setting is set to 'none'.
*
* @param string $value The custom field indexing setting value. The parameter
* is ignored, Relevanssi disables this filter and then checks the option to
* see what the value is.
*
* @return string If value is undefined, it's set to 'ct_builder_json' or
* 'ct_builder_shortcodes'.
*/
function relevanssi_oxygen_fix_none_setting( $value ) {
if ( ! $value ) {
$value = version_compare( CT_VERSION, '4.0', '>=' )
? 'ct_builder_json'
: 'ct_builder_shortcodes';
}
return $value;
}
/**
* Indexes the Base64 encoded PHP & HTML code block contents.
*
* @param string $content The section content from the
* relevanssi_oxygen_section_content filter hook.
*
* @return string $content The content with the decoded code block content
* added to the end.
*/
function relevanssi_oxygen_code_block( $content ) {
if ( preg_match_all( '/\[ct_code_block.*?ct_code_block\]/', $content, $matches ) ) {
foreach ( $matches[0] as $match ) {
if ( preg_match_all( '/"code-php":"(.*?)"/', $match, $block_matches ) ) {
foreach ( $block_matches[1] as $encoded_text ) {
$content .= ' ' . base64_decode( $encoded_text ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions
}
}
}
}
return $content;
}
/**
* Removes the Oxygen rich text shortcode.
*
* @param string $content The content of the Oxygen section.
*
* @return string The content with the oxy_rich_text shortcodes removed.
*/
function relevanssi_oxygen_rich_text( $content ) {
$content = preg_replace( '/\[\/?oxy_rich_text.*?\]/im', '', $content );
return $content;
}

View File

@@ -1,38 +0,0 @@
<?php
/**
* /lib/compatibility/paidmembershippro.php
*
* Paid Membership Pro compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_post_ok', 'relevanssi_paidmembershippro_compatibility', 10, 2 );
/**
* Checks whether the user is allowed to see the post.
*
* @param boolean $post_ok Can the post be shown to the user.
* @param int $post_id The post ID.
*
* @return boolean $post_ok True if the user is allowed to see the post,
* otherwise false.
*/
function relevanssi_paidmembershippro_compatibility( $post_ok, $post_id ) {
$pmpro_active = get_option( 'pmpro_filterqueries', 0 );
if ( $pmpro_active ) {
$status = relevanssi_get_post_status( $post_id );
if ( 'publish' === $status ) {
// Only apply to published posts, don't apply to drafts.
$current_user = wp_get_current_user();
$post_ok = pmpro_has_membership_access( $post_id, $current_user->ID );
}
}
return $post_ok;
}

View File

@@ -1,205 +0,0 @@
<?php
/**
* /lib/compatibility/polylang.php
*
* Polylang compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_modify_wp_query', 'relevanssi_polylang_filter' );
add_filter( 'relevanssi_where', 'relevanssi_polylang_where_include_terms' );
add_filter( 'relevanssi_hits_filter', 'relevanssi_polylang_term_filter' );
/**
* Removes the Polylang language filters.
*
* If the Polylang allow all option ('relevanssi_polylang_all_languages') is
* enabled this removes the Polylang language filter. By default Polylang
* filters the languages using a taxonomy query.
*
* @param object $query WP_Query object we need to clean up.
*/
function relevanssi_polylang_filter( $query ) {
$polylang_allow_all = get_option( 'relevanssi_polylang_all_languages' );
if ( 'on' === $polylang_allow_all ) {
$ok_queries = array();
if ( ! isset( $query->tax_query ) ) {
// No tax query set, backing off.
return;
}
if ( ! isset( $query->tax_query->queries ) || ! is_array( $query->tax_query->queries ) ) {
// No tax query set, backing off.
return;
}
foreach ( $query->tax_query->queries as $tax_query ) {
if ( isset( $tax_query['taxonomy'] ) && 'language' !== $tax_query['taxonomy'] ) {
// Not a language tax query.
$ok_queries[] = $tax_query;
}
}
$query->tax_query->queries = $ok_queries;
if ( isset( $query->query_vars['tax_query'] ) ) {
// Tax queries can be here as well, so let's sweep this one too.
$ok_queries = array();
foreach ( $query->query_vars['tax_query'] as $tax_query ) {
if ( isset( $tax_query['taxonomy'] ) ) {
if ( 'language' !== $tax_query['taxonomy'] ) {
$ok_queries[] = $tax_query;
}
} else {
// Relation parameter most likely.
$ok_queries[] = $tax_query;
}
}
$query->query_vars['tax_query'] = $ok_queries;
}
if ( isset( $query->query_vars['taxonomy'] ) && 'language' === $query->query_vars['taxonomy'] ) {
// Another way to set the taxonomy.
unset( $query->query_vars['taxonomy'] );
unset( $query->query_vars['term'] );
}
}
return $query;
}
/**
* Allows taxonomy terms in language-restricted searches.
*
* This is a bit of a hack, where the language taxonomy WHERE clause is modified
* on the go to allow all posts with the post ID -1 (which means taxonomy terms
* and users). This may break suddenly in updates, but I haven't come up with a
* better way so far.
*
* @param string $where The WHERE clause to modify.
*
* @return string The WHERE clause with additional filtering included.
*
* @since 2.1.6
*/
function relevanssi_polylang_where_include_terms( $where ) {
global $wpdb;
$current_language = substr( get_locale(), 0, 2 );
if ( function_exists( 'pll_current_language' ) ) {
$current_language = pll_current_language();
}
$languages = get_terms( array( 'taxonomy' => 'language' ) );
$language_id = 0;
foreach ( $languages as $language ) {
if (
! is_wp_error( $language ) &&
$language instanceof WP_Term &&
$language->slug === $current_language
) {
$language_id = intval( $language->term_id );
break;
}
}
// Language ID should now have current language ID.
if ( 0 !== $language_id ) {
// Do a simple search-and-replace to modify the query.
$where = preg_replace( '/\s+/', ' ', $where );
$where = preg_replace( '/\(\s/', '(', $where );
$where = str_replace(
"AND relevanssi.doc IN (SELECT DISTINCT(tr.object_id) FROM {$wpdb->prefix}term_relationships AS tr WHERE tr.term_taxonomy_id IN ($language_id))",
"AND (relevanssi.doc IN ( SELECT DISTINCT(tr.object_id) FROM {$wpdb->prefix}term_relationships AS tr WHERE tr.term_taxonomy_id IN ($language_id)) OR (relevanssi.doc = -1))",
$where
);
}
return $where;
}
/**
* Filters out taxonomy terms in the wrong language.
*
* If all languages are not allowed, this filter goes through the results and
* removes the taxonomy terms in the wrong language. This can't be done in the
* original query because the term language information is slightly hard to
* find.
*
* @param array $hits The found posts are in $hits[0].
*
* @return array The $hits array with the unwanted posts removed.
*
* @since 2.1.6
*/
function relevanssi_polylang_term_filter( $hits ) {
$polylang_allow_all = get_option( 'relevanssi_polylang_all_languages' );
if ( 'on' !== $polylang_allow_all ) {
$current_language = substr( get_locale(), 0, 2 );
if ( function_exists( 'pll_current_language' ) ) {
$current_language = pll_current_language();
}
$accepted_hits = array();
foreach ( $hits[0] as $hit ) {
$original_hit = $hit;
if ( is_numeric( $hit ) ) {
// In case "fields" is set to "ids", fetch the post object we need.
$original_hit = $hit;
$hit = get_post( $hit );
}
if ( ! isset( $hit->post_content ) && isset( $hit->ID ) ) {
// The "fields" is set to "id=>parent".
$original_hit = $hit;
$hit = get_post( $hit->ID );
}
if ( isset( $hit->ID ) && -1 === $hit->ID && isset( $hit->term_id ) ) {
$term_id = intval( $hit->term_id );
$translations = pll_get_term_translations( $term_id );
if (
isset( $translations[ $current_language ] ) &&
$translations[ $current_language ] === $term_id
) {
$accepted_hits[] = $original_hit;
}
} else {
$accepted_hits[] = $original_hit;
}
}
$hits[0] = $accepted_hits;
}
return $hits;
}
/**
* Returns the term_taxonomy_id matching the Polylang language based on locale.
*
* @param string $locale The locale string for the language.
*
* @return int The term_taxonomy_id for the language; 0 if nothing is found.
*/
function relevanssi_get_language_term_taxonomy_id( $locale ) {
global $wpdb, $relevanssi_language_term_ids;
if ( isset( $relevanssi_language_term_ids[ $locale ] ) ) {
return $relevanssi_language_term_ids[ $locale ];
}
$languages = $wpdb->get_results(
"SELECT term_taxonomy_id, description FROM $wpdb->term_taxonomy " .
"WHERE taxonomy = 'language'"
);
$term_id = 0;
foreach ( $languages as $row ) {
$description = unserialize( $row->description ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions
if ( $description['locale'] === $locale ) {
$term_id = $row->term_taxonomy_id;
break;
}
}
$relevanssi_language_term_ids[ $locale ] = $term_id;
return $term_id;
}

View File

@@ -1,30 +0,0 @@
<?php
/**
* /lib/compatibility/pretty-links.php
*
* Pretty Links compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_admin_search_ok', 'relevanssi_pretty_links_ok', 10, 2 );
add_filter( 'relevanssi_prevent_default_request', 'relevanssi_pretty_links_ok', 10, 2 );
add_filter( 'relevanssi_search_ok', 'relevanssi_pretty_links_ok', 10, 2 );
/**
* Returns false if the query post type is set to 'pretty-link'.
*
* @param boolean $ok Whether to allow the query.
* @param WP_Query $query The WP_Query object.
*
* @return boolean False if this is a Pretty Links query.
*/
function relevanssi_pretty_links_ok( $ok, $query ) {
if ( isset( $query->query['post_type'] ) && 'pretty-link' === $query->query['post_type'] ) {
$ok = false;
}
return $ok;
}

View File

@@ -1,62 +0,0 @@
<?php
/**
* /lib/compatibility/product-gtin-ean-upc-isbn-for-woocommerce.php.php
*
* Adds Product GTIN (EAN, UPC, ISBN) for WooCommerce support for Relevanssi.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_action( 'pre_option_wpm_pgw_search_by_code', 'relevanssi_disable_gtin_code' );
add_filter( 'relevanssi_index_custom_fields', 'relevanssi_add_wpm_gtin_code' );
add_filter( 'option_relevanssi_index_fields', 'relevanssi_wpm_pgw_fix_none_setting' );
/**
* Disables the 'wpm_pgw_search_by_code' option.
*
* If this option is enabled, it will break Relevanssi search when there's a
* match for the code.
*
* @return string 'no'.
*/
function relevanssi_disable_gtin_code() {
return 'no';
}
/**
* Adds the `_wpm_gtin_code` to the list of indexed custom fields.
*
* @param array|boolean $fields An array of custom fields to index, or false.
*
* @return array An array of custom fields, including `_wpm_gtin_code`.
*/
function relevanssi_add_wpm_gtin_code( $fields ) {
if ( ! is_array( $fields ) ) {
$fields = array();
}
if ( ! in_array( '_wpm_gtin_code', $fields, true ) ) {
$fields[] = '_wpm_gtin_code';
}
return $fields;
}
/**
* Makes sure the GTIN code is included in the index, even when the custom field
* setting is set to 'none'.
*
* @param string $value The custom field indexing setting value. The parameter
* is ignored, Relevanssi disables this filter and then checks the option to
* see what the value is.
*
* @return string If value is undefined, it's set to '_wpm_gtin_code'.
*/
function relevanssi_wpm_pgw_fix_none_setting( $value ) {
if ( ! $value ) {
$value = '_wpm_gtin_code';
}
return $value;
}

View File

@@ -1,100 +0,0 @@
<?php
/**
* /lib/compatibility/rankmath.php
*
* Rank Math noindex filtering function.
*
* @package Relevanssi
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_do_not_index', 'relevanssi_rankmath_noindex', 10, 2 );
add_filter( 'relevanssi_indexing_restriction', 'relevanssi_rankmath_exclude' );
add_action( 'relevanssi_indexing_tab_advanced', 'relevanssi_rankmath_form', 20 );
add_action( 'relevanssi_indexing_options', 'relevanssi_rankmath_options' );
/**
* Blocks indexing of posts marked "noindex" in the Rank Math settings.
*
* Attaches to the 'relevanssi_do_not_index' filter hook.
*
* @param boolean $do_not_index True, if the post shouldn't be indexed.
* @param integer $post_id The post ID number.
*
* @return string|boolean If the post shouldn't be indexed, this returns
* 'RankMath'. The value may also be a boolean.
*/
function relevanssi_rankmath_noindex( $do_not_index, $post_id ) {
if ( 'on' !== get_option( 'relevanssi_seo_noindex' ) ) {
return $do_not_index;
}
$noindex = get_post_meta( $post_id, 'rank_math_robots', true );
if ( is_array( $noindex ) && in_array( 'noindex', $noindex, true ) ) {
$do_not_index = 'RankMath';
}
return $do_not_index;
}
/**
* Excludes the "noindex" posts from Relevanssi indexing.
*
* Adds a MySQL query restriction that blocks posts that have the Rank Math
* "rank_math_robots" setting set to something that includes "noindex".
*
* @param array $restriction An array with two values: 'mysql' for the MySQL
* query restriction to modify, 'reason' for the reason of restriction.
*/
function relevanssi_rankmath_exclude( $restriction ) {
if ( 'on' !== get_option( 'relevanssi_seo_noindex' ) ) {
return $restriction;
}
global $wpdb;
// Backwards compatibility code for 2.8.0, remove at some point.
if ( is_string( $restriction ) ) {
$restriction = array(
'mysql' => $restriction,
'reason' => '',
);
}
$restriction['mysql'] .= " AND post.ID NOT IN (SELECT post_id FROM
$wpdb->postmeta WHERE meta_key = 'rank_math_robots'
AND meta_value LIKE '%noindex%' ) ";
$restriction['reason'] .= ' Rank Math';
return $restriction;
}
/**
* Prints out the form fields for disabling the feature.
*/
function relevanssi_rankmath_form() {
$seo_noindex = get_option( 'relevanssi_seo_noindex' );
$seo_noindex = relevanssi_check( $seo_noindex );
?>
<tr>
<th scope="row">
<label for='relevanssi_seo_noindex'><?php esc_html_e( 'Use Rank Math SEO noindex', 'relevanssi' ); ?></label>
</th>
<td>
<label for='relevanssi_seo_noindex'>
<input type='checkbox' name='relevanssi_seo_noindex' id='relevanssi_seo_noindex' <?php echo esc_attr( $seo_noindex ); ?> />
<?php esc_html_e( 'Use Rank Math SEO noindex.', 'relevanssi' ); ?>
</label>
<p class="description"><?php esc_html_e( 'If checked, Relevanssi will not index posts marked as "No index" in Rank Math SEO settings.', 'relevanssi' ); ?></p>
</td>
</tr>
<?php
}
/**
* Saves the SEO No index option.
*
* @param array $request An array of option values from the request.
*/
function relevanssi_rankmath_options( array $request ) {
relevanssi_update_off_or_on( $request, 'relevanssi_seo_noindex', true );
}

View File

@@ -1,32 +0,0 @@
<?php
/**
* /lib/compatibility/restrictcontentpro.php
*
* Restrict Content Pro compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_post_ok', 'relevanssi_restrictcontentpro_compatibility', 10, 2 );
/**
* Checks whether the user is allowed to see the post.
*
* @param boolean $post_ok Can the post be shown to the user.
* @param int $post_id The post ID.
*
* @return boolean $post_ok True if the user is allowed to see the post,
* otherwise false.
*/
function relevanssi_restrictcontentpro_compatibility( $post_ok, $post_id ) {
if ( ! $post_ok ) {
return $post_ok;
}
$post_ok = rcp_user_can_access( get_current_user_id(), $post_id );
return $post_ok;
}

View File

@@ -1,96 +0,0 @@
<?php
/**
* /lib/compatibility/seoframework.php
*
* The SEO Framework noindex filtering function.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_do_not_index', 'relevanssi_seoframework_noindex', 10, 2 );
add_filter( 'relevanssi_indexing_restriction', 'relevanssi_seoframework_exclude' );
add_action( 'relevanssi_indexing_tab_advanced', 'relevanssi_seoframework_form', 20 );
add_action( 'relevanssi_indexing_options', 'relevanssi_seoframework_options' );
/**
* Blocks indexing of posts marked "Exclude this page from all search queries
* on this site." in the SEO Framework settings.
*
* Attaches to the 'relevanssi_do_not_index' filter hook.
*
* @param boolean $do_not_index True, if the post shouldn't be indexed.
* @param integer $post_id The post ID number.
*
* @return string|boolean If the post shouldn't be indexed, this returns
* 'SEO Framework'. The value may also be a boolean.
*/
function relevanssi_seoframework_noindex( $do_not_index, $post_id ) {
if ( 'on' !== get_option( 'relevanssi_seo_noindex' ) ) {
return $do_not_index;
}
$noindex = get_post_meta( $post_id, 'exclude_local_search', true );
if ( '1' === $noindex ) {
$do_not_index = 'SEO Framework';
}
return $do_not_index;
}
/**
* Excludes the "noindex" posts from Relevanssi indexing.
*
* Adds a MySQL query restriction that blocks posts that have the SEO Framework
* "Exclude this page from all search queries on this site" setting set to "1"
* from indexing.
*
* @param array $restriction An array with two values: 'mysql' for the MySQL
* query restriction to modify, 'reason' for the reason of restriction.
*/
function relevanssi_seoframework_exclude( $restriction ) {
if ( 'on' !== get_option( 'relevanssi_seo_noindex' ) ) {
return $restriction;
}
global $wpdb;
$restriction['mysql'] .= " AND post.ID NOT IN (SELECT post_id FROM
$wpdb->postmeta WHERE meta_key = 'exclude_local_search'
AND meta_value = '1' ) ";
$restriction['reason'] .= ' SEO Framework';
return $restriction;
}
/**
* Prints out the form fields for disabling the feature.
*/
function relevanssi_seoframework_form() {
$seo_noindex = get_option( 'relevanssi_seo_noindex' );
$seo_noindex = relevanssi_check( $seo_noindex );
?>
<tr>
<th scope="row">
<label for='relevanssi_seo_noindex'><?php esc_html_e( 'Use SEO Framework noindex', 'relevanssi' ); ?></label>
</th>
<td>
<label for='relevanssi_seo_noindex'>
<input type='checkbox' name='relevanssi_seo_noindex' id='relevanssi_seo_noindex' <?php echo esc_attr( $seo_noindex ); ?> />
<?php esc_html_e( 'Use SEO Framework noindex.', 'relevanssi' ); ?>
</label>
<p class="description"><?php esc_html_e( 'If checked, Relevanssi will not index posts marked as "No index" in SEO Framework settings.', 'relevanssi' ); ?></p>
</td>
</tr>
<?php
}
/**
* Saves the SEO No index option.
*
* @param array $request An array of option values from the request.
*/
function relevanssi_seoframework_options( array $request ) {
relevanssi_update_off_or_on( $request, 'relevanssi_seo_noindex', true );
}

View File

@@ -1,102 +0,0 @@
<?php
/**
* /lib/compatibility/seopress.php
*
* SEOPress noindex filtering function.
*
* @package Relevanssi
* @author Benjamin Denis
* @source ./yoast-seo.php (Mikko Saari)
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_do_not_index', 'relevanssi_seopress_noindex', 10, 2 );
add_filter( 'relevanssi_indexing_restriction', 'relevanssi_seopress_exclude' );
add_action( 'relevanssi_indexing_tab_advanced', 'relevanssi_seopress_form', 20 );
add_action( 'relevanssi_indexing_options', 'relevanssi_seopress_options' );
/**
* Blocks indexing of posts marked "noindex" in the SEOPress settings.
*
* Attaches to the 'relevanssi_do_not_index' filter hook.
*
* @param boolean $do_not_index True, if the post shouldn't be indexed.
* @param integer $post_id The post ID number.
*
* @return string|boolean If the post shouldn't be indexed, this returns
* 'seopress'. The value may also be a boolean.
*/
function relevanssi_seopress_noindex( $do_not_index, $post_id ) {
if ( 'on' !== get_option( 'relevanssi_seo_noindex' ) ) {
return $do_not_index;
}
$noindex = get_post_meta( $post_id, '_seopress_robots_index', true );
if ( 'yes' === $noindex ) {
$do_not_index = 'SEOPress';
}
return $do_not_index;
}
/**
* Excludes the "noindex" posts from Relevanssi indexing.
*
* Adds a MySQL query restriction that blocks posts that have the SEOPress
* "noindex" setting set to "1" from indexing.
*
* @param array $restriction An array with two values: 'mysql' for the MySQL
* query restriction to modify, 'reason' for the reason of restriction.
*/
function relevanssi_seopress_exclude( $restriction ) {
if ( 'on' !== get_option( 'relevanssi_seo_noindex' ) ) {
return $restriction;
}
global $wpdb;
// Backwards compatibility code for 2.8.0, remove at some point.
if ( is_string( $restriction ) ) {
$restriction = array(
'mysql' => $restriction,
'reason' => '',
);
}
$restriction['mysql'] .= " AND post.ID NOT IN (SELECT post_id FROM
$wpdb->postmeta WHERE meta_key = '_seopress_robots_index'
AND meta_value = 'yes' ) ";
$restriction['reason'] .= 'SEOPress';
return $restriction;
}
/**
* Prints out the form fields for disabling the feature.
*/
function relevanssi_seopress_form() {
$seo_noindex = get_option( 'relevanssi_seo_noindex' );
$seo_noindex = relevanssi_check( $seo_noindex );
?>
<tr>
<th scope="row">
<label for='relevanssi_seo_noindex'><?php esc_html_e( 'Use SEOPress noindex', 'relevanssi' ); ?></label>
</th>
<td>
<label for='relevanssi_seo_noindex'>
<input type='checkbox' name='relevanssi_seo_noindex' id='relevanssi_seo_noindex' <?php echo esc_attr( $seo_noindex ); ?> />
<?php esc_html_e( 'Use SEOPress noindex.', 'relevanssi' ); ?>
</label>
<p class="description"><?php esc_html_e( 'If checked, Relevanssi will not index posts marked as "No index" in SEOPress settings.', 'relevanssi' ); ?></p>
</td>
</tr>
<?php
}
/**
* Saves the SEO No index option.
*
* @param array $request An array of option values from the request.
*/
function relevanssi_seopress_options( array $request ) {
relevanssi_update_off_or_on( $request, 'relevanssi_seo_noindex', true );
}

View File

@@ -1,30 +0,0 @@
<?php
/**
* /lib/compatibility/simplemembership.php
*
* Simple Membership compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_post_ok', 'relevanssi_simplemembership_compatibility', 10, 2 );
/**
* Checks whether the user is allowed to see the post.
*
* @param boolean $post_ok Can the post be shown to the user.
* @param int $post_id The post ID.
*
* @return boolean $post_ok True if the user is allowed to see the post,
* otherwise false.
*/
function relevanssi_simplemembership_compatibility( $post_ok, $post_id ) {
$access_ctrl = SwpmAccessControl::get_instance();
$post = get_post( $post_id );
$post_ok = $access_ctrl->can_i_read_post( $post );
return $post_ok;
}

View File

@@ -1,29 +0,0 @@
<?php
/**
* /lib/compatibility/tablepress.php
*
* TablePress compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_post_content', 'relevanssi_table_filter' );
/**
* Replaces the [table_filter] shortcodes with [table].
*
* The shortcode filter extension adds a [table_filter] shortcode which is not
* compatible with Relevanssi. This function switches those to the normal
* [table] shortcode which works better.
*
* @param string $content The post content.
*
* @return string The fixed post content.
*/
function relevanssi_table_filter( $content ) {
$content = str_replace( '[table_filter', '[table', $content );
return $content;
}

View File

@@ -1,38 +0,0 @@
<?php
/**
* /lib/compatibility/useraccessmanager.php
*
* User Access Manager compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_post_ok', 'relevanssi_useraccessmanager_compatibility', 10, 2 );
/**
* Checks whether the user is allowed to see the post.
*
* @param boolean $post_ok Can the post be shown to the user.
* @param int $post_id The post ID.
*
* @return boolean $post_ok True if the user is allowed to see the post,
* otherwise false.
*/
function relevanssi_useraccessmanager_compatibility( $post_ok, $post_id ) {
$status = relevanssi_get_post_status( $post_id );
if ( 'publish' === $status ) {
// Only apply to published posts, don't apply to drafts.
// phpcs:disable WordPress.NamingConventions.ValidVariableName
global $userAccessManager;
$type = relevanssi_get_post_type( $post_id );
$post_ok = $userAccessManager->getAccessHandler()->checkObjectAccess( $type, $post_id );
// phpcs:enable WordPress.NamingConventions.ValidVariableName
}
return $post_ok;
}

View File

@@ -1,300 +0,0 @@
<?php
/**
* /lib/compatibility/woocommerce.php
*
* WooCommerce compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_indexing_restriction', 'relevanssi_woocommerce_restriction' );
add_filter( 'relevanssi_admin_search_blocked_post_types', 'relevanssi_woocommerce_admin_search_blocked_post_types' );
add_filter( 'relevanssi_modify_wp_query', 'relevanssi_woocommerce_filters' );
add_filter( 'relevanssi_post_ok', 'relevanssi_variation_post_ok', 10, 2 );
/**
* This action solves the problems introduced by adjust_posts_count() in
* WooCommerce version 4.4.0.
*/
add_action( 'woocommerce_before_shop_loop', 'relevanssi_wc_reset_loop' );
RELEVANSSI_PREMIUM && add_filter( 'relevanssi_match', 'relevanssi_sku_boost' );
/**
* Resets the WC post loop in search queries.
*
* Hooks on to woocommerce_before_shop_loop.
*/
function relevanssi_wc_reset_loop() {
global $wp_query;
if ( $wp_query->is_search ) {
wc_reset_loop();
}
}
/**
* Applies the WooCommerce product visibility filter.
*
* @param array $restriction An array with two values: 'mysql' for the MySQL
* query restriction to modify, 'reason' for the reason of restriction.
*/
function relevanssi_woocommerce_restriction( $restriction ) {
// Backwards compatibility code for 2.8.0, remove at some point.
if ( is_string( $restriction ) ) {
$restriction = array(
'mysql' => $restriction,
'reason' => '',
);
}
$restriction['mysql'] .= relevanssi_woocommerce_indexing_filter();
$restriction['reason'] .= 'WooCommerce';
return $restriction;
}
/**
* WooCommerce product visibility filtering for indexing.
*
* This filter is applied before the posts are selected for indexing, so this will
* skip all the excluded posts right away.
*
* @since 4.0.9 (2.1.5)
* @global $wpdb The WordPress database interface.
*
* @return string $restriction The query restriction for the WooCommerce filtering.
*/
function relevanssi_woocommerce_indexing_filter() {
global $wpdb;
$restriction = '';
$woocommerce_blocks = array(
'outofstock' => false,
'exclude-from-catalog' => false,
'exclude-from-search' => true,
);
/**
* Controls the WooCommerce product visibility filtering.
*
* @param array $woocommerce_blocks Has three keys: 'outofstock',
* 'exclude-from-catalog' and 'exclude-from-search', matching three different
* product visibility settings. If the filter sets some of these to 'true',
* those posts will be filtered in the indexing.
*/
$woocommerce_blocks = apply_filters( 'relevanssi_woocommerce_indexing', $woocommerce_blocks );
$term_taxonomy_id_array = array();
if ( $woocommerce_blocks['outofstock'] ) {
$out_of_stock = get_term_by( 'slug', 'outofstock', 'product_visibility', OBJECT );
if ( $out_of_stock && isset( $out_of_stock->term_taxonomy_id ) ) {
$term_taxonomy_id_array[] = $out_of_stock->term_taxonomy_id;
}
}
if ( $woocommerce_blocks['exclude-from-catalog'] ) {
$exclude_from_catalog = get_term_by( 'slug', 'exclude-from-catalog', 'product_visibility', OBJECT );
if ( $exclude_from_catalog && isset( $exclude_from_catalog->term_taxonomy_id ) ) {
$term_taxonomy_id_array[] = $exclude_from_catalog->term_taxonomy_id;
}
}
if ( $woocommerce_blocks['exclude-from-search'] ) {
$exclude_from_search = get_term_by( 'slug', 'exclude-from-search', 'product_visibility', OBJECT );
if ( $exclude_from_search && isset( $exclude_from_search->term_taxonomy_id ) ) {
$term_taxonomy_id_array[] = $exclude_from_search->term_taxonomy_id;
}
}
if ( ! empty( $term_taxonomy_id_array ) ) {
$term_taxonomy_id_string = implode( ',', $term_taxonomy_id_array );
$restriction .= " AND post.ID NOT IN (SELECT object_id FROM $wpdb->term_relationships WHERE object_id = post.ID AND term_taxonomy_id IN ($term_taxonomy_id_string)) ";
}
return $restriction;
}
/**
* SKU weight boost.
*
* Increases the weight for matches in the _sku custom field. The amount of
* boost can be adjusted with the `relevanssi_sku_boost` filter hook. The
* default is 2.
*
* @param object $match_object The match object.
*
* @return object The match object.
*/
function relevanssi_sku_boost( $match_object ) {
$custom_field_detail = json_decode( $match_object->customfield_detail );
if ( null !== $custom_field_detail && isset( $custom_field_detail->_sku ) ) {
/**
* Filters the SKU boost value.
*
* @param float The boost multiplier, default 2.
*/
$match_object->weight *= apply_filters( 'relevanssi_sku_boost', 2 );
}
return $match_object;
}
/**
* Adds blocked WooCommerce post types to the list of blocked post types.
*
* Stops Relevanssi from taking over the admin search for the WooCommerce
* blocked post types using the relevanssi_admin_search_blocked_post_types
* filter hook.
*
* @param array $post_types The list of blocked post types.
* @return array
*/
function relevanssi_woocommerce_admin_search_blocked_post_types( array $post_types ): array {
$woo_post_types = array(
'shop_coupon',
'shop_order',
'shop_order_refund',
'wc_order_status',
'wc_order_email',
'shop_webhook',
);
return array_merge( $post_types, $woo_post_types );
}
/**
* Relevanssi support for WooCommerce filtering.
*
* @param WP_Query $query The WP_Query object.
* @return WP_Query The WP_Query object.
*/
function relevanssi_woocommerce_filters( $query ) {
// phpcs:disable WordPress.Security.NonceVerification.Recommended
$min_price = isset( $_REQUEST['min_price'] ) ? intval( $_REQUEST['min_price'] ) : false;
$max_price = isset( $_REQUEST['max_price'] ) ? intval( $_REQUEST['max_price'] ) : false;
$meta_query = $query->get( 'meta_query' );
if ( $min_price ) {
$meta_query[] = array(
'key' => '_price',
'value' => $min_price,
'compare' => '>=',
'type' => 'NUMERIC',
);
}
if ( $max_price ) {
$meta_query[] = array(
'key' => '_price',
'value' => $max_price,
'compare' => '<=',
'type' => 'NUMERIC',
);
}
if ( $meta_query ) {
$query->set( 'meta_query', $meta_query );
}
foreach ( array( 'product_tag', 'product_cat', 'product_brand' ) as $taxonomy ) {
$value = isset( $_REQUEST[ $taxonomy ] ) ? intval( $_REQUEST[ $taxonomy ] ) : false;
if ( $value ) {
$tax_query = $query->get( 'tax_query' );
if ( ! is_array( $tax_query ) ) {
$tax_query = array();
}
$tax_query[] = array(
'taxonomy' => $taxonomy,
'field' => 'term_id',
'terms' => $value,
);
$query->set( 'tax_query', $tax_query );
}
}
if ( 'no' === get_option( 'woocommerce_attribute_lookup_enabled' ) ) {
return $query;
}
$chosen_attributes = array();
if ( ! empty( $_GET ) ) {
foreach ( $_GET as $key => $value ) {
if ( 0 === strpos( $key, 'filter_' ) ) {
$attribute = wc_sanitize_taxonomy_name( str_replace( 'filter_', '', $key ) );
$taxonomy = wc_attribute_taxonomy_name( $attribute );
$filter_terms = ! empty( $value ) ? explode( ',', wc_clean( wp_unslash( $value ) ) ) : array();
if ( empty( $filter_terms ) || ! taxonomy_exists( $taxonomy ) || ! wc_attribute_taxonomy_id_by_name( $attribute ) ) {
continue;
}
$query_type = ! empty( $_GET[ 'query_type_' . $attribute ] ) && in_array( $_GET[ 'query_type_' . $attribute ], array( 'and', 'or' ), true )
? wc_clean( wp_unslash( $_GET[ 'query_type_' . $attribute ] ) )
: '';
$chosen_attributes[ $taxonomy ]['terms'] = array_map( 'sanitize_title', $filter_terms );
$chosen_attributes[ $taxonomy ]['query_type'] = $query_type ? $query_type : apply_filters( 'woocommerce_layered_nav_default_query_type', 'and' );
}
}
}
$tax_query = $query->get( 'tax_query' );
if ( ! is_array( $tax_query ) ) {
$tax_query = array();
}
foreach ( $chosen_attributes as $taxonomy => $data ) {
$tax_query[] = array(
'taxonomy' => $taxonomy,
'field' => 'slug',
'terms' => $data['terms'],
'operator' => 'and' === $data['query_type'] ? 'AND' : 'IN',
'include_children' => false,
);
}
$query->set( 'tax_query', $tax_query );
return $query;
}
/**
* Provides layered navigation term counts based on Relevanssi searches.
*
* Hooks onto woocommerce_get_filtered_term_product_counts_query to provide
* accurate term counts.
*
* @param array $query The MySQL query parts.
*
* @return array The modified query.
*/
function relevanssi_filtered_term_product_counts_query( $query ) {
if ( defined( 'BeRocket_AJAX_filters_version' ) ) {
return $query;
}
global $relevanssi_variables, $wpdb;
if ( false !== stripos( $query['select'], 'product_or_parent_id' ) ) {
$query['from'] = str_replace( 'FROM ', "FROM {$relevanssi_variables['relevanssi_table']} AS relevanssi, ", $query['from'] );
$query['where'] = str_replace( 'WHERE ', " WHERE relevanssi.doc = $wpdb->posts.ID AND ", $query['where'] );
$query['where'] = preg_replace( '/\(\w+posts.post_title LIKE(.*?)\)\)/', 'relevanssi.term LIKE\1)', $query['where'] );
$query['where'] = preg_replace( array( '/OR \(\w+posts.post_excerpt LIKE .*?\)/', '/OR \(\w+posts.post_content LIKE .*?\)/' ), '', $query['where'] );
} else {
$query['select'] = 'SELECT COUNT( DISTINCT( relevanssi.doc ) ) AS term_count, terms.term_id AS term_count_id';
$query['from'] = "FROM {$relevanssi_variables['relevanssi_table']} AS relevanssi, $wpdb->posts";
$query['where'] = str_replace( 'WHERE ', " WHERE relevanssi.doc = $wpdb->posts.ID AND ", $query['where'] );
$query['where'] = preg_replace( '/\(\w+posts.post_title LIKE(.*?)\)\)/', 'relevanssi.term LIKE\1)', $query['where'] );
$query['where'] = preg_replace( array( '/OR \(\w+posts.post_excerpt LIKE .*?\)/', '/OR \(\w+posts.post_content LIKE .*?\)/' ), '', $query['where'] );
}
return $query;
}
/**
* Checks the parent product status for product variations.
*
* @param bool $ok Whether the post is OK to return in search.
* @param int $post_id The post ID.
*
* @return bool
*/
function relevanssi_variation_post_ok( $ok, $post_id ) : bool {
$post_type = relevanssi_get_post_type( $post_id );
if ( 'product_variation' === $post_type ) {
$parent = get_post_parent( $post_id );
return apply_filters( 'relevanssi_post_ok', $ok, $parent->ID );
}
return $ok;
}

View File

@@ -1,58 +0,0 @@
<?php
/**
* /lib/compatibility/wp-file-download.php
*
* WP File Download compatibility features. Compatibility with WPFD checked for
* version 4.5.4.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_content_to_index', 'relevanssi_wpfd_content', 10, 2 );
add_action( 'wpfd_file_indexed', 'relevanssi_wpfd_index' );
/**
* Adds the WPFD indexed content to wpfd_file posts.
*
* Fetches the words from wpfd_words. wpfd_index.tid is the post ID, wpfd_index.id is
* then used to get the wpfd_docs.id, that is used to get the wpfd_vectors.did which
* can then be used to fetch the correct words from wpfd_words. This function is
* hooked onto relevanssi_content_to_index filter hook.
*
* @param string $content The post content as a string.
* @param object $post The post object.
*
* @return string The post content with the words added to the end.
*/
function relevanssi_wpfd_content( $content, $post ) {
$wpfd_search_config = get_option( '_wpfd_global_search_config', null );
if ( 'wpfd_file' === $post->post_type ) {
if ( $wpfd_search_config && isset( $wpfd_search_config['plain_text_search'] ) && $wpfd_search_config['plain_text_search'] ) {
global $wpdb;
$words = $wpdb->get_col(
"SELECT word
FROM {$wpdb->prefix}wpfd_words, {$wpdb->prefix}wpfd_docs, {$wpdb->prefix}wpfd_index, {$wpdb->prefix}wpfd_vectors " .
"WHERE {$wpdb->prefix}wpfd_index.tid = {$post->ID} " . // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared
" AND {$wpdb->prefix}wpfd_docs.index_id = {$wpdb->prefix}wpfd_index.id
AND {$wpdb->prefix}wpfd_docs.id = {$wpdb->prefix}wpfd_vectors.did
AND {$wpdb->prefix}wpfd_vectors.wid = {$wpdb->prefix}wpfd_words.id"
);
$content .= implode( ' ', $words );
}
}
return $content;
}
/**
* Runs Relevanssi indexing after WPFD indexing is done.
*
* @param int $wpfd_id The WPFD post index.
*/
function relevanssi_wpfd_index( $wpfd_id ) {
global $wpdb;
$post_id = $wpdb->get_var( $wpdb->prepare( "SELECT tid FROM {$wpdb->prefix}wpfd_index WHERE id=%d", $wpfd_id ) );
relevanssi_insert_edit( $post_id );
}

View File

@@ -1,46 +0,0 @@
<?php
/**
* /lib/compatibility/wp-members.php
*
* WP-Members compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_post_ok', 'relevanssi_wpmembers_compatibility', 10, 2 );
/**
* Checks whether the post type is blocked.
*
* Allows all logged-in users to see posts. For non-logged-in users, checks if
* the post is blocked by the _wpmem_block custom field, or if the post type is
* blocked in the $wpmem global.
*
* @param bool $post_ok Whether the user is allowed to see the post.
* @param int|string $post_id The post ID.
*
* @return bool
*/
function relevanssi_wpmembers_compatibility( bool $post_ok, $post_id ): bool {
global $wpmem;
if ( is_user_logged_in() ) {
return $post_ok;
}
$post_meta = get_post_meta( $post_id, '_wpmem_block', true );
$post_type = isset( $wpmem->block[ relevanssi_get_post_type( $post_id ) ] )
? $wpmem->block[ relevanssi_get_post_type( $post_id ) ]
: 0;
if ( '1' === $post_meta ) {
$post_ok = false;
} elseif ( '1' === $post_type && '0' !== $post_meta ) {
$post_ok = false;
}
return $post_ok;
}

View File

@@ -1,25 +0,0 @@
<?php
/**
* /lib/compatibility/wp-search-suggest.php
*
* WP Search Suggest compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'wpss_search_results', 'relevanssi_wpss_support', 10, 2 );
/**
* Adds Relevanssi results to WP Search Suggest dropdown.
*
* @param array $title_list List of post titles.
* @param object $query The WP_Query object.
*
* @return array List of post titles.
*/
function relevanssi_wpss_support( $title_list, $query ) {
$query = relevanssi_do_query( $query );
return wp_list_pluck( $query->posts, 'post_title' );
}

View File

@@ -1,28 +0,0 @@
<?php
/**
* /lib/compatibility/wpjvpostreadinggroups.php
*
* WP JV Post Reading Groups compatibility features.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_post_ok', 'relevanssi_wpjvpostreadinggroups_compatibility', 10, 2 );
/**
* Checks whether the user is allowed to see the post.
*
* @param boolean $post_ok Can the post be shown to the user.
* @param int $post_id The post ID.
*
* @return boolean $post_ok True if the user is allowed to see the post,
* otherwise false.
*/
function relevanssi_wpjvpostreadinggroups_compatibility( $post_ok, $post_id ) {
$post_ok = wp_jv_prg_user_can_see_a_post( get_current_user_id(), $post_id );
return $post_ok;
}

View File

@@ -1,172 +0,0 @@
<?php
/**
* /lib/compatibility/wpml.php
*
* WPML filtering function.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_hits_filter', 'relevanssi_wpml_filter', 9 );
add_filter( 'relevanssi_tag_before_tokenize', 'relevanssi_wpml_term_fix', 10, 4 );
add_action( 'relevanssi_pre_index_taxonomies', 'relevanssi_disable_wpml_terms' );
add_action( 'relevanssi_post_index_taxonomies', 'relevanssi_enable_wpml_terms' );
/**
* Filters posts based on WPML language.
*
* Attaches to 'relevanssi_hits_filter' to restrict WPML searches to the current
* language. Whether this filter is used or not depends on the option
* 'relevanssi_wpml_only_current'. Thanks to rvencu for the initial code.
*
* @global object $sitepress The WPML global object.
*
* @param array $data Index 0 has the array of results, index 1 has the search query.
*
* @return array $data The whole parameter array, with the filtered posts in the index 0.
*/
function relevanssi_wpml_filter( $data ) {
$filter_enabled = get_option( 'relevanssi_wpml_only_current' );
if ( 'on' === $filter_enabled ) {
$wpml_post_type_setting = apply_filters( 'wpml_setting', false, 'custom_posts_sync_option' );
$wpml_taxonomy_setting = apply_filters( 'wpml_setting', false, 'taxonomies_sync_option' );
$current_blog_language = get_bloginfo( 'language' );
$filtered_hits = array();
foreach ( $data[0] as $hit ) {
$original_hit = $hit;
$object_array = relevanssi_get_an_object( $hit );
$hit = $object_array['object'];
if ( isset( $hit->blog_id ) && function_exists( 'switch_to_blog' ) ) {
// This is a multisite search.
switch_to_blog( $hit->blog_id );
if ( function_exists( 'icl_object_id' ) ) {
// Reset the WPML cache when blog is switched, otherwise WPML
// will be confused.
global $wpml_post_translations;
$wpml_post_translations->reload();
}
}
global $sitepress;
// Check if WPML is used.
if ( function_exists( 'icl_object_id' ) && ! function_exists( 'pll_is_translated_post_type' ) ) {
if ( $sitepress->is_translated_post_type( $hit->post_type ) ) {
$fallback_to_default = false;
if ( isset( $wpml_post_type_setting[ $hit->post_type ] ) && '2' === $wpml_post_type_setting[ $hit->post_type ] ) {
$fallback_to_default = true;
}
$id = apply_filters( 'wpml_object_id', $hit->ID, $hit->post_type, $fallback_to_default );
// This is a post in a translated post type.
if ( intval( $hit->ID ) === intval( $id ) ) {
// The post exists in the current language, and can be included.
$filtered_hits[] = $original_hit;
}
} elseif ( isset( $hit->term_id ) ) {
$fallback_to_default = false;
if ( isset( $wpml_taxonomy_setting[ $hit->post_type ] ) && '2' === $wpml_taxonomy_setting[ $hit->post_type ] ) {
$fallback_to_default = true;
}
if ( ! isset( $hit->post_type ) ) {
// This is a term object, not a Relevanssi-generated post object.
$hit->post_type = $hit->taxonomy;
}
$id = apply_filters( 'wpml_object_id', $hit->term_id, $hit->post_type, $fallback_to_default );
if ( intval( $hit->term_id ) === intval( $id ) ) {
// The post exists in the current language, and can be included.
$filtered_hits[] = $original_hit;
}
} else {
// This is not a translated post type, so include all posts.
$filtered_hits[] = $original_hit;
}
} elseif ( get_bloginfo( 'language' ) === $current_blog_language ) {
// If there is no WPML but the target blog has identical language with current blog,
// we use the hits. Note en-US is not identical to en-GB!
$filtered_hits[] = $original_hit;
}
if ( isset( $hit->blog_id ) && function_exists( 'restore_current_blog' ) ) {
restore_current_blog();
}
}
// A bit of foolproofing, avoid a warning if someone passes this filter bad data.
$query = '';
if ( isset( $data[1] ) ) {
$query = $data[1];
}
return array( $filtered_hits, $query );
}
return $data;
}
/**
* Fixes translated term indexing for WPML.
*
* WPML indexed translated terms based on current admin language, not the post
* language. This filter changes the term indexing to match the post language.
*
* @param string $term_content All terms in the taxonomy as a string.
* @param array $terms All the term objects in the current taxonomy.
* @param string $taxonomy The taxonomy name.
* @param int $post_id The post ID.
*
* @return string The term names as a string.
*/
function relevanssi_wpml_term_fix( string $term_content, array $terms, string $taxonomy, int $post_id ) {
$post_language = apply_filters( 'wpml_post_language_details', null, $post_id );
if ( ! is_wp_error( $post_language ) ) {
$term_content = '';
global $sitepress;
remove_filter( 'get_term', array( $sitepress, 'get_term_adjust_id' ), 1, 1 );
foreach ( $terms as $term ) {
$term = get_term(
apply_filters(
'wpml_object_id',
$term->term_id,
$taxonomy,
true,
$post_language['language_code']
),
$taxonomy
);
$term_content .= ' ' . $term->name;
}
add_filter( 'get_term', array( $sitepress, 'get_term_adjust_id' ), 1, 1 );
}
return $term_content;
}
/**
* Disables WPML term filtering.
*
* This function disables the WPML term filtering, so that Relevanssi can index
* the terms in the correct language.
*/
function relevanssi_disable_wpml_terms() {
global $sitepress;
remove_filter( 'get_term', array( $sitepress, 'get_term_adjust_id' ), 1 );
}
/**
* Enables WPML term filtering.
*
* This function enables the WPML term filtering.
*/
function relevanssi_enable_wpml_terms() {
global $sitepress;
add_filter( 'get_term', array( $sitepress, 'get_term_adjust_id' ), 1, 1 );
}

View File

@@ -1,102 +0,0 @@
<?php
/**
* /lib/compatibility/yoast-seo.php
*
* Yoast SEO noindex filtering function.
*
* @package Relevanssi
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_filter( 'relevanssi_do_not_index', 'relevanssi_yoast_noindex', 10, 2 );
add_filter( 'relevanssi_indexing_restriction', 'relevanssi_yoast_exclude' );
add_action( 'relevanssi_indexing_tab_advanced', 'relevanssi_yoast_form', 20 );
add_action( 'relevanssi_indexing_options', 'relevanssi_yoast_options' );
/**
* Blocks indexing of posts marked "noindex" in the Yoast SEO settings.
*
* Attaches to the 'relevanssi_do_not_index' filter hook.
*
* @param boolean $do_not_index True, if the post shouldn't be indexed.
* @param integer $post_id The post ID number.
*
* @return string|boolean If the post shouldn't be indexed, this returns
* 'yoast_seo'. The value may also be a boolean.
*/
function relevanssi_yoast_noindex( $do_not_index, $post_id ) {
if ( 'on' !== get_option( 'relevanssi_seo_noindex' ) ) {
return $do_not_index;
}
$noindex = get_post_meta( $post_id, '_yoast_wpseo_meta-robots-noindex', true );
if ( '1' === $noindex ) {
$do_not_index = 'Yoast SEO';
}
return $do_not_index;
}
/**
* Excludes the "noindex" posts from Relevanssi indexing.
*
* Adds a MySQL query restriction that blocks posts that have the Yoast SEO
* "noindex" setting set to "1" from indexing.
*
* @param array $restriction An array with two values: 'mysql' for the MySQL
* query restriction to modify, 'reason' for the reason of restriction.
*/
function relevanssi_yoast_exclude( $restriction ) {
if ( 'on' !== get_option( 'relevanssi_seo_noindex' ) ) {
return $restriction;
}
global $wpdb;
// Backwards compatibility code for 2.8.0, remove at some point.
if ( is_string( $restriction ) ) {
$restriction = array(
'mysql' => $restriction,
'reason' => '',
);
}
$restriction['mysql'] .= " AND post.ID NOT IN (SELECT post_id FROM
$wpdb->postmeta WHERE meta_key = '_yoast_wpseo_meta-robots-noindex'
AND meta_value = '1' ) ";
$restriction['reason'] .= ' Yoast SEO';
return $restriction;
}
/**
* Prints out the form fields for disabling the feature.
*/
function relevanssi_yoast_form() {
$seo_noindex = get_option( 'relevanssi_seo_noindex' );
$seo_noindex = relevanssi_check( $seo_noindex );
?>
<tr>
<th scope="row">
<label for='relevanssi_seo_noindex'><?php esc_html_e( 'Use Yoast SEO noindex', 'relevanssi' ); ?></label>
</th>
<td>
<label for='relevanssi_seo_noindex'>
<input type='checkbox' name='relevanssi_seo_noindex' id='relevanssi_seo_noindex' <?php echo esc_attr( $seo_noindex ); ?> />
<?php esc_html_e( 'Use Yoast SEO noindex.', 'relevanssi' ); ?>
</label>
<p class="description"><?php esc_html_e( 'If checked, Relevanssi will not index posts marked as "No index" in Yoast SEO settings.', 'relevanssi' ); ?></p>
</td>
</tr>
<?php
}
/**
* Saves the SEO No index option.
*
* @param array $request An array of option values from the request.
*/
function relevanssi_yoast_options( array $request ) {
relevanssi_update_off_or_on( $request, 'relevanssi_seo_noindex', true );
}