no wp
This commit is contained in:
@@ -1,780 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* /premium/admin-ajax.php
|
||||
*
|
||||
* @package Relevanssi_Premium
|
||||
* @author Mikko Saari
|
||||
* @license https://wordpress.org/about/gpl/ GNU General Public License
|
||||
* @see https://www.relevanssi.com/
|
||||
*/
|
||||
|
||||
add_action( 'wp_ajax_relevanssi_list_pdfs', 'relevanssi_list_pdfs_action' );
|
||||
add_action( 'wp_ajax_relevanssi_wipe_pdfs', 'relevanssi_wipe_pdfs_action' );
|
||||
add_action( 'wp_ajax_relevanssi_wipe_server_errors', 'relevanssi_wipe_server_errors_action' );
|
||||
add_action( 'wp_ajax_relevanssi_index_pdfs', 'relevanssi_index_pdfs_action' );
|
||||
add_action( 'wp_ajax_relevanssi_send_pdf', 'relevanssi_send_pdf' );
|
||||
add_action( 'wp_ajax_relevanssi_send_url', 'relevanssi_send_url' );
|
||||
add_action( 'wp_ajax_relevanssi_get_pdf_errors', 'relevanssi_get_pdf_errors_action' );
|
||||
add_action( 'wp_ajax_relevanssi_index_taxonomies', 'relevanssi_index_taxonomies_ajax_wrapper' );
|
||||
add_action( 'wp_ajax_relevanssi_count_taxonomies', 'relevanssi_count_taxonomies_ajax_wrapper' );
|
||||
add_action( 'wp_ajax_relevanssi_index_post_type_archives', 'relevanssi_index_post_type_archives_ajax_wrapper' );
|
||||
add_action( 'wp_ajax_relevanssi_index_users', 'relevanssi_index_users_ajax_wrapper' );
|
||||
add_action( 'wp_ajax_relevanssi_count_users', 'relevanssi_count_users_ajax_wrapper' );
|
||||
add_action( 'wp_ajax_relevanssi_list_taxonomies', 'relevanssi_list_taxonomies_wrapper' );
|
||||
add_action( 'wp_ajax_relevanssi_related_posts', 'relevanssi_get_related_posts' );
|
||||
add_action( 'wp_ajax_relevanssi_related_remove', 'relevanssi_add_to_exclude_list' );
|
||||
add_action( 'wp_ajax_relevanssi_related_return', 'relevanssi_remove_from_exclude_list' );
|
||||
add_action( 'wp_ajax_relevanssi_pin_post', 'relevanssi_pin_post' );
|
||||
add_action( 'wp_ajax_relevanssi_unpin_post', 'relevanssi_unpin_post' );
|
||||
add_action( 'wp_ajax_relevanssi_get_words', 'relevanssi_ajax_get_words' );
|
||||
add_action( 'wp_ajax_nopriv_relevanssi_get_words', 'relevanssi_ajax_get_words' );
|
||||
add_action( 'wp_ajax_relevanssi_index_pdf', 'relevanssi_ajax_index_pdf' );
|
||||
|
||||
/**
|
||||
* Performs the "list PDF files" AJAX action.
|
||||
*
|
||||
* Uses relevanssi_get_posts_with_attachments() to get a list of posts with files
|
||||
* attached to them.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function relevanssi_list_pdfs_action() {
|
||||
check_ajax_referer( 'relevanssi-list-pdfs', 'security' );
|
||||
relevanssi_current_user_can_access_options();
|
||||
|
||||
$limit = 0;
|
||||
if ( isset( $_POST['limit'] ) ) { // WPCS: input var ok.
|
||||
$limit = intval( wp_unslash( $_POST['limit'] ) ); // WPCS: input var ok.
|
||||
}
|
||||
$pdfs = relevanssi_get_posts_with_attachments( $limit );
|
||||
echo wp_json_encode( $pdfs );
|
||||
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the "wipe PDF content" AJAX action.
|
||||
*
|
||||
* Removes all '_relevanssi_pdf_content' and '_relevanssi_pdf_error' post meta
|
||||
* fields from the wp_postmeta table. However, if '_relevanssi_pdf_modified' is
|
||||
* set, the content is not removed for that post.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function relevanssi_wipe_pdfs_action() {
|
||||
check_ajax_referer( 'relevanssi-wipe-pdfs', 'security' );
|
||||
relevanssi_current_user_can_access_options();
|
||||
|
||||
$deleted_content = relevanssi_delete_all_but(
|
||||
'_relevanssi_pdf_content',
|
||||
'_relevanssi_pdf_modified',
|
||||
'1'
|
||||
);
|
||||
$deleted_errors = delete_post_meta_by_key( '_relevanssi_pdf_error' );
|
||||
|
||||
$response = array();
|
||||
$response['deleted_content'] = false;
|
||||
$response['deleted_errors'] = false;
|
||||
|
||||
if ( $deleted_content ) {
|
||||
$response['deleted_content'] = true;
|
||||
}
|
||||
if ( $deleted_errors ) {
|
||||
$response['deleted_errors'] = true;
|
||||
}
|
||||
|
||||
echo wp_json_encode( $response );
|
||||
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the "wipe server errors" AJAX action.
|
||||
*
|
||||
* Removes all '_relevanssi_pdf_error' post meta fields from the wp_postmeta
|
||||
* table where the meta_value is 'R_ERR06: Server did not respond.'.
|
||||
*/
|
||||
function relevanssi_wipe_server_errors_action() {
|
||||
check_ajax_referer( 'relevanssi-wipe-errors', 'security' );
|
||||
relevanssi_current_user_can_access_options();
|
||||
|
||||
global $wpdb;
|
||||
$result = $wpdb->delete(
|
||||
$wpdb->postmeta,
|
||||
array(
|
||||
'meta_key' => '_relevanssi_pdf_error',
|
||||
'meta_value' => 'R_ERR06: Server did not respond.',
|
||||
),
|
||||
array(
|
||||
'%s',
|
||||
'%s',
|
||||
)
|
||||
);
|
||||
|
||||
$response['deleted_rows'] = $result;
|
||||
|
||||
echo wp_json_encode( $response );
|
||||
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all post meta for certain meta key unless another meta key is set.
|
||||
*
|
||||
* @global object $wpdb The WordPress database interface.
|
||||
*
|
||||
* @param string $meta_key The meta key to delete.
|
||||
* @param string $exclusion_key The conditional meta key.
|
||||
* @param string $value Value for the conditional meta to check.
|
||||
*
|
||||
* @return boolean True if something was deleted, false if not.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function relevanssi_delete_all_but( $meta_key, $exclusion_key, $value ) {
|
||||
global $wpdb;
|
||||
|
||||
$query = $wpdb->prepare(
|
||||
"SELECT meta_id FROM $wpdb->postmeta WHERE meta_key = %s
|
||||
AND post_id NOT IN (
|
||||
SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s
|
||||
)",
|
||||
$meta_key,
|
||||
$exclusion_key,
|
||||
$value
|
||||
);
|
||||
|
||||
$meta_ids = $wpdb->get_col( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
||||
if ( ! count( $meta_ids ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$query = "DELETE FROM $wpdb->postmeta WHERE meta_id IN ( " . implode( ',', $meta_ids ) . ' )';
|
||||
|
||||
$count = $wpdb->query( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
||||
|
||||
if ( ! $count ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the "index PDFs" AJAX action.
|
||||
*
|
||||
* Reads in the PDF content for PDF files fetched using the relevanssi_get_posts_with_attachments() function.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function relevanssi_index_pdfs_action() {
|
||||
check_ajax_referer( 'relevanssi-index-pdfs', 'security' );
|
||||
relevanssi_current_user_can_access_options();
|
||||
|
||||
$pdfs = relevanssi_get_posts_with_attachments( 3 );
|
||||
|
||||
if ( ! isset( $_POST['completed'] ) || ! isset( $_POST['total'] ) ) { // WPCS: input var ok.
|
||||
wp_die();
|
||||
}
|
||||
|
||||
$post_data = $_POST; // WPCS: input var ok.
|
||||
|
||||
$completed = absint( $post_data['completed'] );
|
||||
$total = absint( $post_data['total'] );
|
||||
|
||||
$response = array();
|
||||
$response['feedback'] = '';
|
||||
|
||||
if ( empty( $pdfs ) ) {
|
||||
$response['feedback'] = __( 'Indexing complete!', 'relevanssi' );
|
||||
$response['completed'] = 'done';
|
||||
$response['percentage'] = 100;
|
||||
} else {
|
||||
foreach ( $pdfs as $post_id ) {
|
||||
$echo_and_die = false;
|
||||
$send_files = get_option( 'relevanssi_send_pdf_files' );
|
||||
if ( 'off' === $send_files ) {
|
||||
$send_files = false;
|
||||
}
|
||||
|
||||
$index_response = relevanssi_index_pdf( $post_id, $echo_and_die, $send_files );
|
||||
++$completed;
|
||||
|
||||
if ( $index_response['success'] ) {
|
||||
// translators: placeholder is the post ID.
|
||||
$response['feedback'] .= sprintf( esc_html__( 'Successfully indexed attachment id %d.', 'relevanssi' ), esc_html( $post_id ) ) . "\n";
|
||||
} else {
|
||||
// translators: the numeric placeholder is the post ID, the string is the error message.
|
||||
$response['feedback'] .= sprintf( esc_html__( 'Failed to index attachment id %1$d: %2$s', 'relevanssi' ), esc_html( $post_id ), esc_html( $index_response['error'] ) ) . "\n";
|
||||
}
|
||||
}
|
||||
$response['completed'] = $completed;
|
||||
if ( $total > 0 ) {
|
||||
$response['percentage'] = round( $completed / $total * 100, 0 );
|
||||
} else {
|
||||
$response['percentage'] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
echo wp_json_encode( $response );
|
||||
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the "send PDF" AJAX action.
|
||||
*
|
||||
* Reads in the PDF content for one PDF file, based on the 'post_id' parameter, sending the PDF over.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function relevanssi_send_pdf() {
|
||||
check_ajax_referer( 'relevanssi_send_pdf', 'security' );
|
||||
if ( ! current_user_can( 'upload_files' ) ) {
|
||||
wp_die();
|
||||
}
|
||||
|
||||
if ( ! isset( $_REQUEST['post_id'] ) ) { // WPCS: input var ok.
|
||||
wp_die();
|
||||
}
|
||||
$post_id = intval( wp_unslash( $_REQUEST['post_id'] ) ); // WPCS: input var ok.
|
||||
$echo_and_die = true;
|
||||
$send_file = true;
|
||||
relevanssi_index_pdf( $post_id, $echo_and_die, $send_file );
|
||||
|
||||
// Just for sure; relevanssi_index_pdf() should echo necessary responses and die, so don't expect this to ever happen.
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the "send URL" AJAX action.
|
||||
*
|
||||
* Reads in the PDF content for one PDF file, based on the 'post_id' parameter, using the PDF URL.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function relevanssi_send_url() {
|
||||
check_ajax_referer( 'relevanssi_send_pdf', 'security' );
|
||||
if ( ! current_user_can( 'upload_files' ) ) {
|
||||
wp_die();
|
||||
}
|
||||
|
||||
if ( ! isset( $_REQUEST['post_id'] ) ) { // WPCS: input var ok.
|
||||
wp_die();
|
||||
}
|
||||
$post_id = intval( wp_unslash( $_REQUEST['post_id'] ) ); // WPCS: input var ok.
|
||||
$echo_and_die = true;
|
||||
$send_file = false;
|
||||
relevanssi_index_pdf( $post_id, $echo_and_die, $send_file );
|
||||
|
||||
// Just for sure; relevanssi_index_pdf() should echo necessary responses and die, so don't expect this to ever happen.
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all PDF errors.
|
||||
*
|
||||
* Gets a list of all PDF errors in the database and prints out a list of them.
|
||||
*
|
||||
* @global $wpdb The WordPress database interface, used to fetch the meta fields.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function relevanssi_get_pdf_errors_action() {
|
||||
if ( ! current_user_can( 'upload_files' ) ) {
|
||||
wp_die();
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
|
||||
$errors = $wpdb->get_results( "SELECT post_id, meta_value FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_pdf_error'" );
|
||||
$error_message = array();
|
||||
foreach ( $errors as $error ) {
|
||||
$row = __( 'Attachment ID', 'relevanssi' ) . ' ' . $error->post_id . ': ' . $error->meta_value;
|
||||
$row = str_replace( 'PDF Processor error: ', '', $row );
|
||||
$error_message[] = $row;
|
||||
}
|
||||
|
||||
echo wp_json_encode( implode( "\n", $error_message ) );
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a list of taxonomies.
|
||||
*
|
||||
* Gets a list of taxonomies selected for indexing from the relevanssi_list_taxonomies() function.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function relevanssi_list_taxonomies_wrapper() {
|
||||
relevanssi_current_user_can_access_options();
|
||||
|
||||
$taxonomies = array();
|
||||
if ( function_exists( 'relevanssi_list_taxonomies' ) ) {
|
||||
$taxonomies = relevanssi_list_taxonomies();
|
||||
}
|
||||
echo wp_json_encode( $taxonomies );
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indexes taxonomy terms for AJAX indexing.
|
||||
*
|
||||
* Reads in the parameters, indexes taxonomy terms and reports the results.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function relevanssi_index_taxonomies_ajax_wrapper() {
|
||||
check_ajax_referer( 'relevanssi_taxonomy_indexing_nonce', 'security' );
|
||||
relevanssi_current_user_can_access_options();
|
||||
|
||||
if ( ! isset( $_POST['completed'] ) || ! isset( $_POST['total'] ) || ! isset( $_POST['taxonomy'] ) || ! isset( $_POST['offset'] ) || ! isset( $_POST['limit'] ) ) { // WPCS: input var ok.
|
||||
wp_die();
|
||||
}
|
||||
|
||||
$post_data = $_POST; // WPCS: input var ok.
|
||||
|
||||
$completed = absint( $post_data['completed'] );
|
||||
$total = absint( $post_data['total'] );
|
||||
$taxonomy = relevanssi_validate_taxonomy( $post_data['taxonomy'] );
|
||||
$offset = intval( $post_data['offset'] );
|
||||
$limit = intval( $post_data['limit'] );
|
||||
|
||||
if ( empty( $taxonomy ) ) {
|
||||
// Non-valid taxonomy.
|
||||
wp_die();
|
||||
}
|
||||
|
||||
$response = array();
|
||||
|
||||
$indexing_response = relevanssi_index_taxonomies_ajax( $taxonomy, $limit, $offset );
|
||||
|
||||
$completed += $indexing_response['indexed'];
|
||||
if ( $completed === $total ) {
|
||||
$response['completed'] = 'done';
|
||||
$response['total_posts'] = $completed;
|
||||
$response['percentage'] = 100;
|
||||
// translators: number of terms indexed on this go, total indexed terms, total number of terms.
|
||||
$response['feedback'] = sprintf( _n( '%1$d taxonomy term, total %2$d / %3$d.', '%1$d taxonomy terms, total %2$d / %3$d.', $indexing_response['indexed'], 'relevanssi' ), $indexing_response['indexed'], $completed, $total ) . "\n";
|
||||
} else {
|
||||
$response['completed'] = $completed;
|
||||
// translators: number of terms indexed on this go, total indexed terms, total number of terms.
|
||||
$response['feedback'] = sprintf( _n( '%1$d taxonomy term, total %2$d / %3$d.', '%1$d taxonomy terms, total %2$d / %3$d.', $indexing_response['indexed'], 'relevanssi' ), $indexing_response['indexed'], $completed, $total ) . "\n";
|
||||
|
||||
if ( $total > 0 ) {
|
||||
$response['percentage'] = $completed / $total * 100;
|
||||
} else {
|
||||
$response['percentage'] = 0;
|
||||
}
|
||||
|
||||
$response['new_taxonomy'] = false;
|
||||
if ( 'done' === $indexing_response['taxonomy_completed'] ) {
|
||||
$response['new_taxonomy'] = true;
|
||||
}
|
||||
}
|
||||
$response['offset'] = $offset + $limit;
|
||||
|
||||
echo wp_json_encode( $response );
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indexes post type archives for AJAX indexing.
|
||||
*
|
||||
* Indexes post type archives and reports the results. The post type archives are
|
||||
* always indexed all at one go; I don't think there's often a case where there are
|
||||
* too many.
|
||||
*
|
||||
* @since 2.2.0
|
||||
*/
|
||||
function relevanssi_index_post_type_archives_ajax_wrapper() {
|
||||
check_ajax_referer( 'relevanssi_post_type_archive_indexing_nonce', 'security' );
|
||||
relevanssi_current_user_can_access_options();
|
||||
|
||||
$response = array();
|
||||
|
||||
if ( 'on' !== get_option( 'relevanssi_index_post_type_archives' ) ) {
|
||||
$response['feedback'] = __( 'disabled.', 'relevanssi' ) . "\n";
|
||||
} else {
|
||||
$indexing_response = relevanssi_index_post_type_archives_ajax();
|
||||
|
||||
$response['completed'] = 'done';
|
||||
$response['total_posts'] = $indexing_response['indexed'];
|
||||
$response['percentage'] = 100;
|
||||
// translators: number of terms indexed on this go, total indexed terms, total number of terms.
|
||||
$response['feedback'] = sprintf( _n( '%1$d post type archive indexed.', '%1$d post type archives indexed.', $indexing_response['indexed'], 'relevanssi' ), $indexing_response['indexed'] ) . "\n";
|
||||
}
|
||||
|
||||
echo wp_json_encode( $response );
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indexes users for AJAX indexing.
|
||||
*
|
||||
* Reads in the parameters, indexes users and reports the results.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function relevanssi_index_users_ajax_wrapper() {
|
||||
check_ajax_referer( 'relevanssi_user_indexing_nonce', 'security' );
|
||||
relevanssi_current_user_can_access_options();
|
||||
|
||||
if ( ! isset( $_POST['completed'] ) || ! isset( $_POST['total'] ) || ! isset( $_POST['limit'] ) ) { // WPCS: input var ok.
|
||||
wp_die();
|
||||
}
|
||||
|
||||
$post_data = $_POST; // WPCS: input var ok.
|
||||
|
||||
$completed = absint( $post_data['completed'] );
|
||||
$total = absint( $post_data['total'] );
|
||||
$limit = $post_data['limit'];
|
||||
if ( isset( $post_data['offset'] ) ) {
|
||||
$offset = $post_data['offset'];
|
||||
} else {
|
||||
$offset = 0;
|
||||
}
|
||||
|
||||
$response = array();
|
||||
|
||||
$indexing_response = relevanssi_index_users_ajax( $limit, $offset );
|
||||
|
||||
$completed += $indexing_response['indexed'];
|
||||
$processed = $offset;
|
||||
|
||||
if ( $completed === $total || $processed > $total ) {
|
||||
$response['completed'] = 'done';
|
||||
$response['total_posts'] = $completed;
|
||||
$response['percentage'] = 100;
|
||||
$processed = $total;
|
||||
} else {
|
||||
$response['completed'] = $completed;
|
||||
$offset = $offset + $limit;
|
||||
|
||||
if ( $total > 0 ) {
|
||||
$response['percentage'] = $completed / $total * 100;
|
||||
} else {
|
||||
$response['percentage'] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// translators: number of users indexed on this go, total indexed users, total processed users, total number of users.
|
||||
$response['feedback'] = sprintf( _n( 'Indexed %1$d user (total %2$d), processed %3$d / %4$d.', 'Indexed %1$d users (total %2$d), processed %3$d / %4$d.', $indexing_response['indexed'], 'relevanssi' ), $indexing_response['indexed'], $completed, $processed, $total ) . "\n";
|
||||
$response['offset'] = $offset;
|
||||
|
||||
echo wp_json_encode( $response );
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the users.
|
||||
*
|
||||
* Counts the users for indexing purposes using the relevanssi_count_users() function.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function relevanssi_count_users_ajax_wrapper() {
|
||||
relevanssi_current_user_can_access_options();
|
||||
|
||||
$count = -1;
|
||||
if ( function_exists( 'relevanssi_count_users' ) ) {
|
||||
$count = relevanssi_count_users();
|
||||
}
|
||||
echo wp_json_encode( $count );
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the taxonomy terms.
|
||||
*
|
||||
* Counts the taxonomy terms for indexing purposes using the relevanssi_count_taxonomy_terms() function.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function relevanssi_count_taxonomies_ajax_wrapper() {
|
||||
relevanssi_current_user_can_access_options();
|
||||
|
||||
$count = -1;
|
||||
if ( function_exists( 'relevanssi_count_taxonomy_terms' ) ) {
|
||||
$count = relevanssi_count_taxonomy_terms();
|
||||
}
|
||||
echo wp_json_encode( $count );
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a list of related posts.
|
||||
*
|
||||
* @since 2.2.4
|
||||
*/
|
||||
function relevanssi_get_related_posts() {
|
||||
check_ajax_referer( 'relevanssi_metabox_nonce', 'security' );
|
||||
if ( ! current_user_can( 'edit_posts' ) ) {
|
||||
wp_die();
|
||||
}
|
||||
|
||||
$post_id = (int) $_POST['post_id']; // WPCS: input var ok.
|
||||
|
||||
if ( 0 === $post_id ) {
|
||||
wp_die();
|
||||
}
|
||||
|
||||
if ( isset( $_POST['keywords'] ) ) {
|
||||
$keywords = sanitize_text_field( $_POST['keywords'] ); // WPCS: input var ok.
|
||||
|
||||
delete_post_meta( $post_id, '_relevanssi_related_keywords' );
|
||||
add_post_meta( $post_id, '_relevanssi_related_keywords', $keywords );
|
||||
|
||||
// Keywords have changed, flush the cache.
|
||||
delete_post_meta( $post_id, '_relevanssi_related_posts' );
|
||||
}
|
||||
|
||||
if ( isset( $_POST['ids'] ) ) {
|
||||
$include_ids_array = explode( ',', $_POST['ids'] );
|
||||
$valid_ids = array();
|
||||
foreach ( $include_ids_array as $id ) {
|
||||
if ( get_post( $id ) ) {
|
||||
$valid_ids[] = $id;
|
||||
}
|
||||
}
|
||||
if ( ! empty( $valid_ids ) ) {
|
||||
$id_string = implode( ',', $valid_ids );
|
||||
delete_post_meta( $post_id, '_relevanssi_related_include_ids' );
|
||||
add_post_meta( $post_id, '_relevanssi_related_include_ids', $id_string );
|
||||
} else {
|
||||
delete_post_meta( $post_id, '_relevanssi_related_include_ids' );
|
||||
}
|
||||
|
||||
// Included IDs have changed, flush the cache.
|
||||
delete_post_meta( $post_id, '_relevanssi_related_posts' );
|
||||
}
|
||||
|
||||
$list = relevanssi_generate_related_list( $post_id );
|
||||
|
||||
$response = array(
|
||||
'list' => $list,
|
||||
);
|
||||
|
||||
echo wp_json_encode( $response );
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a post ID to the excluded ID list.
|
||||
*
|
||||
* @since 2.2.4
|
||||
*/
|
||||
function relevanssi_add_to_exclude_list() {
|
||||
check_ajax_referer( 'relevanssi_metabox_nonce', 'security' );
|
||||
if ( ! current_user_can( 'edit_posts' ) ) {
|
||||
wp_die();
|
||||
}
|
||||
|
||||
$post_id = (int) $_POST['post_id']; // WPCS: input var ok.
|
||||
|
||||
if ( 0 === $post_id ) {
|
||||
wp_die();
|
||||
}
|
||||
|
||||
if ( isset( $_POST['remove_id'] ) ) {
|
||||
relevanssi_exclude_a_related_post( $post_id, $_POST['remove_id'] );
|
||||
}
|
||||
|
||||
$related = relevanssi_generate_related_list( $post_id );
|
||||
$excluded = relevanssi_generate_excluded_list( $post_id );
|
||||
|
||||
$response = array(
|
||||
'related' => $related,
|
||||
'excluded' => $excluded,
|
||||
);
|
||||
|
||||
echo wp_json_encode( $response );
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a post ID to the list of excluded post IDs of a post.
|
||||
*
|
||||
* @param int $post_id Add to this post IDs exclude list.
|
||||
* @param int $excluded_post Add this post ID to the exclude list.
|
||||
*/
|
||||
function relevanssi_exclude_a_related_post( $post_id, $excluded_post ) {
|
||||
$remove_id = (int) $excluded_post;
|
||||
$excluded_ids = trim( get_post_meta( $post_id, '_relevanssi_related_exclude_ids', true ) );
|
||||
if ( $excluded_ids ) {
|
||||
$excluded_ids = explode( ',', $excluded_ids );
|
||||
} else {
|
||||
$excluded_ids = array();
|
||||
}
|
||||
$excluded_ids[] = $remove_id;
|
||||
$excluded_ids = array_keys( array_flip( $excluded_ids ) );
|
||||
$excluded_ids = implode( ',', $excluded_ids );
|
||||
update_post_meta( $post_id, '_relevanssi_related_exclude_ids', $excluded_ids );
|
||||
|
||||
// Excluded IDs have changed, flush the cache.
|
||||
delete_post_meta( $post_id, '_relevanssi_related_posts' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a post ID from the excluded ID list and regenerates the lists.
|
||||
*
|
||||
* @since 2.2.4
|
||||
*/
|
||||
function relevanssi_remove_from_exclude_list() {
|
||||
check_ajax_referer( 'relevanssi_metabox_nonce', 'security' );
|
||||
if ( ! current_user_can( 'edit_posts' ) ) {
|
||||
wp_die();
|
||||
}
|
||||
|
||||
$post_id = (int) $_POST['post_id']; // WPCS: input var ok.
|
||||
|
||||
if ( 0 === $post_id ) {
|
||||
wp_die();
|
||||
}
|
||||
|
||||
if ( isset( $_POST['return_id'] ) ) {
|
||||
relevanssi_unexclude_a_related_post( $post_id, $_POST['return_id'] );
|
||||
}
|
||||
|
||||
$related = relevanssi_generate_related_list( $post_id );
|
||||
$excluded = relevanssi_generate_excluded_list( $post_id );
|
||||
|
||||
$response = array(
|
||||
'related' => $related,
|
||||
'excluded' => $excluded,
|
||||
);
|
||||
|
||||
echo wp_json_encode( $response );
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a post ID from the related posts exclude list.
|
||||
*
|
||||
* @param int $post_id The post ID that owns the related posts exclude list.
|
||||
* @param int $unexcluded_post The post ID which is removed from the exclude list.
|
||||
*/
|
||||
function relevanssi_unexclude_a_related_post( $post_id, $unexcluded_post ) {
|
||||
$return_id = (int) $unexcluded_post;
|
||||
$excluded_ids = trim( get_post_meta( $post_id, '_relevanssi_related_exclude_ids', true ) );
|
||||
$excluded_ids = array_flip( explode( ',', $excluded_ids ) );
|
||||
unset( $excluded_ids[ $return_id ] );
|
||||
$excluded_ids = array_keys( $excluded_ids );
|
||||
$excluded_ids = implode( ',', $excluded_ids );
|
||||
update_post_meta( $post_id, '_relevanssi_related_exclude_ids', $excluded_ids );
|
||||
|
||||
// Excluded IDs have changed, flush the cache.
|
||||
delete_post_meta( $post_id, '_relevanssi_related_posts' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a keyword to the pinned keywords list for a post.
|
||||
*
|
||||
* @since 2.2.6
|
||||
*/
|
||||
function relevanssi_pin_post() {
|
||||
check_ajax_referer( 'relevanssi_admin_search_nonce', 'security' );
|
||||
if ( ! current_user_can( 'edit_posts' ) ) {
|
||||
wp_die();
|
||||
}
|
||||
|
||||
$post_id = (int) $_POST['post_id']; // WPCS: input var ok.
|
||||
$keyword = $_POST['keyword']; // WPCS: input var ok.
|
||||
|
||||
if ( 0 === $post_id || empty( $keyword ) ) {
|
||||
wp_die();
|
||||
}
|
||||
|
||||
$result = false;
|
||||
$already_pinned = false;
|
||||
$pins = get_post_meta( $post_id, '_relevanssi_pin' );
|
||||
foreach ( $pins as $pin ) {
|
||||
if ( $pin === $keyword ) {
|
||||
$already_pinned = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( ! $already_pinned ) {
|
||||
$result = add_post_meta( $post_id, '_relevanssi_pin', $keyword );
|
||||
}
|
||||
|
||||
$response = array(
|
||||
'success' => $result,
|
||||
);
|
||||
|
||||
echo wp_json_encode( $response );
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a keyword from the pinned keywords list for a post.
|
||||
*
|
||||
* @since 2.2.6
|
||||
*/
|
||||
function relevanssi_unpin_post() {
|
||||
check_ajax_referer( 'relevanssi_admin_search_nonce', 'security' );
|
||||
if ( ! current_user_can( 'edit_posts' ) ) {
|
||||
wp_die();
|
||||
}
|
||||
|
||||
$post_id = (int) $_POST['post_id']; // WPCS: input var ok.
|
||||
$keyword = $_POST['keyword']; // WPCS: input var ok.
|
||||
|
||||
if ( 0 === $post_id || empty( $keyword ) ) {
|
||||
wp_die();
|
||||
}
|
||||
|
||||
$result = delete_post_meta( $post_id, '_relevanssi_pin', $keyword );
|
||||
|
||||
$response = array(
|
||||
'success' => $result,
|
||||
);
|
||||
|
||||
echo wp_json_encode( $response );
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches database words to the relevanssi_words option.
|
||||
*
|
||||
* An AJAX wrapper for relevanssi_update_words_option().
|
||||
*
|
||||
* @see relevanssi_update_words_option()
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function relevanssi_ajax_get_words() {
|
||||
if ( ! wp_verify_nonce( $_REQUEST['_nonce'], 'relevanssi_get_words' ) ) {
|
||||
wp_die();
|
||||
}
|
||||
|
||||
relevanssi_update_words_option();
|
||||
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Launches the attachment content indexing.
|
||||
*
|
||||
* Sets the _relevanssi_pdf_error for the post to show RELEVANSSI_ERROR_05
|
||||
* (ie. "work in progress"), then launches the indexing and dies off.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function relevanssi_ajax_index_pdf() {
|
||||
if ( ! wp_verify_nonce( $_REQUEST['_nonce'], 'relevanssi_index_pdf' ) ) {
|
||||
wp_die();
|
||||
}
|
||||
|
||||
if ( ! current_user_can( 'upload_files' ) ) {
|
||||
wp_die();
|
||||
}
|
||||
|
||||
$post_id = intval( $_REQUEST['post_id'] );
|
||||
|
||||
update_post_meta( $post_id, '_relevanssi_pdf_error', RELEVANSSI_ERROR_05 );
|
||||
|
||||
relevanssi_index_pdf( $post_id );
|
||||
|
||||
wp_die();
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
jQuery(document).ready(function ($) {
|
||||
$("#relevanssi_related_keywords").change(function (e) {
|
||||
var post_id = $("#this_post_id").val()
|
||||
var keywords = $("#relevanssi_related_keywords").val()
|
||||
var data = {
|
||||
action: "relevanssi_related_posts",
|
||||
security: relevanssi_metabox_data.metabox_nonce,
|
||||
post_id: post_id,
|
||||
keywords: keywords,
|
||||
}
|
||||
jQuery.post(ajaxurl, data, function (response) {
|
||||
response = JSON.parse(response)
|
||||
$("#related_posts_list").html(response.list)
|
||||
})
|
||||
})
|
||||
|
||||
$("#relevanssi_related_include_ids").change(function (e) {
|
||||
var post_id = $("#this_post_id").val()
|
||||
var ids = $("#relevanssi_related_include_ids").val()
|
||||
var data = {
|
||||
action: "relevanssi_related_posts",
|
||||
security: relevanssi_metabox_data.metabox_nonce,
|
||||
post_id: post_id,
|
||||
ids: ids,
|
||||
}
|
||||
jQuery.post(ajaxurl, data, function (response) {
|
||||
response = JSON.parse(response)
|
||||
$("#related_posts_list").html(response.list)
|
||||
})
|
||||
})
|
||||
|
||||
$("#relevanssi_hidebox").on("click", "button.removepost", function (e) {
|
||||
var remove_id = $(this).data("removepost")
|
||||
if (remove_id) {
|
||||
var post_id = $("#this_post_id").val()
|
||||
var data = {
|
||||
action: "relevanssi_related_remove",
|
||||
security: relevanssi_metabox_data.metabox_nonce,
|
||||
post_id: post_id,
|
||||
remove_id: remove_id,
|
||||
}
|
||||
jQuery.post(ajaxurl, data, function (response) {
|
||||
response = JSON.parse(response)
|
||||
|
||||
$("#related_posts_list").html(response.related)
|
||||
$("#excluded_posts_list").html(response.excluded)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
$("#relevanssi_hidebox").on("click", "button.returnpost", function (e) {
|
||||
var return_id = $(this).data("returnpost")
|
||||
console.log(return_id)
|
||||
if (return_id) {
|
||||
var post_id = $("#this_post_id").val()
|
||||
var data = {
|
||||
action: "relevanssi_related_return",
|
||||
security: relevanssi_metabox_data.metabox_nonce,
|
||||
post_id: post_id,
|
||||
return_id: return_id,
|
||||
}
|
||||
jQuery.post(ajaxurl, data, function (response) {
|
||||
response = JSON.parse(response)
|
||||
console.log(response)
|
||||
|
||||
$("#related_posts_list").html(response.related)
|
||||
$("#excluded_posts_list").html(response.excluded)
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
@@ -1,49 +0,0 @@
|
||||
jQuery(document).ready(function () {
|
||||
jQuery("#sendUrl").click(function (e) {
|
||||
e.preventDefault()
|
||||
var postID = jQuery("#sendUrl").data("post_id")
|
||||
console.log(postID)
|
||||
jQuery.ajax({
|
||||
url: ajaxurl,
|
||||
type: "POST",
|
||||
data: {
|
||||
action: "relevanssi_send_url",
|
||||
post_id: postID,
|
||||
security: admin_pdf_data.send_pdf_nonce,
|
||||
},
|
||||
dataType: "json",
|
||||
complete: function (data) {
|
||||
console.log(data)
|
||||
location.reload()
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
jQuery("#sendPdf").click(function (e) {
|
||||
e.preventDefault()
|
||||
var postID = jQuery("#sendPdf").data("post_id")
|
||||
console.log(postID)
|
||||
jQuery.ajax({
|
||||
url: ajaxurl,
|
||||
type: "POST",
|
||||
data: {
|
||||
action: "relevanssi_send_pdf",
|
||||
post_id: postID,
|
||||
security: admin_pdf_data.send_pdf_nonce,
|
||||
},
|
||||
dataType: "json",
|
||||
complete: function (data) {
|
||||
console.log(data)
|
||||
location.reload()
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
jQuery("textarea#relevanssi_pdf_content").focus(function () {
|
||||
jQuery(this).animate({ rows: 40, cols: 120 }, 500)
|
||||
})
|
||||
|
||||
jQuery("textarea#relevanssi_pdf_content").focusout(function () {
|
||||
jQuery(this).animate({ rows: 4, cols: 80 }, 500)
|
||||
})
|
||||
})
|
||||
@@ -1,540 +0,0 @@
|
||||
jQuery(document).ready(function ($) {
|
||||
// Show and hide the "Show Relevanssi for admins" setting on the Overview tab depending
|
||||
// on whether the "Hide Relevanssi" setting is enabled.
|
||||
var show_post_controls = $("#show_post_controls")
|
||||
$("#relevanssi_hide_post_controls").on("change", function () {
|
||||
show_post_controls.toggleClass("screen-reader-text")
|
||||
})
|
||||
|
||||
// Find out the latest row ID in the redirect table.
|
||||
var last_row_id = $(".redirect_table_row:last").attr("id")
|
||||
var redirect_row_index = 0
|
||||
if (last_row_id) {
|
||||
// There's a last row, we're on the Redirects tab.
|
||||
last_row_id = last_row_id.split("_")
|
||||
if (last_row_id.length > 1) {
|
||||
redirect_row_index = last_row_id[1]
|
||||
}
|
||||
}
|
||||
|
||||
// Adds a new row to the redirect table on the Redirects tab.
|
||||
$("#add_redirect").on("click", function (e) {
|
||||
redirect_row_index++
|
||||
$(".redirect_table_row:last")
|
||||
.clone(true)
|
||||
.attr("id", "row_" + redirect_row_index)
|
||||
.insertAfter(".redirect_table_row:last")
|
||||
|
||||
var query = $("#row_" + redirect_row_index + " input:first")
|
||||
query.val("")
|
||||
query.attr("name", "query_" + redirect_row_index)
|
||||
query.attr("id", "query_" + redirect_row_index)
|
||||
|
||||
var partial = $("#row_" + redirect_row_index + " input:checkbox")
|
||||
partial.prop("checked", false)
|
||||
partial.attr("name", "partial_" + redirect_row_index)
|
||||
partial.attr("id", "partial_" + redirect_row_index)
|
||||
|
||||
var url = $("#row_" + redirect_row_index + " input:eq(2)")
|
||||
url.val("")
|
||||
url.attr("id", "url_" + redirect_row_index)
|
||||
url.attr("name", "url_" + redirect_row_index)
|
||||
|
||||
var hits = $("#row_" + redirect_row_index + " input:last")
|
||||
hits.val("")
|
||||
hits.attr("name", "hits_" + redirect_row_index)
|
||||
hits.attr("id", "hits_" + redirect_row_index)
|
||||
|
||||
var hitsNumber = $("#row_" + redirect_row_index + " span:last")
|
||||
hitsNumber.html("0")
|
||||
})
|
||||
|
||||
// Related posts tab: if "Matching post types" is checked, disable and uncheck other options.
|
||||
$("input.matching").on("click", function (e) {
|
||||
if ($(this).is(":checked")) {
|
||||
$("input.nonmatching").prop("checked", false)
|
||||
$("input.nonmatching").attr("disabled", true)
|
||||
} else {
|
||||
$("input.nonmatching").attr("disabled", false)
|
||||
}
|
||||
})
|
||||
|
||||
// Related posts tab: Display default thumbnail option.
|
||||
$("#relevanssi_related_thumbnails").on("click", function (e) {
|
||||
$("#defaultthumbnail").toggleClass("screen-reader-text", !this.checked)
|
||||
})
|
||||
|
||||
// Redirects tab redirect table row removal.
|
||||
$(".remove").on("click", function (e) {
|
||||
e.preventDefault()
|
||||
if ($("#redirect_table >tbody >tr").length > 1) {
|
||||
// If there is more than one row in the table, remove the last row.
|
||||
$(this).closest("tr").remove()
|
||||
} else {
|
||||
// Only one row left, don't remove it (because adding rows is based on cloning).
|
||||
// Instead empty out the values.
|
||||
$(".redirect_table_row:last input:text").val("")
|
||||
$(".redirect_table_row:last input:checkbox").prop("checked", false)
|
||||
}
|
||||
})
|
||||
|
||||
// Related posts tab: Toggle settings for main switch.
|
||||
$("#relevanssi_related_enabled").on("click", function () {
|
||||
$("#tr_relevanssi_related_append input").attr("disabled", !this.checked)
|
||||
$("#tr_relevanssi_related_keyword input").attr("disabled", !this.checked)
|
||||
$("#relevanssi_related_number").attr("disabled", !this.checked)
|
||||
$("#relevanssi_related_months").attr("disabled", !this.checked)
|
||||
$("#tr_relevanssi_related_post_types input").attr("disabled", !this.checked)
|
||||
$("#relevanssi_related_nothing").attr("disabled", !this.checked)
|
||||
$("#relevanssi_related_notenough").attr("disabled", !this.checked)
|
||||
$("#relevanssi_related_titles").attr("disabled", !this.checked)
|
||||
$("#relevanssi_related_thumbnails").attr("disabled", !this.checked)
|
||||
$("#relevanssi_related_excerpts").attr("disabled", !this.checked)
|
||||
$("#relevanssi_related_cache_for_admins").attr("disabled", !this.checked)
|
||||
$("#relevanssi_flush_related_cache").attr("disabled", !this.checked)
|
||||
})
|
||||
|
||||
// Redirects tab redirect table row cloning.
|
||||
$("a.copy").on("click", function (e) {
|
||||
e.preventDefault()
|
||||
redirect_row_index++
|
||||
$(this)
|
||||
.closest("tr")
|
||||
.clone(true)
|
||||
.attr("id", "row_" + redirect_row_index)
|
||||
.insertAfter(".redirect_table_row:last")
|
||||
|
||||
var query = $("#row_" + redirect_row_index + " input:first")
|
||||
query.attr("name", "query_" + redirect_row_index)
|
||||
query.attr("id", "query_" + redirect_row_index)
|
||||
|
||||
var partial = $("#row_" + redirect_row_index + " input:checkbox")
|
||||
partial.attr("name", "partial_" + redirect_row_index)
|
||||
partial.attr("id", "partial_" + redirect_row_index)
|
||||
|
||||
var url = $("#row_" + redirect_row_index + " input:eq(2)")
|
||||
url.attr("name", "url_" + redirect_row_index)
|
||||
url.attr("name", "url_" + redirect_row_index)
|
||||
|
||||
var hits = $("#row_" + redirect_row_index + " input:last")
|
||||
hits.val("")
|
||||
hits.attr("name", "hits_" + redirect_row_index)
|
||||
hits.attr("id", "hits_" + redirect_row_index)
|
||||
|
||||
var hitsNumber = $("#row_" + redirect_row_index + " span:last")
|
||||
hitsNumber.html("0")
|
||||
})
|
||||
|
||||
$("#attachments_tab :input").on("change", function (e) {
|
||||
$("#index").attr("disabled", "disabled")
|
||||
var relevanssi_note = $("#relevanssi-note")
|
||||
relevanssi_note.show()
|
||||
relevanssi_note.html(
|
||||
'<p class="description important">' + relevanssi.options_changed + "</p>"
|
||||
)
|
||||
})
|
||||
|
||||
$("#build_index").on("click", function () {
|
||||
$("#relevanssi-progress").show()
|
||||
$("#results").show()
|
||||
$("#relevanssi-timer").show()
|
||||
$("#relevanssi-indexing-instructions").show()
|
||||
$("#stateoftheindex").html(relevanssi.reload_state)
|
||||
$("#indexing_button_instructions").hide()
|
||||
var results = document.getElementById("results")
|
||||
results.value = ""
|
||||
|
||||
var data = {
|
||||
action: "relevanssi_truncate_index",
|
||||
security: nonce.indexing_nonce,
|
||||
}
|
||||
|
||||
intervalID = window.setInterval(relevanssiUpdateClock, 1000)
|
||||
|
||||
console.log("Truncating index.")
|
||||
results.value += relevanssi.truncating_index + " "
|
||||
jQuery.post(ajaxurl, data, function (response) {
|
||||
truncate_response = JSON.parse(response)
|
||||
console.log("Truncate index: " + truncate_response)
|
||||
if (truncate_response == true) {
|
||||
results.value += relevanssi.done + "\n"
|
||||
}
|
||||
var data = {
|
||||
action: "relevanssi_index_post_type_archives",
|
||||
security: nonce.post_type_archive_indexing_nonce,
|
||||
}
|
||||
console.log("Indexing post type archives.")
|
||||
results.value += "Indexing post type archives... "
|
||||
jQuery.post(ajaxurl, data, function (response) {
|
||||
console.log("Done")
|
||||
response = JSON.parse(response)
|
||||
results.value += response.feedback
|
||||
var data = {
|
||||
action: "relevanssi_count_users",
|
||||
}
|
||||
console.log("Counting users.")
|
||||
results.value += relevanssi.counting_users + " "
|
||||
jQuery.post(ajaxurl, data, function (response) {
|
||||
count_response = JSON.parse(response)
|
||||
console.log("Counted " + count_response + " users.")
|
||||
if (count_response < 0) {
|
||||
results.value += relevanssi.user_disabled + "\n"
|
||||
} else {
|
||||
results.value +=
|
||||
count_response + " " + relevanssi.users_found + "\n"
|
||||
}
|
||||
|
||||
var user_total = count_response
|
||||
|
||||
var data = {
|
||||
action: "relevanssi_count_taxonomies",
|
||||
}
|
||||
console.log("Counting taxonomies.")
|
||||
results.value += relevanssi.counting_terms + " "
|
||||
jQuery.post(ajaxurl, data, function (response) {
|
||||
count_response = JSON.parse(response)
|
||||
console.log("Counted " + count_response + " taxonomy terms.")
|
||||
if (count_response < 0) {
|
||||
results.value += relevanssi.taxonomy_disabled + "\n"
|
||||
} else {
|
||||
results.value +=
|
||||
count_response + " " + relevanssi.terms_found + "\n"
|
||||
}
|
||||
|
||||
var taxonomy_total = count_response
|
||||
|
||||
var data = {
|
||||
action: "relevanssi_count_posts",
|
||||
}
|
||||
console.log("Counting posts.")
|
||||
results.value += relevanssi.counting_posts + " "
|
||||
jQuery.post(ajaxurl, data, function (response) {
|
||||
count_response = JSON.parse(response)
|
||||
console.log("Counted " + count_response + " posts.")
|
||||
var post_total = parseInt(count_response)
|
||||
results.value +=
|
||||
count_response + " " + relevanssi.posts_found + "\n"
|
||||
|
||||
var data = {
|
||||
action: "relevanssi_list_taxonomies",
|
||||
}
|
||||
console.log("Listing taxonomies.")
|
||||
jQuery.post(ajaxurl, data, function (response) {
|
||||
taxonomies_response = JSON.parse(response)
|
||||
console.log("Listing taxonomies: " + taxonomies_response)
|
||||
console.log("Starting indexing.")
|
||||
console.log("User total " + user_total)
|
||||
if (user_total > 0) {
|
||||
console.log("Indexing users.")
|
||||
var args = {
|
||||
total: user_total,
|
||||
completed: 0,
|
||||
total_seconds: 0,
|
||||
post_total: post_total,
|
||||
limit: 10,
|
||||
taxonomies: taxonomies_response,
|
||||
taxonomies_total: taxonomy_total,
|
||||
}
|
||||
process_user_step(args)
|
||||
} else if (taxonomy_total > 0) {
|
||||
console.log("Indexing taxonomies.")
|
||||
results.value += relevanssi.indexing_taxonomies + " "
|
||||
results.value += taxonomies_response + "\n"
|
||||
var args = {
|
||||
taxonomies: taxonomies_response,
|
||||
completed: 0,
|
||||
total: taxonomy_total,
|
||||
total_seconds: 0,
|
||||
post_total: post_total,
|
||||
current_taxonomy: "",
|
||||
offset: 0,
|
||||
limit: 20,
|
||||
}
|
||||
process_taxonomy_step(args)
|
||||
} else {
|
||||
console.log("Just indexing.")
|
||||
var args = {
|
||||
completed: 0,
|
||||
total: post_total,
|
||||
offset: 0,
|
||||
total_seconds: 0,
|
||||
limit: relevanssi_params.indexing_limit,
|
||||
adjust: relevanssi_params.indexing_adjust,
|
||||
extend: false,
|
||||
security: nonce.indexing_nonce,
|
||||
}
|
||||
process_indexing_step(args)
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
function process_user_step(args) {
|
||||
var completed = args.completed
|
||||
var total = args.total
|
||||
var total_seconds = args.total_seconds
|
||||
|
||||
console.log(completed + " / " + total)
|
||||
var t0 = performance.now()
|
||||
|
||||
jQuery.ajax({
|
||||
type: "POST",
|
||||
url: ajaxurl,
|
||||
data: {
|
||||
action: "relevanssi_index_users",
|
||||
limit: args.limit,
|
||||
offset: args.offset,
|
||||
completed: completed,
|
||||
total: total,
|
||||
security: nonce.user_indexing_nonce,
|
||||
},
|
||||
dataType: "json",
|
||||
success: function (response) {
|
||||
console.log(response)
|
||||
if (response.completed == "done") {
|
||||
var t1 = performance.now()
|
||||
var time_seconds = (t1 - t0) / 1000
|
||||
time_seconds = Math.round(time_seconds * 100) / 100
|
||||
total_seconds += time_seconds
|
||||
|
||||
var results_textarea = document.getElementById("results")
|
||||
results_textarea.value += response.feedback
|
||||
results_textarea.scrollTop = results_textarea.scrollHeight
|
||||
var percentage_rounded = Math.round(response.percentage)
|
||||
|
||||
jQuery(".rpi-progress div").animate(
|
||||
{
|
||||
width: percentage_rounded + "%",
|
||||
},
|
||||
50,
|
||||
function () {
|
||||
// Animation complete.
|
||||
}
|
||||
)
|
||||
|
||||
console.log("Done indexing users.")
|
||||
|
||||
if (args.taxonomies_total > 0) {
|
||||
var new_args = {
|
||||
completed: 0,
|
||||
total: args.taxonomies_total,
|
||||
taxonomies: args.taxonomies,
|
||||
current_taxonomy: "",
|
||||
post_total: args.post_total,
|
||||
offset: 0,
|
||||
total_seconds: total_seconds,
|
||||
limit: 20,
|
||||
extend: false,
|
||||
}
|
||||
process_taxonomy_step(new_args)
|
||||
} else {
|
||||
var new_args = {
|
||||
security: nonce.indexing_nonce,
|
||||
completed: 0,
|
||||
total: args.post_total,
|
||||
offset: 0,
|
||||
total_seconds: 0,
|
||||
limit: relevanssi_params.indexing_limit,
|
||||
adjust: relevanssi_params.indexing_adjust,
|
||||
extend: false,
|
||||
}
|
||||
process_indexing_step(new_args)
|
||||
}
|
||||
} else {
|
||||
var t1 = performance.now()
|
||||
var time_seconds = (t1 - t0) / 1000
|
||||
time_seconds = Math.round(time_seconds * 100) / 100
|
||||
total_seconds += time_seconds
|
||||
|
||||
var estimated_time = rlv_format_approximate_time(
|
||||
Math.round(
|
||||
(total_seconds / response.percentage) * 100 - total_seconds
|
||||
)
|
||||
)
|
||||
|
||||
document.getElementById("relevanssi_estimated").innerHTML =
|
||||
estimated_time
|
||||
|
||||
if (time_seconds < 2) {
|
||||
args.limit = args.limit * 2
|
||||
// current limit can be indexed in less than two seconds; double the limit
|
||||
} else if (time_seconds < 5) {
|
||||
args.limit += 5
|
||||
// current limit can be indexed in less than five seconds; up the limit
|
||||
} else if (time_seconds > 20) {
|
||||
args.limit = Math.round(args.limit / 2)
|
||||
if (args.limit < 1) args.limit = 1
|
||||
// current limit takes more than twenty seconds; halve the limit
|
||||
} else if (time_seconds > 10) {
|
||||
args.limit -= 5
|
||||
if (args.limit < 1) args.limit = 1
|
||||
// current limit takes more than ten seconds; reduce the limit
|
||||
}
|
||||
|
||||
var results_textarea = document.getElementById("results")
|
||||
results_textarea.value += response.feedback
|
||||
results_textarea.scrollTop = results_textarea.scrollHeight
|
||||
var percentage_rounded = Math.round(response.percentage)
|
||||
|
||||
jQuery(".rpi-progress div").animate(
|
||||
{
|
||||
width: percentage_rounded + "%",
|
||||
},
|
||||
50,
|
||||
function () {
|
||||
// Animation complete.
|
||||
}
|
||||
)
|
||||
console.log("Next step.")
|
||||
var new_args = {
|
||||
completed: parseInt(response.completed),
|
||||
total: args.total,
|
||||
total_seconds: total_seconds,
|
||||
offset: response.offset,
|
||||
limit: args.limit,
|
||||
post_total: args.post_total,
|
||||
taxonomies: args.taxonomies,
|
||||
taxonomies_total: args.taxonomies_total,
|
||||
}
|
||||
process_user_step(new_args)
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
function process_taxonomy_step(args) {
|
||||
var completed = args.completed
|
||||
var total = args.total
|
||||
var total_seconds = args.total_seconds
|
||||
|
||||
console.log(completed + " / " + total)
|
||||
var t0 = performance.now()
|
||||
|
||||
if (args.current_taxonomy == "") {
|
||||
taxonomy = args.taxonomies.shift()
|
||||
args.offset = 0
|
||||
args.limit = 20
|
||||
} else {
|
||||
taxonomy = args.current_taxonomy
|
||||
}
|
||||
|
||||
if (taxonomy != undefined) {
|
||||
var results_textarea = document.getElementById("results")
|
||||
results_textarea.value += "Indexing " + "'" + taxonomy + "': "
|
||||
jQuery.ajax({
|
||||
type: "POST",
|
||||
url: ajaxurl,
|
||||
data: {
|
||||
action: "relevanssi_index_taxonomies",
|
||||
completed: completed,
|
||||
total: total,
|
||||
taxonomy: taxonomy,
|
||||
offset: args.offset,
|
||||
limit: args.limit,
|
||||
security: nonce.taxonomy_indexing_nonce,
|
||||
},
|
||||
dataType: "json",
|
||||
success: function (response) {
|
||||
console.log(response)
|
||||
if (response.completed == "done") {
|
||||
var t1 = performance.now()
|
||||
var time_seconds = (t1 - t0) / 1000
|
||||
time_seconds = Math.round(time_seconds * 100) / 100
|
||||
total_seconds += time_seconds
|
||||
|
||||
var results_textarea = document.getElementById("results")
|
||||
results_textarea.value += response.feedback
|
||||
|
||||
console.log("Done indexing taxonomies.")
|
||||
|
||||
var new_args = {
|
||||
completed: 0,
|
||||
total: args.post_total,
|
||||
offset: 0,
|
||||
total_seconds: 0,
|
||||
limit: relevanssi_params.indexing_limit,
|
||||
adjust: relevanssi_params.indexing_adjust,
|
||||
extend: false,
|
||||
security: nonce.indexing_nonce,
|
||||
}
|
||||
process_indexing_step(new_args)
|
||||
} else {
|
||||
var t1 = performance.now()
|
||||
var time_seconds = (t1 - t0) / 1000
|
||||
time_seconds = Math.round(time_seconds * 100) / 100
|
||||
total_seconds += time_seconds
|
||||
|
||||
var estimated_time = rlv_format_approximate_time(
|
||||
Math.round(
|
||||
(total_seconds / response.percentage) * 100 - total_seconds
|
||||
)
|
||||
)
|
||||
|
||||
document.getElementById("relevanssi_estimated").innerHTML =
|
||||
estimated_time
|
||||
|
||||
if (time_seconds < 2) {
|
||||
args.limit = args.limit * 2
|
||||
// current limit can be indexed in less than two seconds; double the limit
|
||||
} else if (time_seconds < 5) {
|
||||
args.limit += 5
|
||||
// current limit can be indexed in less than five seconds; up the limit
|
||||
} else if (time_seconds > 20) {
|
||||
args.limit = Math.round(args.limit / 2)
|
||||
if (args.limit < 1) args.limit = 1
|
||||
// current limit takes more than twenty seconds; halve the limit
|
||||
} else if (time_seconds > 10) {
|
||||
args.limit -= 5
|
||||
if (args.limit < 1) args.limit = 1
|
||||
// current limit takes more than ten seconds; reduce the limit
|
||||
}
|
||||
|
||||
var results_textarea = document.getElementById("results")
|
||||
results_textarea.value += response.feedback
|
||||
results_textarea.scrollTop = results_textarea.scrollHeight
|
||||
var percentage_rounded = Math.round(response.percentage)
|
||||
|
||||
jQuery(".rpi-progress div").animate(
|
||||
{
|
||||
width: percentage_rounded + "%",
|
||||
},
|
||||
50,
|
||||
function () {
|
||||
// Animation complete.
|
||||
}
|
||||
)
|
||||
console.log("Next step.")
|
||||
if (response.new_taxonomy) taxonomy = ""
|
||||
var new_args = {
|
||||
taxonomies: args.taxonomies,
|
||||
completed: parseInt(response.completed),
|
||||
total: args.total,
|
||||
total_seconds: total_seconds,
|
||||
post_total: args.post_total,
|
||||
current_taxonomy: taxonomy,
|
||||
offset: response.offset,
|
||||
limit: args.limit,
|
||||
}
|
||||
process_taxonomy_step(new_args)
|
||||
}
|
||||
},
|
||||
})
|
||||
} else {
|
||||
var new_args = {
|
||||
completed: 0,
|
||||
total: args.post_total,
|
||||
offset: 0,
|
||||
total_seconds: 0,
|
||||
limit: relevanssi_params.indexing_limit,
|
||||
adjust: relevanssi_params.indexing_adjust,
|
||||
extend: false,
|
||||
security: nonce.indexing_nonce,
|
||||
}
|
||||
process_indexing_step(new_args)
|
||||
}
|
||||
}
|
||||
@@ -1,388 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* /premium/body-stopwords.php
|
||||
*
|
||||
* @package Relevanssi
|
||||
* @author Mikko Saari
|
||||
* @license https://wordpress.org/about/gpl/ GNU General Public License
|
||||
* @see https://www.relevanssi.com/
|
||||
*/
|
||||
|
||||
add_filter( 'relevanssi_match', 'relevanssi_block_body_stopwords', 10, 3 );
|
||||
|
||||
/**
|
||||
* Adds a stopword to the list of stopwords.
|
||||
*
|
||||
* @param string $term The stopword that is added.
|
||||
* @param boolean $verbose If true, print out notice. If false, be silent. Default
|
||||
* true.
|
||||
*
|
||||
* @return boolean True, if success; false otherwise.
|
||||
*/
|
||||
function relevanssi_add_body_stopword( $term, $verbose = true ) {
|
||||
if ( empty( $term ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$n = 0;
|
||||
$s = 0;
|
||||
|
||||
$terms = explode( ',', $term );
|
||||
if ( count( $terms ) > 1 ) {
|
||||
foreach ( $terms as $term ) {
|
||||
++$n;
|
||||
$term = trim( $term );
|
||||
$success = relevanssi_add_single_body_stopword( $term );
|
||||
if ( $success ) {
|
||||
++$s;
|
||||
}
|
||||
}
|
||||
if ( $verbose ) {
|
||||
// translators: %1$d is the successful entries, %2$d is the total entries.
|
||||
printf( "<div id='message' class='updated fade'><p>%s</p></div>", sprintf( esc_html__( 'Successfully added %1$d/%2$d terms to content stopwords!', 'relevanssi' ), intval( $s ), intval( $n ) ) );
|
||||
}
|
||||
} else {
|
||||
// Add to stopwords.
|
||||
$success = relevanssi_add_single_body_stopword( $term );
|
||||
|
||||
$term = stripslashes( $term );
|
||||
$term = esc_html( $term );
|
||||
if ( $verbose ) {
|
||||
if ( $success ) {
|
||||
// Translators: %s is the stopword.
|
||||
printf( "<div id='message' class='updated fade'><p>%s</p></div>", sprintf( esc_html__( "Term '%s' added to content stopwords!", 'relevanssi' ), esc_html( stripslashes( $term ) ) ) );
|
||||
} else {
|
||||
// Translators: %s is the stopword.
|
||||
printf( "<div id='message' class='updated fade'><p>%s</p></div>", sprintf( esc_html__( "Couldn't add term '%s' to content stopwords!", 'relevanssi' ), esc_html( stripslashes( $term ) ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a single stopword to the stopword table.
|
||||
*
|
||||
* @global object $wpdb The WP database interface.
|
||||
* @global array $relevanssi_variables The global Relevanssi variables.
|
||||
*
|
||||
* @param string $term The term to add.
|
||||
*
|
||||
* @return boolean True if success, false if not.
|
||||
*/
|
||||
function relevanssi_add_single_body_stopword( $term ) {
|
||||
if ( empty( $term ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$term = stripslashes( relevanssi_strtolower( $term ) );
|
||||
$stopwords = relevanssi_fetch_body_stopwords();
|
||||
|
||||
if ( in_array( $term, $stopwords, true ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$stopwords[] = $term;
|
||||
|
||||
$success = relevanssi_update_body_stopwords( $stopwords );
|
||||
|
||||
if ( ! $success ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
global $wpdb, $relevanssi_variables;
|
||||
|
||||
relevanssi_delete_term_from_all_post_content( $term );
|
||||
|
||||
// Remove all lines with all zeros, ie. no matches.
|
||||
$wpdb->query(
|
||||
'DELETE FROM '
|
||||
. $relevanssi_variables['relevanssi_table'] // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
. ' WHERE content + title + comment + tag + link + author + category + excerpt + taxonomy + customfield + mysqlcolumn = 0'
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a term from all posts in the database, language considered.
|
||||
*
|
||||
* If Polylang or WPML are used, deletes the term only from the posts matching
|
||||
* the current language.
|
||||
*
|
||||
* @param string $term The term to delete.
|
||||
*/
|
||||
function relevanssi_delete_term_from_all_post_content( $term ) {
|
||||
global $wpdb, $relevanssi_variables;
|
||||
|
||||
if ( function_exists( 'pll_languages_list' ) ) {
|
||||
$term_id = relevanssi_get_language_term_taxonomy_id(
|
||||
relevanssi_get_current_language()
|
||||
);
|
||||
|
||||
$wpdb->query(
|
||||
$wpdb->prepare(
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
"UPDATE {$relevanssi_variables['relevanssi_table']}
|
||||
SET content = 0
|
||||
WHERE term=%s
|
||||
AND doc IN (
|
||||
SELECT object_id
|
||||
FROM $wpdb->term_relationships
|
||||
WHERE term_taxonomy_id = %d
|
||||
)",
|
||||
$term,
|
||||
$term_id
|
||||
)
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( function_exists( 'icl_object_id' ) && ! function_exists( 'pll_is_translated_post_type' ) ) {
|
||||
$language = relevanssi_get_current_language( false );
|
||||
$wpdb->query(
|
||||
$wpdb->prepare(
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
"UPDATE {$relevanssi_variables['relevanssi_table']}
|
||||
SET content = 0
|
||||
WHERE term=%s
|
||||
AND doc IN (
|
||||
SELECT DISTINCT(element_id)
|
||||
FROM {$wpdb->prefix}icl_translations
|
||||
WHERE language_code = %s
|
||||
)",
|
||||
$term,
|
||||
$language
|
||||
)
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// No language defined, just remove from the index.
|
||||
$wpdb->query(
|
||||
$wpdb->prepare(
|
||||
'UPDATE ' . $relevanssi_variables['relevanssi_table'] . ' SET content = 0 WHERE term=%s', // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
$term
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all content stopwords in specific language.
|
||||
*
|
||||
* Empties the relevanssi_body_stopwords option for particular language.
|
||||
*
|
||||
* @param string $language The language code of stopwords. If empty, removes
|
||||
* the stopwords for the current language.
|
||||
*/
|
||||
function relevanssi_remove_all_body_stopwords( $language = null ) {
|
||||
if ( ! $language ) {
|
||||
$language = relevanssi_get_current_language();
|
||||
}
|
||||
|
||||
$stopwords = get_option( 'relevanssi_body_stopwords', array() );
|
||||
unset( $stopwords[ $language ] );
|
||||
$success = update_option( 'relevanssi_body_stopwords', $stopwords );
|
||||
|
||||
if ( $success ) {
|
||||
printf(
|
||||
"<div id='message' class='updated fade'><p>%s</p></div>",
|
||||
esc_html__( 'All content stopwords removed! Remember to re-index.', 'relevanssi' )
|
||||
);
|
||||
} else {
|
||||
printf(
|
||||
"<div id='message' class='updated fade'><p>%s</p></div>",
|
||||
esc_html__( "There was a problem, and content stopwords couldn't be removed.", 'relevanssi' )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the current language content stopwords in the stopwords option.
|
||||
*
|
||||
* Fetches the stopwords option, replaces the current language stopwords with
|
||||
* the parameter array and updates the option.
|
||||
*
|
||||
* @param array $stopwords An array of stopwords.
|
||||
*
|
||||
* @return boolean The return value from update_option().
|
||||
*/
|
||||
function relevanssi_update_body_stopwords( $stopwords ) {
|
||||
$current_language = relevanssi_get_current_language();
|
||||
$stopwords_option = get_option( 'relevanssi_body_stopwords', array() );
|
||||
|
||||
$stopwords_option[ $current_language ] = implode( ',', array_filter( $stopwords ) );
|
||||
return update_option(
|
||||
'relevanssi_body_stopwords',
|
||||
$stopwords_option
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a single content stopword.
|
||||
*
|
||||
* @param string $term The stopword to remove.
|
||||
* @param boolean $verbose If true, print out a notice. Default true.
|
||||
*
|
||||
* @return boolean True if success, false if not.
|
||||
*/
|
||||
function relevanssi_remove_body_stopword( $term, $verbose = true ) {
|
||||
$stopwords = relevanssi_fetch_body_stopwords();
|
||||
$term = stripslashes( $term );
|
||||
$stopwords = array_filter(
|
||||
$stopwords,
|
||||
function ( $stopword ) use ( $term ) {
|
||||
return $stopword !== $term;
|
||||
}
|
||||
);
|
||||
|
||||
$success = relevanssi_update_body_stopwords( $stopwords );
|
||||
|
||||
if ( $success ) {
|
||||
if ( $verbose ) {
|
||||
printf(
|
||||
"<div id='message' class='updated fade'><p>%s</p></div>",
|
||||
sprintf(
|
||||
// Translators: %s is the stopword.
|
||||
esc_html__(
|
||||
"Term '%s' removed from content stopwords! Re-index to get it back to index.",
|
||||
'relevanssi'
|
||||
),
|
||||
esc_html( stripslashes( $term ) )
|
||||
)
|
||||
);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
if ( $verbose ) {
|
||||
printf(
|
||||
"<div id='message' class='updated fade'><p>%s</p></div>",
|
||||
sprintf(
|
||||
// Translators: %s is the stopword.
|
||||
esc_html__(
|
||||
"Couldn't remove term '%s' from content stopwords!",
|
||||
'relevanssi'
|
||||
),
|
||||
esc_html( stripslashes( $term ) )
|
||||
)
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the list of content stopwords.
|
||||
*
|
||||
* Gets the list of content stopwords from the options.
|
||||
*
|
||||
* @return array An array of stopwords.
|
||||
*/
|
||||
function relevanssi_fetch_body_stopwords() {
|
||||
$current_language = relevanssi_get_current_language();
|
||||
$stopwords_array = get_option( 'relevanssi_body_stopwords', array() );
|
||||
$stopwords = isset( $stopwords_array[ $current_language ] ) ? $stopwords_array[ $current_language ] : '';
|
||||
$stopword_list = $stopwords ? explode( ',', $stopwords ) : array();
|
||||
|
||||
return $stopword_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a list of body stopwords.
|
||||
*
|
||||
* Displays the list of body stopwords and gives the controls for adding new stopwords.
|
||||
*/
|
||||
function relevanssi_show_body_stopwords() {
|
||||
printf(
|
||||
'<p>%s</p>',
|
||||
esc_html__( 'Post content stopwords are like stopwords, but they are only applied to the post content. These words can be used for searching and will be found in post titles, custom fields and other indexed content – just not in the post body content. Sometimes a word can be very common, but also have a more specific meaning and use on your site, and making it a content stopword will make it easier to find the specific use cases.', 'relevanssi' )
|
||||
);
|
||||
?>
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="addbodystopword"><p><?php esc_html_e( 'Content stopword(s) to add', 'relevanssi' ); ?>
|
||||
</th>
|
||||
<td>
|
||||
<textarea name="addbodystopword" id="addbodystopword" rows="2" cols="80"></textarea>
|
||||
<p><input type="submit" value="<?php esc_attr_e( 'Add', 'relevanssi' ); ?>" class='button' /></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p><?php esc_html_e( "Here's a list of content stopwords in the database. Click a word to remove it from content stopwords. You need to reindex the database to get the words back in to the index.", 'relevanssi' ); ?></p>
|
||||
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<?php esc_html_e( 'Current content stopwords', 'relevanssi' ); ?>
|
||||
</th>
|
||||
<td>
|
||||
<ul>
|
||||
<?php
|
||||
$stopwords = array_map( 'stripslashes', relevanssi_fetch_body_stopwords() );
|
||||
$exportlist = htmlspecialchars( implode( ', ', $stopwords ) );
|
||||
sort( $stopwords );
|
||||
array_walk(
|
||||
$stopwords,
|
||||
function ( $term ) {
|
||||
printf( '<li style="display: inline;"><input type="submit" name="removebodystopword" value="%s"/></li>', esc_attr( $term ) );
|
||||
}
|
||||
);
|
||||
|
||||
?>
|
||||
</ul>
|
||||
<p><input type="submit" id="removeallbodystopwords" name="removeallbodystopwords" value="<?php esc_attr_e( 'Remove all content stopwords', 'relevanssi' ); ?>" class='button' /></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<?php esc_html_e( 'Exportable list of content stopwords', 'relevanssi' ); ?>
|
||||
</th>
|
||||
<td>
|
||||
<label for="bodystopwords" class="screen-reader-text"><?php esc_html_e( 'Exportable list of content stopwords', 'relevanssi' ); ?></label>
|
||||
<textarea name="bodystopwords" id="bodystopwords" rows="2" cols="80"><?php echo esc_textarea( $exportlist ); ?></textarea>
|
||||
<p class="description"><?php esc_html_e( 'You can copy the list of content stopwords from here if you want to back up the list, copy it to a different blog or otherwise need the list.', 'relevanssi' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Blocks body stopwords from partial matches.
|
||||
*
|
||||
* If the search term is a body stopword, all cases where all the matches are
|
||||
* in the post content are removed from the results by setting the match
|
||||
* weight to 0. This will eliminate all partial matches based on body stopwords
|
||||
* from the results.
|
||||
*
|
||||
* @param object $match_object The match object.
|
||||
* @param int $idf The IDF value (not used here).
|
||||
* @param string $term The original search term.
|
||||
*
|
||||
* @return object The match object.
|
||||
*/
|
||||
function relevanssi_block_body_stopwords( $match_object, $idf, $term ) {
|
||||
$body_stopwords = relevanssi_fetch_body_stopwords();
|
||||
if ( in_array( $term, $body_stopwords, true ) ) {
|
||||
$sum = $match_object->content
|
||||
+ $match_object->title
|
||||
+ $match_object->comment
|
||||
+ $match_object->link
|
||||
+ $match_object->author
|
||||
+ $match_object->excerpt
|
||||
+ $match_object->customfield
|
||||
+ $match_object->mysqlcolumn
|
||||
+ $match_object->tag
|
||||
+ $match_object->taxonomy
|
||||
+ $match_object->category;
|
||||
if ( (int) $match_object->content === (int) $sum ) {
|
||||
$match_object->weight = 0;
|
||||
}
|
||||
}
|
||||
return $match_object;
|
||||
}
|
||||
@@ -1,211 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Main T15S library.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @package WP_Translations\T15S_registry
|
||||
*/
|
||||
|
||||
/**
|
||||
* TranslationsPress features.
|
||||
*/
|
||||
class Relevanssi_Language_Packs {
|
||||
|
||||
/**
|
||||
* Project type, either plugin or theme.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type;
|
||||
|
||||
/**
|
||||
* Project directory slug.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $slug;
|
||||
|
||||
/**
|
||||
* Full GlotPress API URL.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $api_url;
|
||||
|
||||
/**
|
||||
* The class constructor.
|
||||
*
|
||||
* @param string $type Project type, either plugin or theme.
|
||||
* @param string $slug Project directory slug.
|
||||
* @param string $api_url Full GlotPress API URL.
|
||||
*/
|
||||
public function __construct( $type, $slug, $api_url ) {
|
||||
$this->type = $type;
|
||||
$this->slug = $slug;
|
||||
$this->api_url = $api_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new project to load translations for.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function add_project() {
|
||||
if ( ! has_action( 'init', array( $this, 'register_clean_translations_cache' ) ) ) {
|
||||
add_action( 'init', array( $this, 'register_clean_translations_cache' ), 9999 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Short-circuits translations API requests for private projects.
|
||||
*/
|
||||
add_filter(
|
||||
'translations_api',
|
||||
function ( $result, $requested_type, $args ) {
|
||||
if ( $this->type . 's' === $requested_type && $this->slug === $args['slug'] ) {
|
||||
return $this->get_translations( $this->type, $args['slug'], $this->api_url );
|
||||
}
|
||||
|
||||
return $result;
|
||||
},
|
||||
10,
|
||||
3
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters the translations transients to include the private plugin or theme.
|
||||
*
|
||||
* @see wp_get_translation_updates()
|
||||
*/
|
||||
add_filter(
|
||||
'site_transient_update_' . $this->type . 's',
|
||||
function ( $value ) {
|
||||
if ( ! $value ) {
|
||||
$value = new \stdClass();
|
||||
}
|
||||
|
||||
if ( ! isset( $value->translations ) ) {
|
||||
$value->translations = array();
|
||||
}
|
||||
|
||||
$translations = $this->get_translations( $this->type, $this->slug, $this->api_url );
|
||||
|
||||
if ( ! isset( $translations['translations'] ) ) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$installed_translations = wp_get_installed_translations( $this->type . 's' );
|
||||
|
||||
foreach ( (array) $translations['translations'] as $translation ) {
|
||||
if ( in_array( $translation['language'], get_available_languages(), true ) ) {
|
||||
if ( isset( $installed_translations[ $this->slug ][ $translation['language'] ] ) && $translation['updated'] ) {
|
||||
$local = new DateTime( $installed_translations[ $this->slug ][ $translation['language'] ]['PO-Revision-Date'] );
|
||||
$remote = new DateTime( $translation['updated'] );
|
||||
|
||||
if ( $local >= $remote ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$translation['type'] = $this->type;
|
||||
$translation['slug'] = $this->slug;
|
||||
|
||||
$value->translations[] = $translation;
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers actions for clearing translation caches.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public function register_clean_translations_cache() {
|
||||
$clear_plugin_translations = function () {
|
||||
$this->clean_translations_cache( 'plugin' );
|
||||
};
|
||||
$clear_theme_translations = function () {
|
||||
$this->clean_translations_cache( 'theme' );
|
||||
};
|
||||
|
||||
add_action( 'set_site_transient_update_plugins', $clear_plugin_translations );
|
||||
add_action( 'delete_site_transient_update_plugins', $clear_plugin_translations );
|
||||
|
||||
add_action( 'set_site_transient_update_themes', $clear_theme_translations );
|
||||
add_action( 'delete_site_transient_update_themes', $clear_theme_translations );
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears existing translation cache for a given type.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*
|
||||
* @param string $type Project type. Either plugin or theme.
|
||||
*/
|
||||
public function clean_translations_cache( $type ) {
|
||||
$transient_key = 't15s-registry-' . $this->slug . '-' . $type;
|
||||
$translations = get_site_transient( $transient_key );
|
||||
|
||||
if ( ! is_object( $translations ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't delete the cache if the transient gets changed multiple times
|
||||
* during a single request. Set cache lifetime to maximum 15 seconds.
|
||||
*/
|
||||
$cache_lifespan = 15;
|
||||
$time_not_changed = isset( $translations->_last_checked ) && ( time() - $translations->_last_checked ) > $cache_lifespan;
|
||||
|
||||
if ( ! $time_not_changed ) {
|
||||
return;
|
||||
}
|
||||
|
||||
delete_site_transient( $transient_key );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the translations for a given project.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param string $type Project type. Either plugin or theme.
|
||||
* @param string $slug Project directory slug.
|
||||
* @param string $url Full GlotPress API URL for the project.
|
||||
*
|
||||
* @return array Translation data.
|
||||
*/
|
||||
public function get_translations( $type, $slug, $url ) {
|
||||
$transient_key = 't15s-registry-' . $slug . '-' . $type;
|
||||
$translations = get_site_transient( $transient_key );
|
||||
|
||||
if ( ! is_object( $translations ) ) {
|
||||
$translations = new \stdClass();
|
||||
}
|
||||
|
||||
if ( isset( $translations->{$slug} ) && is_array( $translations->{$slug} ) ) {
|
||||
return $translations->{$slug};
|
||||
}
|
||||
|
||||
$result = json_decode(
|
||||
wp_remote_retrieve_body(
|
||||
wp_remote_get( $url, array( 'timeout' => 2 ) )
|
||||
),
|
||||
true
|
||||
);
|
||||
if ( is_array( $result ) ) {
|
||||
$translations->{$slug} = $result;
|
||||
$translations->_last_checked = time();
|
||||
|
||||
set_site_transient( $transient_key, $translations );
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Nothing found.
|
||||
return array();
|
||||
}
|
||||
}
|
||||
@@ -1,221 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* /premium/class-spellcorrector.php
|
||||
*
|
||||
* @package Relevanssi_Premium
|
||||
* @author Felipe Ribeiro <felipernb@gmail.com> with modifications by Mikko Saari
|
||||
* @see https://www.relevanssi.com/
|
||||
*/
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Copyright (C) 2008 by Felipe Ribeiro *
|
||||
* felipernb@gmail.com *
|
||||
* http://www.feliperibeiro.com *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining *
|
||||
* a copy of this software and associated documentation files (the *
|
||||
* "Software"), to deal in the Software without restriction, including *
|
||||
* without limitation the rights to use, copy, modify, merge, publish, *
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to *
|
||||
* the following conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be *
|
||||
* included in all copies or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR *
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
|
||||
* OTHER DEALINGS IN THE SOFTWARE. *
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
* Spell correcting feature.
|
||||
*
|
||||
* This class implements the Spell correcting feature, useful for the
|
||||
* "Did you mean" functionality on the search engine. Using a dictionary of
|
||||
* words extracted from the product catalog.
|
||||
*
|
||||
* Based on the concepts of Peter Norvig: http://norvig.com/spell-correct.html
|
||||
*
|
||||
* @author Felipe Ribeiro <felipernb@gmail.com>
|
||||
* @date September 18th, 2008
|
||||
*/
|
||||
class Relevanssi_SpellCorrector {
|
||||
/**
|
||||
* Dictionary of words.
|
||||
*
|
||||
* @var array $dictionary Array of words, containing the dictionary.
|
||||
*/
|
||||
private static $dictionary;
|
||||
|
||||
/**
|
||||
* Reads a text and extracts the list of words.
|
||||
*
|
||||
* @param string $text Source text for the words.
|
||||
* @return array The list of words
|
||||
*/
|
||||
private static function words( $text ) {
|
||||
$matches = array();
|
||||
$text = relevanssi_strtolower( $text );
|
||||
preg_match_all( '/[a-z]+/', $text, $matches );
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a list of possible "disturbances" on the passed string.
|
||||
*
|
||||
* @param string $word Word to disturb.
|
||||
*
|
||||
* @return array A list of variations.
|
||||
*/
|
||||
private static function edits1( $word ) {
|
||||
/**
|
||||
* Filters the alphabet used for Did you mean suggestions.
|
||||
*
|
||||
* In order to use the Did you mean suggestions with non-Latin alphabets
|
||||
* (or even European languages with a wider range of characters than
|
||||
* English), Relevanssi needs to be provided with the alphabet used.
|
||||
*
|
||||
* @param string A string containing the alphabet as a string of
|
||||
* characters without spaces.
|
||||
*/
|
||||
$alphabet = apply_filters(
|
||||
'relevanssi_didyoumean_alphabet',
|
||||
'abcdefghijklmnopqrstuvwxyzäöåü'
|
||||
);
|
||||
$alphabet = preg_split( '/(?<!^)(?!$)/u', $alphabet );
|
||||
$n = relevanssi_strlen( $word );
|
||||
$edits = array();
|
||||
|
||||
$substr_function = 'substr';
|
||||
if ( function_exists( 'mb_substr' ) ) {
|
||||
$substr_function = 'mb_substr';
|
||||
}
|
||||
for ( $i = 0; $i < $n; $i++ ) {
|
||||
// Removing one letter.
|
||||
$edits[] = call_user_func( $substr_function, $word, 0, $i )
|
||||
. call_user_func( $substr_function, $word, $i + 1 );
|
||||
|
||||
// Substituting one letter.
|
||||
foreach ( $alphabet as $c ) {
|
||||
$edits[] = call_user_func( $substr_function, $word, 0, $i )
|
||||
. $c . call_user_func( $substr_function, $word, $i + 1 );
|
||||
}
|
||||
}
|
||||
for ( $i = 0; $i < $n - 1; $i++ ) {
|
||||
// Swapping character order.
|
||||
$edits[] = call_user_func( $substr_function, $word, 0, $i )
|
||||
. $word[ $i + 1 ] . $word[ $i ]
|
||||
. call_user_func( $substr_function, $word, $i + 2 );
|
||||
}
|
||||
|
||||
// Inserting one character.
|
||||
for ( $i = 0; $i < $n + 1; $i++ ) {
|
||||
foreach ( $alphabet as $c ) {
|
||||
$edits[] = call_user_func( $substr_function, $word, 0, $i )
|
||||
. $c . call_user_func( $substr_function, $word, $i );
|
||||
}
|
||||
}
|
||||
|
||||
return $edits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate possible "disturbances" in a second level that exist on the
|
||||
* dictionary.
|
||||
*
|
||||
* @param string $word Word to disturb.
|
||||
*
|
||||
* @return array Known disturbances.
|
||||
*/
|
||||
private static function known_edits2( $word ) {
|
||||
$known = array();
|
||||
foreach ( self::edits1( $word ) as $e1 ) {
|
||||
foreach ( self::edits1( $e1 ) as $e2 ) {
|
||||
if ( array_key_exists( $e2, self::$dictionary ) ) {
|
||||
$known[] = $e2;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $known;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a list of words, returns the subset that is present on the
|
||||
* dictionary.
|
||||
*
|
||||
* @param array $words Array of words to check.
|
||||
* @return array Words that are in the dictionary.
|
||||
*/
|
||||
private static function known( array $words ) {
|
||||
$known = array();
|
||||
foreach ( $words as $w ) {
|
||||
if ( array_key_exists( $w, self::$dictionary ) ) {
|
||||
$known[] = $w;
|
||||
}
|
||||
}
|
||||
return $known;
|
||||
}
|
||||
|
||||
/**
|
||||
* Corrects the word.
|
||||
*
|
||||
* Returns the word that is present on the dictionary that is the most
|
||||
* similar (and the most relevant) to the word passed as parameter.
|
||||
*
|
||||
* @param string $word Word to correct.
|
||||
*
|
||||
* @return string Correction suggestion, null if nothing found.
|
||||
*/
|
||||
public static function correct( $word ) {
|
||||
$word = trim( $word );
|
||||
|
||||
if ( empty( $word ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$word = relevanssi_strtolower( $word );
|
||||
|
||||
if ( empty( self::$dictionary ) ) {
|
||||
self::$dictionary = relevanssi_get_words();
|
||||
}
|
||||
|
||||
$candidates = array();
|
||||
if ( self::known( array( $word ) ) ) {
|
||||
// Word is in the dictionary. It's fine.
|
||||
return true;
|
||||
} else {
|
||||
$tmp_candidates = self::known( self::edits1( $word ) );
|
||||
if ( ! empty( $tmp_candidates ) ) {
|
||||
foreach ( $tmp_candidates as $candidate ) {
|
||||
$candidates[] = $candidate;
|
||||
}
|
||||
} else {
|
||||
$tmp_candidates = self::known_edits2( $word );
|
||||
if ( ! empty( $tmp_candidates ) ) {
|
||||
foreach ( $tmp_candidates as $candidate ) {
|
||||
$candidates[] = $candidate;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
$max = 0;
|
||||
|
||||
foreach ( $candidates as $c ) {
|
||||
$value = self::$dictionary[ $c ];
|
||||
if ( $value > $max ) {
|
||||
$max = $value;
|
||||
$word = $c;
|
||||
}
|
||||
}
|
||||
return $word;
|
||||
}
|
||||
}
|
||||
@@ -1,222 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* /premium/class-relevanssi-wp-auto-update.php
|
||||
*
|
||||
* @package Relevanssi_Premium
|
||||
* @author Mikko Saari
|
||||
* @license https://wordpress.org/about/gpl/ GNU General Public License
|
||||
* @see https://www.relevanssi.com/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Manages the auto update system for Relevanssi Premium.
|
||||
*
|
||||
* Manages the auto updates, getting update information from Relevanssi.com and passing it to the WordPress update system.
|
||||
*/
|
||||
class Relevanssi_WP_Auto_Update {
|
||||
/**
|
||||
* The plugin current version
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $current_version;
|
||||
|
||||
/**
|
||||
* The plugin remote update path
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $update_path;
|
||||
|
||||
/**
|
||||
* Plugin Slug (plugin_directory/plugin_file.php)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $plugin_slug;
|
||||
|
||||
/**
|
||||
* Plugin name (plugin_file)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $slug;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the WordPress Auto-Update class
|
||||
*
|
||||
* @param string $current_version Current version of the plugin.
|
||||
* @param string $update_path Path to the remove service.
|
||||
* @param string $plugin_slug Plugin slug.
|
||||
*/
|
||||
public function __construct( $current_version, $update_path, $plugin_slug ) {
|
||||
// Set the class public variables.
|
||||
$this->current_version = $current_version;
|
||||
$this->update_path = $update_path;
|
||||
$this->plugin_slug = $plugin_slug;
|
||||
list ($t1, $t2) = explode( '/', $plugin_slug );
|
||||
$this->slug = str_replace( '.php', '', $t2 );
|
||||
|
||||
if ( 'on' !== get_option( 'relevanssi_do_not_call_home' ) ) {
|
||||
// define the alternative API for updating checking.
|
||||
add_filter( 'pre_set_site_transient_update_plugins', array( &$this, 'check_update' ) );
|
||||
|
||||
// Define the alternative response for information checking.
|
||||
add_filter( 'plugins_api', array( &$this, 'check_info' ), 10, 3 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds our self-hosted autoupdate plugin to the filter transient.
|
||||
*
|
||||
* @param object $transient The filtered transient.
|
||||
*
|
||||
* @return object $transient
|
||||
*/
|
||||
public function check_update( $transient ) {
|
||||
if ( ! is_object( $transient ) ) {
|
||||
return $transient;
|
||||
}
|
||||
|
||||
// Get the remote version.
|
||||
$info = $this->get_remote_information();
|
||||
$remote_version = 0;
|
||||
if ( isset( $info->new_version ) ) {
|
||||
$remote_version = $info->new_version;
|
||||
}
|
||||
|
||||
// If a newer version is available, add the update.
|
||||
if ( version_compare( $this->current_version, $remote_version, '<' ) ) {
|
||||
$obj = new stdClass();
|
||||
$obj->slug = $this->slug;
|
||||
$obj->new_version = $remote_version;
|
||||
$obj->url = $info->package;
|
||||
$obj->package = $info->package;
|
||||
$obj->icons = $info->icons;
|
||||
$obj->banners = $info->banners;
|
||||
|
||||
$transient->response[ $this->plugin_slug ] = $obj;
|
||||
} else {
|
||||
global $relevanssi_variables;
|
||||
// No update is available.
|
||||
$item = (object) array(
|
||||
'id' => 'relevanssi-premium/relevanssi.php',
|
||||
'slug' => 'relevanssi-premium',
|
||||
'plugin' => 'relevanssi-premium/relevanssi.php',
|
||||
'new_version' => $relevanssi_variables['plugin_version'],
|
||||
'url' => '',
|
||||
'package' => '',
|
||||
'icons' => array(),
|
||||
'banners' => array(),
|
||||
'banners_rtl' => array(),
|
||||
'tested' => '',
|
||||
'requires_php' => '',
|
||||
'compatibility' => new stdClass(),
|
||||
);
|
||||
$transient->no_update['relevanssi-premium/relevanssi.php'] = $item;
|
||||
}
|
||||
|
||||
return $transient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds our self-hosted description to the filter.
|
||||
*
|
||||
* @param object $api Result object or array, should return false.
|
||||
* @param array $action Type of information request.
|
||||
* @param object $args Plugin API arguments.
|
||||
*
|
||||
* @return object $api New stdClass with plugin information on success, default response on failure.
|
||||
*/
|
||||
public function check_info( $api, $action, $args ) {
|
||||
$plugin = ( 'plugin_information' === $action ) && isset( $args->slug ) && ( $this->slug === $args->slug );
|
||||
|
||||
if ( $plugin ) {
|
||||
if ( $args->slug === $this->slug ) {
|
||||
$information = $this->get_remote_information();
|
||||
return $information;
|
||||
}
|
||||
}
|
||||
return $api;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the remote version.
|
||||
*
|
||||
* @return string $remote_version Version number at the remote end.
|
||||
*/
|
||||
public function get_remote_version() {
|
||||
$api_key = get_network_option( null, 'relevanssi_api_key' );
|
||||
if ( ! $api_key ) {
|
||||
$api_key = get_option( 'relevanssi_api_key' );
|
||||
}
|
||||
$request = wp_remote_post(
|
||||
$this->update_path,
|
||||
array(
|
||||
'body' => array(
|
||||
'api_key' => $api_key,
|
||||
'action' => 'version',
|
||||
),
|
||||
)
|
||||
);
|
||||
if ( ! is_wp_error( $request ) || 200 === wp_remote_retrieve_response_code( $request ) ) {
|
||||
return $request['body'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information about the remote version.
|
||||
*
|
||||
* @return bool|object
|
||||
*/
|
||||
public function get_remote_information() {
|
||||
$api_key = get_network_option( null, 'relevanssi_api_key' );
|
||||
if ( ! $api_key ) {
|
||||
$api_key = get_option( 'relevanssi_api_key' );
|
||||
}
|
||||
$request = wp_remote_post(
|
||||
$this->update_path,
|
||||
array(
|
||||
'body' => array(
|
||||
'api_key' => $api_key,
|
||||
'action' => 'info',
|
||||
),
|
||||
)
|
||||
);
|
||||
if ( ! is_wp_error( $request ) || 200 === wp_remote_retrieve_response_code( $request ) ) {
|
||||
if ( is_serialized( $request['body'] ) ) {
|
||||
return unserialize( $request['body'] ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the status of the plugin licensing.
|
||||
*
|
||||
* @return boolean $remote_license
|
||||
*/
|
||||
public function get_remote_license() {
|
||||
$api_key = get_network_option( null, 'relevanssi_api_key' );
|
||||
if ( ! $api_key ) {
|
||||
$api_key = get_option( 'relevanssi_api_key' );
|
||||
}
|
||||
$request = wp_remote_post(
|
||||
$this->update_path,
|
||||
array(
|
||||
'body' => array(
|
||||
'api_key' => $api_key,
|
||||
'action' => 'license',
|
||||
),
|
||||
)
|
||||
);
|
||||
if ( ! is_wp_error( $request ) || 200 === wp_remote_retrieve_response_code( $request ) ) {
|
||||
if ( 'false' === $request['body'] ) {
|
||||
return false;
|
||||
}
|
||||
return $request['body'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,714 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* /premium/class-relevanssi-wp-cli-command.php
|
||||
*
|
||||
* @package Relevanssi_Premium
|
||||
* @author Mikko Saari
|
||||
* @license https://wordpress.org/about/gpl/ GNU General Public License
|
||||
* @see https://www.relevanssi.com/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Relevanssi Premium WP CLI command.
|
||||
*
|
||||
* Implements the WP CLI support for Relevanssi Premium.
|
||||
*/
|
||||
class Relevanssi_WP_CLI_Command extends WP_CLI_Command {
|
||||
|
||||
/**
|
||||
* Rebuilds the index or reindexes one post.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [--target=<target>]
|
||||
* : What to index. No value means everything. Valid values are
|
||||
* "taxonomies" and "users" to index taxonomy terms and user profiles
|
||||
* respectively.
|
||||
* ---
|
||||
* options:
|
||||
* - post_types
|
||||
* - taxonomies
|
||||
* - users
|
||||
* ---
|
||||
*
|
||||
* [--post=<post_ID>]
|
||||
* : Post ID, if you only want to reindex one post.
|
||||
*
|
||||
* [--limit=<limit>]
|
||||
* : Number of posts you want to index at one go.
|
||||
*
|
||||
* [--extend=<extend>]
|
||||
* : If true, do not truncate the index or index users and taxonomies.
|
||||
* If false, first truncate the index, then index user profiles and
|
||||
* taxonomy terms.
|
||||
* ---
|
||||
* default: false
|
||||
* options:
|
||||
* - true
|
||||
* - false
|
||||
* ---
|
||||
*
|
||||
* [--index_debug=<debug>]
|
||||
* : If true, display debugging information when indexing a single post.
|
||||
* ---
|
||||
* default: false
|
||||
* options:
|
||||
* - true
|
||||
* - false
|
||||
* ---
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp relevanssi index
|
||||
* wp relevanssi index --post=1
|
||||
* wp relevanssi index --target=taxonomies
|
||||
* wp relevanssi index --target=users
|
||||
* wp relevanssi index --post=1 --index_debug=true
|
||||
* wp relevanssi index --limit=100
|
||||
* wp relevanssi index --extend=true --limit=100
|
||||
*
|
||||
* @param array $args Command arguments (not used).
|
||||
* @param array $assoc_args Command arguments as associative array.
|
||||
*/
|
||||
public function index( $args, $assoc_args ) {
|
||||
remove_filter( 'relevanssi_search_ok', '__return_true' );
|
||||
|
||||
$post_id = null;
|
||||
if ( isset( $assoc_args['post'] ) ) {
|
||||
$post_id = $assoc_args['post'];
|
||||
}
|
||||
|
||||
$limit = null;
|
||||
if ( isset( $assoc_args['limit'] ) ) {
|
||||
$limit = $assoc_args['limit'];
|
||||
}
|
||||
|
||||
$extend = false;
|
||||
if ( isset( $assoc_args['extend'] ) ) {
|
||||
$extend = $assoc_args['extend'];
|
||||
}
|
||||
|
||||
$debug = false;
|
||||
if ( isset( $assoc_args['index_debug'] ) ) {
|
||||
$debug = $assoc_args['index_debug'];
|
||||
}
|
||||
|
||||
$target = null;
|
||||
if ( isset( $assoc_args['target'] ) ) {
|
||||
$target = $assoc_args['target'];
|
||||
}
|
||||
|
||||
if ( 'taxonomies' === $target ) {
|
||||
relevanssi_index_taxonomies();
|
||||
WP_CLI::success( 'Done!' );
|
||||
} elseif ( 'users' === $target ) {
|
||||
relevanssi_index_users();
|
||||
WP_CLI::success( 'Done!' );
|
||||
} elseif ( 'post_types' === $target ) {
|
||||
relevanssi_index_post_type_archives();
|
||||
WP_CLI::success( 'Done!' );
|
||||
} elseif ( isset( $post_id ) ) {
|
||||
$n = relevanssi_index_doc( $post_id, true, relevanssi_get_custom_fields(), true, $debug );
|
||||
switch ( $n ) {
|
||||
case -1:
|
||||
WP_CLI::error( "No such post: $post_id!" );
|
||||
break;
|
||||
case 'hide':
|
||||
WP_CLI::error( "Post $post_id is excluded from indexing." );
|
||||
break;
|
||||
case 'donotindex':
|
||||
WP_CLI::error( "Post $post_id is excluded from indexing by the relevanssi_do_not_index filter." );
|
||||
break;
|
||||
default:
|
||||
WP_CLI::success( "Reindexed post $post_id!" );
|
||||
}
|
||||
} else {
|
||||
$verbose = false;
|
||||
list( $complete, $n ) = relevanssi_build_index( $extend, $verbose, $limit );
|
||||
|
||||
$completion = 'Index is not complete yet.';
|
||||
if ( $complete ) {
|
||||
$completion = 'Index is complete.';
|
||||
}
|
||||
|
||||
WP_CLI::success( "$n posts indexed. $completion" );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the Relevanssi index.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp relevanssi refresh
|
||||
*
|
||||
* @param array $args Command arguments (not used).
|
||||
* @param array $assoc_args Command arguments as associative array.
|
||||
*/
|
||||
public function refresh( $args, $assoc_args ) {
|
||||
$index_post_types = get_option( 'relevanssi_index_post_types', '' );
|
||||
$index_statuses = apply_filters(
|
||||
'relevanssi_valid_status',
|
||||
array( 'publish', 'private', 'draft', 'pending', 'future' )
|
||||
);
|
||||
$all_indexed_posts = get_posts(
|
||||
array(
|
||||
'post_type' => $index_post_types,
|
||||
'fields' => 'ids',
|
||||
'numberposts' => -1,
|
||||
'post_status' => $index_statuses,
|
||||
)
|
||||
);
|
||||
|
||||
$found_posts = count( $all_indexed_posts );
|
||||
$progress = $this->relevanssi_generate_progress_bar( 'Indexing posts', $found_posts );
|
||||
|
||||
WP_CLI::log( 'Found ' . $found_posts . ' posts to refresh.' );
|
||||
foreach ( $all_indexed_posts as $post_id ) {
|
||||
relevanssi_index_doc( $post_id, true, relevanssi_get_custom_fields(), true, false );
|
||||
$progress->tick();
|
||||
}
|
||||
$progress->finish();
|
||||
|
||||
WP_CLI::success( 'Index refresh done!' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Empties the Relevanssi index.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp relevanssi truncate_index
|
||||
*
|
||||
* @param array $args Command arguments (not used).
|
||||
* @param array $assoc_args Command arguments as associative array.
|
||||
*/
|
||||
public function truncate_index( $args, $assoc_args ) {
|
||||
$result = relevanssi_truncate_index();
|
||||
switch ( $result ) {
|
||||
case false:
|
||||
WP_CLI::error( "Couldn't truncate the Relevanssi database!" );
|
||||
break;
|
||||
default:
|
||||
WP_CLI::success( 'Relevanssi database truncated.' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a stopword to the list of stopwords and removes it from the index.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <stopword>...
|
||||
* : Stopwords to add.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp relevanssi add_stopword stop halt seis
|
||||
*
|
||||
* @param array $args Command arguments (not used).
|
||||
* @param array $assoc_args Command arguments as associative array.
|
||||
*/
|
||||
public function add_stopword( $args, $assoc_args ) {
|
||||
if ( is_array( $args ) ) {
|
||||
foreach ( $args as $stopword ) {
|
||||
if ( relevanssi_add_single_stopword( $stopword ) ) {
|
||||
WP_CLI::success( "Stopword added: $stopword" );
|
||||
} else {
|
||||
WP_CLI::error( "Couldn't add stopword: $stopword!" );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
WP_CLI::error( 'No stopwords listed.' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a stopword from the list of stopwords. Reindex to get it back to the index.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <stopword>...
|
||||
* : Stopwords to remove.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp relevanssi remove_stopword stop halt seis
|
||||
*
|
||||
* @param array $args Command arguments (not used).
|
||||
* @param array $assoc_args Command arguments as associative array.
|
||||
*/
|
||||
public function remove_stopword( $args, $assoc_args ) {
|
||||
$verbose = false;
|
||||
if ( is_array( $args ) ) {
|
||||
foreach ( $args as $stopword ) {
|
||||
if ( relevanssi_remove_stopword( $stopword, $verbose ) ) {
|
||||
WP_CLI::success( "Stopword removed: $stopword" );
|
||||
} else {
|
||||
WP_CLI::error( "Couldn't remove stopword: $stopword!" );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
WP_CLI::error( 'No stopwords listed.' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Empties the Relevanssi logs.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp relevanssi reset_log
|
||||
*
|
||||
* @param array $args Command arguments (not used).
|
||||
* @param array $assoc_args Command arguments as associative array.
|
||||
*/
|
||||
public function reset_log( $args, $assoc_args ) {
|
||||
$verbose = false;
|
||||
$result = relevanssi_truncate_logs( $verbose );
|
||||
switch ( $result ) {
|
||||
case false:
|
||||
WP_CLI::error( "Couldn't reset the logs!" );
|
||||
break;
|
||||
default:
|
||||
WP_CLI::success( 'Relevanssi log truncated.' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows common words in the index.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [--limit=<limit>]
|
||||
* : How many words to show. Defaults to 25.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp relevanssi common
|
||||
*
|
||||
* @param array $args Command arguments (not used).
|
||||
* @param array $assoc_args Command arguments as associative array.
|
||||
*/
|
||||
public function common( $args, $assoc_args ) {
|
||||
$wp_cli = true;
|
||||
$limit = 25;
|
||||
if ( isset( $assoc_args['limit'] ) && is_numeric( $assoc_args['limit'] ) ) {
|
||||
$limit = $assoc_args['limit'];
|
||||
}
|
||||
|
||||
$words = relevanssi_common_words( $limit, $wp_cli );
|
||||
if ( is_array( $words ) ) {
|
||||
foreach ( $words as $word ) {
|
||||
WP_CLI::log( sprintf( '%s (%d)', $word->term, $word->cnt ) );
|
||||
}
|
||||
} else {
|
||||
WP_CLI::error( 'No words returned.' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the attachment content for all attachments that haven't been read
|
||||
* yet.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp relevanssi read_attachments
|
||||
*
|
||||
* @param array $args Command arguments (not used).
|
||||
* @param array $assoc_args Command arguments as associative array.
|
||||
*/
|
||||
public function read_attachments( $args, $assoc_args ) {
|
||||
$attachment_posts = relevanssi_get_posts_with_attachments( 0 );
|
||||
WP_CLI::log( 'Found ' . count( $attachment_posts ) . ' attachments to read.' );
|
||||
foreach ( $attachment_posts as $post_id ) {
|
||||
$exit_and_die = false;
|
||||
WP_CLI::log( 'Reading attachment ' . $post_id . '...' );
|
||||
$response = relevanssi_index_pdf( $post_id, $exit_and_die );
|
||||
if ( $response['success'] ) {
|
||||
WP_CLI::log( "Successfully read the content for post $post_id." );
|
||||
} else {
|
||||
WP_CLI::log( "Couldn't read the post $post_id: " . $response['error'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all attachment content for all posts. Use with care! Does not
|
||||
* reindex the posts or remove them from the index.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp relevanssi remove_attachment_content
|
||||
*
|
||||
* @param array $args Command arguments (not used).
|
||||
* @param array $assoc_args Command arguments as associative array (not
|
||||
* used).
|
||||
*/
|
||||
public function remove_attachment_content( $args, $assoc_args ) {
|
||||
delete_post_meta_by_key( '_relevanssi_pdf_content' );
|
||||
delete_post_meta_by_key( '_relevanssi_pdf_error' );
|
||||
|
||||
WP_CLI::log( 'Removed all attachment content.' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all attachment errors for all posts.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp relevanssi remove_attachment_errors
|
||||
*
|
||||
* @param array $args Command arguments (not used).
|
||||
* @param array $assoc_args Command arguments as associative array (not
|
||||
* used).
|
||||
*/
|
||||
public function remove_attachment_errors( $args, $assoc_args ) {
|
||||
delete_post_meta_by_key( '_relevanssi_pdf_error' );
|
||||
|
||||
WP_CLI::log( 'Removed all attachment errors.' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Regenerates the related posts for all posts.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [--post_type=<post_types>]
|
||||
* : A comma-separated list of post types to cover. If empty, generate the post
|
||||
* types chosen in the Related posts options, or if that's empty, all public post
|
||||
* types.
|
||||
*
|
||||
* [--post_objects=<post_objects>]
|
||||
* : If true, doesn't generate the related posts HTML code and instead stores the
|
||||
* post objects of the related posts in the transient. If false, the transient
|
||||
* will contain the generated related posts HTML code. Default false.
|
||||
* ---
|
||||
* default: false
|
||||
* options:
|
||||
* - true
|
||||
* - false
|
||||
* ---
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp relevanssi regenerate_related
|
||||
* wp relevanssi regenerate_related --post_type=post,page
|
||||
*
|
||||
* @param array $args Command arguments (not used).
|
||||
* @param array $assoc_args Command arguments as associative array.
|
||||
*/
|
||||
public function regenerate_related( $args, $assoc_args ) {
|
||||
relevanssi_flush_related_cache();
|
||||
|
||||
$settings = get_option( 'relevanssi_related_settings', relevanssi_related_default_settings() );
|
||||
|
||||
if ( isset( $settings['enabled'] ) && 'off' === $settings['enabled'] ) {
|
||||
WP_CLI::error( 'Related posts feature is disabled.' );
|
||||
}
|
||||
|
||||
$post_types = array();
|
||||
if ( isset( $settings['append'] ) && ! empty( $settings['append'] ) ) {
|
||||
// Related posts are automatically appended to certain post types, so
|
||||
// regenerate the related posts for those post types.
|
||||
$post_types = explode( ',', $settings['append'] );
|
||||
} else {
|
||||
// Nothing set, so regenerate for all public post types.
|
||||
$pt_args = array(
|
||||
'public' => true,
|
||||
);
|
||||
$post_types = get_post_types( $pt_args, 'names' );
|
||||
}
|
||||
|
||||
if ( isset( $assoc_args['post_type'] ) ) {
|
||||
$post_types = explode( ',', $assoc_args['post_type'] );
|
||||
}
|
||||
|
||||
$post_objects = false;
|
||||
if ( isset( $assoc_args['post_objects'] ) ) {
|
||||
if ( filter_var( $assoc_args['post_objects'], FILTER_VALIDATE_BOOLEAN ) ) {
|
||||
$post_objects = true;
|
||||
}
|
||||
}
|
||||
|
||||
$post_args = array(
|
||||
'post_type' => $post_types,
|
||||
'fields' => 'ids',
|
||||
'posts_per_page' => -1,
|
||||
);
|
||||
$posts = get_posts( $post_args ); // Get all posts for the wanted post types.
|
||||
$count = count( $posts );
|
||||
WP_CLI::log( 'Regenerating related posts for post types ' . implode( ', ', $post_types ) . ", total $count posts." );
|
||||
|
||||
$progress = $this->relevanssi_generate_progress_bar( 'Regenerating', $count );
|
||||
|
||||
foreach ( $posts as $post_id ) {
|
||||
relevanssi_related_posts( $post_id, $post_objects );
|
||||
$progress->tick();
|
||||
}
|
||||
|
||||
$progress->finish();
|
||||
WP_CLI::success( 'Done!' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists pinned posts.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [--format=<format>]
|
||||
* : Format of the results. Possible values are "table", "json", "csv",
|
||||
* "yaml" and "count". Default: "table".
|
||||
*
|
||||
* [--type=<type>]
|
||||
* : Type of the results. Possible values are "pinned", "unpinned", and
|
||||
* "both". Default: "both".
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp relevanssi list_pinned_posts
|
||||
* wp relevanssi list_pinned_posts --format=csv --type=pinned
|
||||
*
|
||||
* @param array $args Command arguments (not used).
|
||||
* @param array $assoc_args Command arguments as associative array.
|
||||
*/
|
||||
public function list_pinned_posts( $args, $assoc_args ) {
|
||||
global $wpdb;
|
||||
|
||||
$posts = $wpdb->get_results(
|
||||
"SELECT p.ID, p.post_title, pm.meta_key, pm.meta_value FROM $wpdb->posts AS p, $wpdb->postmeta AS pm
|
||||
WHERE p.ID = pm.post_id
|
||||
AND (
|
||||
pm.meta_key = '_relevanssi_pin'
|
||||
OR pm.meta_key = '_relevanssi_unpin'
|
||||
OR (
|
||||
pm.meta_key = '_relevanssi_pin_for_all' AND pm.meta_value = 'on'
|
||||
)
|
||||
)
|
||||
ORDER BY p.ID ASC"
|
||||
);
|
||||
|
||||
$pinned = array();
|
||||
$unpinned = array();
|
||||
|
||||
$format = $assoc_args['format'] ?? 'table';
|
||||
if ( 'ids' === $format ) {
|
||||
$format = 'table';
|
||||
}
|
||||
|
||||
$include_pinned = true;
|
||||
$include_unpinned = true;
|
||||
if ( isset( $assoc_args['type'] ) ) {
|
||||
if ( 'pinned' === $assoc_args['type'] ) {
|
||||
$include_unpinned = false;
|
||||
} elseif ( 'unpinned' === $assoc_args['type'] ) {
|
||||
$include_pinned = false;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $posts as $post ) {
|
||||
if ( $include_pinned && '_relevanssi_pin_for_all' === $post->meta_key ) {
|
||||
$pinned[] = array(
|
||||
'ID' => $post->ID,
|
||||
'Title' => $post->post_title,
|
||||
'Pinned keywords' => __( 'all keywords' ),
|
||||
);
|
||||
} elseif ( $include_pinned && '_relevanssi_pin' === $post->meta_key ) {
|
||||
$pinned[] = array(
|
||||
'ID' => $post->ID,
|
||||
'Title' => $post->post_title,
|
||||
'Pinned keywords' => $post->meta_value,
|
||||
);
|
||||
} elseif ( $include_unpinned && '_relevanssi_unpin' === $post->meta_key ) {
|
||||
$unpinned[] = array(
|
||||
'ID' => $post->ID,
|
||||
'Title' => $post->post_title,
|
||||
'Unpinned keywords' => $post->meta_value,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( $pinned ) {
|
||||
if ( 'table' === $format || 'count' === $format ) {
|
||||
$header = "\n" . __( 'Pinned posts' ) . ':';
|
||||
WP_CLI::log( $header );
|
||||
WP_CLI::log( str_pad( '', strlen( $header ), '=' ) );
|
||||
}
|
||||
WP_CLI\Utils\format_items( $format, $pinned, array( 'ID', 'Title', 'Pinned keywords' ) );
|
||||
}
|
||||
|
||||
if ( $unpinned ) {
|
||||
if ( 'table' === $format || 'count' === $format ) {
|
||||
$header = "\n" . __( 'Unpinned posts' ) . ':';
|
||||
WP_CLI::log( $header );
|
||||
WP_CLI::log( str_pad( '', strlen( $header ), '=' ) );
|
||||
}
|
||||
WP_CLI\Utils\format_items( $format, $unpinned, array( 'ID', 'Title', 'Unpinned keywords' ) );
|
||||
}
|
||||
|
||||
if ( ! $pinned && ! $unpinned ) {
|
||||
WP_CLI::log( __( 'No pinned posts found.' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists posts in or not in the index.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [--format=<format>]
|
||||
* : Format of the results. Possible values are "table", "json", "csv",
|
||||
* "yaml", and "count". Default: "table".
|
||||
*
|
||||
* [--post_type=<type>]
|
||||
* : Post type. Default: none, show all post types.
|
||||
*
|
||||
* [--type=<type>]
|
||||
* : Type of the results. Possible values are "post", "term", and "user".
|
||||
* Default: "post".
|
||||
*
|
||||
* [--status=<status>]
|
||||
* : Status of the results. Possible values are "indexed" and "unindexed".
|
||||
* Default: "indexed".
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp relevanssi list
|
||||
*
|
||||
* @param array $args Command arguments (not used).
|
||||
* @param array $assoc_args Command arguments as associative array.
|
||||
*/
|
||||
public function list( $args, $assoc_args ) {
|
||||
global $wpdb, $relevanssi_variables;
|
||||
|
||||
$status = $assoc_args['status'] ?? 'indexed';
|
||||
$post_type = $assoc_args['post_type'] ?? '';
|
||||
$type = $assoc_args['type'] ?? 'post';
|
||||
|
||||
if ( 'indexed' === $status ) {
|
||||
if ( 'post' === $type ) {
|
||||
if ( $post_type ) {
|
||||
$post_type = "AND post_type = '" . esc_sql( $post_type ) . "'";
|
||||
}
|
||||
$posts = $wpdb->get_results(
|
||||
"SELECT DISTINCT(p.ID), p.post_title AS Title, p.post_type AS 'Type' FROM $wpdb->posts AS p, " .
|
||||
"{$relevanssi_variables['relevanssi_table']} AS r WHERE p.ID = r.doc $post_type " . // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
'ORDER BY p.ID ASC'
|
||||
);
|
||||
} elseif ( 'term' === $type ) {
|
||||
$posts = $wpdb->get_results(
|
||||
"SELECT DISTINCT(t.term_id) AS ID, t.name AS 'Name', tt.taxonomy AS 'Taxonomy', tt.count AS 'Count' FROM $wpdb->terms AS t, $wpdb->term_taxonomy AS tt, " .
|
||||
"{$relevanssi_variables['relevanssi_table']} AS r " . // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
'WHERE tt.term_id = t.term_id AND t.term_id = r.item AND tt.taxonomy = r.type
|
||||
ORDER BY t.term_id ASC'
|
||||
);
|
||||
} elseif ( 'user' === $type ) {
|
||||
$users_in_index = $wpdb->get_col(
|
||||
"SELECT DISTINCT(r.item) FROM {$relevanssi_variables['relevanssi_table']} AS r " . // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
"WHERE r.type = 'user'"
|
||||
);
|
||||
$users = relevanssi_get_users(
|
||||
array(
|
||||
'number' => -1,
|
||||
'orderby' => 'ID',
|
||||
'order' => 'ASC',
|
||||
'include' => array_map( 'intval', $users_in_index ),
|
||||
)
|
||||
);
|
||||
foreach ( $users as $user ) {
|
||||
$posts[] = array(
|
||||
'ID' => $user->ID,
|
||||
'Name' => $user->display_name,
|
||||
'Login' => $user->user_login,
|
||||
'Roles' => implode( ', ', $user->roles ),
|
||||
);
|
||||
}
|
||||
}
|
||||
} elseif ( 'unindexed' === $status ) {
|
||||
if ( 'post' === $type ) {
|
||||
$indexed_post_types = str_replace( 'post.', 'p.', relevanssi_post_type_restriction() );
|
||||
if ( $post_type ) {
|
||||
$post_type = "AND post_type = '" . esc_sql( $post_type ) . "'";
|
||||
$indexed_post_types = '';
|
||||
}
|
||||
|
||||
$posts = $wpdb->get_results(
|
||||
"SELECT DISTINCT(p.ID), p.post_title AS Title, p.post_type AS 'Type' FROM $wpdb->posts AS p " .
|
||||
"LEFT JOIN {$relevanssi_variables['relevanssi_table']} AS r ON p.ID = r.doc " . // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
'WHERE r.doc IS NULL ' .
|
||||
"$indexed_post_types $post_type " . // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
'ORDER BY p.ID ASC'
|
||||
);
|
||||
} elseif ( 'term' === $type ) {
|
||||
$taxonomies = get_option( 'relevanssi_index_terms' );
|
||||
if ( ! is_array( $taxonomies ) ) {
|
||||
$taxonomies = array();
|
||||
}
|
||||
$taxonomies = "'" . implode( "', '", $taxonomies ) . "'";
|
||||
|
||||
$posts = $wpdb->get_results(
|
||||
"SELECT DISTINCT(t.term_id) AS ID, t.name AS 'Name', tt.taxonomy AS 'Taxonomy', tt.count AS 'Count' " .
|
||||
"FROM $wpdb->term_taxonomy AS tt, $wpdb->terms AS t " .
|
||||
"LEFT JOIN {$relevanssi_variables['relevanssi_table']} AS r " . // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
'ON t.term_id = r.item
|
||||
WHERE r.item IS NULL AND tt.term_id = t.term_id AND tt.taxonomy IN (' . $taxonomies . ') ' . // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
'ORDER BY t.term_id ASC'
|
||||
);
|
||||
} elseif ( 'user' === $type ) {
|
||||
$users_in_index = $wpdb->get_col(
|
||||
"SELECT DISTINCT(r.item) FROM {$relevanssi_variables['relevanssi_table']} AS r " . // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
"WHERE r.type = 'user'"
|
||||
);
|
||||
$users = relevanssi_get_users(
|
||||
array(
|
||||
'number' => -1,
|
||||
'orderby' => 'ID',
|
||||
'order' => 'ASC',
|
||||
'exclude' => $users_in_index,
|
||||
)
|
||||
);
|
||||
foreach ( $users as $user ) {
|
||||
$posts[] = array(
|
||||
'ID' => $user->ID,
|
||||
'Name' => $user->display_name,
|
||||
'Login' => $user->user_login,
|
||||
'Roles' => implode( ', ', $user->roles ),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$format = $assoc_args['format'] ?? 'table';
|
||||
if ( 'ids' === $format ) {
|
||||
$format = 'table';
|
||||
}
|
||||
|
||||
if ( 'post' === $type ) {
|
||||
WP_CLI\Utils\format_items( $format, $posts, array( 'ID', 'Title', 'Type' ) );
|
||||
} elseif ( 'term' === $type ) {
|
||||
WP_CLI\Utils\format_items( $format, $posts, array( 'ID', 'Name', 'Taxonomy', 'Count' ) );
|
||||
} elseif ( 'user' === $type ) {
|
||||
WP_CLI\Utils\format_items( $format, $posts, array( 'ID', 'Name', 'Login', 'Roles' ) );
|
||||
} elseif ( 'post_type' === $type ) {
|
||||
WP_CLI\Utils\format_items( $format, $posts, array( 'Title', 'Type' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a WP CLI progress bar.
|
||||
*
|
||||
* If WP CLI is enabled, creates a progress bar using WP_CLI\Utils\make_progress_bar().
|
||||
*
|
||||
* @param string $title Title of the progress bar.
|
||||
* @param int $count Total count for the bar.
|
||||
*/
|
||||
public static function relevanssi_generate_progress_bar( $title, $count ) {
|
||||
$progress = null;
|
||||
if ( defined( 'WP_CLI' ) && WP_CLI ) {
|
||||
$progress = WP_CLI\Utils\make_progress_bar( $title, $count );
|
||||
}
|
||||
return $progress;
|
||||
}
|
||||
}
|
||||
|
||||
WP_CLI::add_command( 'relevanssi', 'Relevanssi_WP_Cli_Command' );
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,103 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* /premium/contextual-help.php
|
||||
*
|
||||
* Contextual help for Premium features.
|
||||
*
|
||||
* @package Relevanssi_Premium
|
||||
* @author Mikko Saari
|
||||
* @license https://wordpress.org/about/gpl/ GNU General Public License
|
||||
* @see https://www.relevanssi.com/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adds the Premium contextual help messages.
|
||||
*
|
||||
* Adds the Premium only contextual help messages to the WordPress contextual help menu.
|
||||
*/
|
||||
function relevanssi_premium_admin_help() {
|
||||
$screen = get_current_screen();
|
||||
$screen->add_help_tab(
|
||||
array(
|
||||
'id' => 'relevanssi-boolean',
|
||||
'title' => __( 'Boolean operators', 'relevanssi' ),
|
||||
'content' => '<ul>' .
|
||||
'<li>' . __( 'Relevanssi Premium offers limited support for Boolean logic. In addition of setting the default operator from Relevanssi settings, you can use AND and NOT operators in searches.', 'relevanssi' ) . '</li>' .
|
||||
'<li>' . __( 'To use the NOT operator, prefix the search term with a minus sign:', 'relevanssi' ) .
|
||||
sprintf( '<pre>%s</pre>', __( 'cats -dogs', 'relevanssi' ) ) .
|
||||
__( "This would only show posts that have the word 'cats' but not the word 'dogs'.", 'relevanssi' ) . '</li>' .
|
||||
'<li>' . __( 'To use the AND operator, set the default operator to OR and prefix the search term with a plus sign:', 'relevanssi' ) .
|
||||
sprintf( '<pre>%s</pre>', __( '+cats dogs mice', 'relevanssi' ) ) .
|
||||
__( "This would show posts that have the word 'cats' and either 'dogs' or 'mice' or both, and would prioritize posts that have all three.", 'relevanssi' ) . '</li>' .
|
||||
'</ul>',
|
||||
)
|
||||
);
|
||||
|
||||
/* Translators: first placeholder is the_permalink(), the second is relevanssi_the_permalink() */
|
||||
$permalinks_to_users = sprintf( esc_html__( "Permalinks to user profiles may not always work on search results templates. %1\$s should work, but if it doesn't, you can replace it with %2\$s.", 'relevanssi' ), '<code>the_permalink()</code>', '<code>relevanssi_the_permalink()</code>' );
|
||||
/* Translators: the placeholder is the name of the relevanssi_index_user_fields option */
|
||||
$index_user_fields = sprintf( esc_html__( 'To control which user meta fields are indexed, you can use the %s option. It should have a comma-separated list of user meta fields. It can be set like this (you only need to run this code once):', 'relevanssi' ), '<code>relevanssi_index_user_fields</code>' );
|
||||
/* Translators: the first placeholder opens the link, the second closes the link */
|
||||
$knowledge_base = sprintf( esc_html__( 'For more details on user profiles and search results templates, see %1$sthis knowledge base entry%2$s.', 'relevanssi' ), "<a href='https://www.relevanssi.com/knowledge-base/user-profile-search/'>", '</a>' );
|
||||
|
||||
$screen->add_help_tab(
|
||||
array(
|
||||
'id' => 'relevanssi-title-user-profiles',
|
||||
'title' => __( 'User profiles', 'relevanssi' ),
|
||||
'content' => '<ul>' .
|
||||
"<li>$permalinks_to_users</li>" .
|
||||
"<li>$index_user_fields" .
|
||||
"<pre>update_option( 'relevanssi_index_user_fields', 'field_a,field_b,field_c' );</pre></li>" .
|
||||
"<li>$knowledge_base</li>" .
|
||||
'</ul>',
|
||||
)
|
||||
);
|
||||
$screen->add_help_tab(
|
||||
array(
|
||||
'id' => 'relevanssi-internal-links',
|
||||
'title' => __( 'Internal links', 'relevanssi' ),
|
||||
'content' => '<ul>' .
|
||||
'<li>' . __( 'This option sets how Relevanssi handles internal links that point to your own site.', 'relevanssi' ) . '</li>' .
|
||||
'<li>' . __( "If you choose 'No special processing', Relevanssi doesn’t care about links and indexes the link anchor (the text of the link) like it is any other text.", 'relevanssi' ) . '</li>' .
|
||||
'<li>' . __( "If you choose 'Index internal links for target documents only', then the link is indexed like the link anchor text were the part of the link target, not the post where the link is.", 'relevanssi' ) . '</li>' .
|
||||
'<li>' . __( "If you choose 'Index internal links for target and source', the link anchor text will count for both posts.", 'relevanssi' ) . '</li>' .
|
||||
'</ul>',
|
||||
)
|
||||
);
|
||||
$screen->add_help_tab(
|
||||
array(
|
||||
'id' => 'relevanssi-stemming',
|
||||
'title' => __( 'Stemming', 'relevanssi' ),
|
||||
'content' => '<ul>' .
|
||||
'<li>' . __( "By default Relevanssi doesn't understand anything about singular word forms, plurals or anything else. You can, however, add a stemmer that will stem all the words to their basic form, making all different forms equal in searching.", 'relevanssi' ) . '</li>' .
|
||||
'<li>' . __( 'To enable the English-language stemmer, add this to the theme functions.php:', 'relevanssi' ) .
|
||||
"<pre>add_filter( 'relevanssi_stemmer', 'relevanssi_simple_english_stemmer' );</pre>" . '</li>' .
|
||||
'<li>' . __( 'After you add the code, rebuild the index to get correct results.', 'relevanssi' ) . '</li>' .
|
||||
'</ul>',
|
||||
)
|
||||
);
|
||||
|
||||
/* Translators: the placeholder has the WP CLI command */
|
||||
$wp_cli_command = sprintf( esc_html__( 'If you have WP CLI installed, Relevanssi Premium has some helpful commands. Use %s to get a list of available commands.', 'relevanssi' ), '<code>wp help relevanssi</code>' );
|
||||
/* Translators: the first placeholder opens the link, the second closes the link */
|
||||
$wp_cli_manual = sprintf( esc_html__( 'You can also see %1$sthe user manual page%2$s.', 'relevanssi' ), "<a href='https://www.relevanssi.com/user-manual/wp-cli/'>", '</a>' );
|
||||
|
||||
$screen->add_help_tab(
|
||||
array(
|
||||
'id' => 'relevanssi-wpcli',
|
||||
'title' => __( 'WP CLI', 'relevanssi' ),
|
||||
'content' => "<ul>
|
||||
<li>$wp_cli_command</li>
|
||||
<li>$wp_cli_manual</li>
|
||||
</ul>",
|
||||
)
|
||||
);
|
||||
|
||||
$screen->set_help_sidebar(
|
||||
'<p><strong>' . __( 'For more information:', 'relevanssi' ) . '</strong></p>' .
|
||||
'<p><a href="http://www.relevanssi.com/support/" target="_blank">' . __( 'Plugin support page', 'relevanssi' ) . '</a></p>' .
|
||||
'<p><a href="http://wordpress.org/tags/relevanssi?forum_id=10" target="_blank">' . __( 'WordPress.org forum', 'relevanssi' ) . '</a></p>' .
|
||||
'<p><a href="mailto:support@relevanssi.zendesk.com">Support email</a></p>' .
|
||||
'<p><a href="http://www.relevanssi.com/knowledge-base/" target="_blank">' . __( 'Plugin knowledge base', 'relevanssi' ) . '</a></p>'
|
||||
);
|
||||
}
|
||||
@@ -1,217 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* /premium/excerpts-highlights.php
|
||||
*
|
||||
* @package Relevanssi_Premium
|
||||
* @author Mikko Saari
|
||||
* @license https://wordpress.org/about/gpl/ GNU General Public License
|
||||
* @see https://www.relevanssi.com/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Extracts multiple excerpts from the full text.
|
||||
*
|
||||
* Finds all the parts of the full text where the terms appear. The function
|
||||
* splits the content by spaces and takes slices of the content, counts the
|
||||
* terms in the content and if the count is > 0, adds the excerpt to the list
|
||||
* of excerpts. To avoid overlapping excerpts, similarity is calculated against
|
||||
* other excerpts and only those excerpts with a similarity percentage of less
|
||||
* than 50 are accepted.
|
||||
*
|
||||
* @param array $terms An array of relevant words.
|
||||
* @param string $content The source text.
|
||||
* @param int $excerpt_length The length of the excerpt, default 30 words.
|
||||
*
|
||||
* @return array An array of excerpts. In each excerpt, there are following
|
||||
* parts: 'text' has the excerpt text, 'hits' the number of keyword matches in
|
||||
* the excerpt, 'start' is true if the excerpt is from the beginning of the
|
||||
* content.
|
||||
*/
|
||||
function relevanssi_extract_multiple_excerpts( $terms, $content, $excerpt_length = 30 ) {
|
||||
if ( $excerpt_length < 1 ) {
|
||||
return array( '', 0, false );
|
||||
}
|
||||
|
||||
$words = array_filter( explode( ' ', $content ) );
|
||||
$offset = 0;
|
||||
$tries = 0;
|
||||
$count_words = count( $words );
|
||||
$start = false;
|
||||
$gap = 0;
|
||||
|
||||
$excerpts = array();
|
||||
|
||||
$excerpt_candidates = $count_words / $excerpt_length;
|
||||
if ( $excerpt_candidates > 200 ) {
|
||||
/**
|
||||
* Adjusts the gap between excerpt candidates.
|
||||
*
|
||||
* The default value for the gap is number of words / 200 minus the
|
||||
* excerpt length, which means Relevanssi tries to create 200 excerpts.
|
||||
*
|
||||
* @param int The gap between excerpt candidates.
|
||||
* @param int $count_words The number of words in the content.
|
||||
* @param int $excerpt_length The length of the excerpt.
|
||||
*/
|
||||
$gap = apply_filters(
|
||||
'relevanssi_excerpt_gap',
|
||||
floor( $count_words / 200 - $excerpt_length ),
|
||||
$count_words,
|
||||
$excerpt_length
|
||||
);
|
||||
}
|
||||
|
||||
while ( $offset < $count_words ) {
|
||||
if ( $offset + $excerpt_length > $count_words ) {
|
||||
$offset = $count_words - $excerpt_length;
|
||||
if ( $offset < 0 ) {
|
||||
$offset = 0;
|
||||
}
|
||||
}
|
||||
$excerpt_slice = array_slice( $words, $offset, $excerpt_length );
|
||||
$excerpt_slice = ' ' . implode( ' ', $excerpt_slice );
|
||||
$count_matches = relevanssi_count_matches( $terms, $excerpt_slice );
|
||||
if ( $count_matches > 0 ) {
|
||||
if ( 0 === $offset ) {
|
||||
$start = true;
|
||||
} else {
|
||||
$start = false;
|
||||
}
|
||||
|
||||
$similarity = 0;
|
||||
array_walk(
|
||||
$excerpts,
|
||||
function ( $item ) use ( &$similarity, $excerpt_slice ) {
|
||||
similar_text( $item['text'], $excerpt_slice, $percentage );
|
||||
if ( $percentage > $similarity ) {
|
||||
$similarity = $percentage;
|
||||
}
|
||||
}
|
||||
);
|
||||
if ( $similarity < 50 ) {
|
||||
$excerpt = array(
|
||||
'hits' => $count_matches,
|
||||
'text' => trim( $excerpt_slice ),
|
||||
'start' => $start,
|
||||
);
|
||||
$excerpts[] = $excerpt;
|
||||
}
|
||||
}
|
||||
++$tries;
|
||||
|
||||
/**
|
||||
* Enables the excerpt optimization.
|
||||
*
|
||||
* If your posts are very long, building excerpts can be really slow.
|
||||
* To speed up the process, you can enable optimization, which means
|
||||
* Relevanssi only creates 50 excerpt candidates.
|
||||
*
|
||||
* @param boolean Return true to enable optimization, default false.
|
||||
*/
|
||||
if ( apply_filters( 'relevanssi_optimize_excerpts', false ) ) {
|
||||
if ( $tries > 50 ) {
|
||||
// An optimization trick: try only 50 times.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$offset += $excerpt_length + $gap;
|
||||
}
|
||||
|
||||
if ( empty( $excerpts ) && $gap > 0 ) {
|
||||
$result = relevanssi_get_first_match( $words, $terms, $excerpt_length );
|
||||
|
||||
if ( ! empty( $result['excerpt'] ) ) {
|
||||
$excerpts[] = array(
|
||||
'text' => $result['excerpt'],
|
||||
'hits' => $result['best_excerpt_term_hits'],
|
||||
'start' => $result['start'],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $excerpts ) ) {
|
||||
/**
|
||||
* Nothing found, take the beginning of the post. +2, because the first
|
||||
* index is an empty space and the last index is the rest of the post.
|
||||
*/
|
||||
$words = explode( ' ', $content, $excerpt_length + 2 );
|
||||
array_pop( $words );
|
||||
$text = implode( ' ', $words );
|
||||
$excerpt = array(
|
||||
'text' => $text,
|
||||
'hits' => 0,
|
||||
'start' => true,
|
||||
);
|
||||
$excerpts[] = $excerpt;
|
||||
}
|
||||
|
||||
return $excerpts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the "source" attribute to the excerpts in the array.
|
||||
*
|
||||
* @param array $excerpts The excerpts array, passed as a reference.
|
||||
* @param string $source The source value to add to the excerpts.
|
||||
*/
|
||||
function relevanssi_add_source_to_excerpts( &$excerpts, $source ) {
|
||||
if ( ! is_array( $excerpts ) ) {
|
||||
return;
|
||||
}
|
||||
array_walk(
|
||||
$excerpts,
|
||||
function ( &$item ) use ( $source ) {
|
||||
$item['source'] = $source;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines multiple arrays of excerpts together, sorts them and slices them.
|
||||
*
|
||||
* Returns a slice with the n excerpts with most term hits.
|
||||
*
|
||||
* @param int $post_id The current post ID.
|
||||
* @param array ...$excerpt_sources Arrays containing excerpts.
|
||||
*
|
||||
* @return array An array containing the n best excerpts.
|
||||
*/
|
||||
function relevanssi_combine_excerpts( $post_id, ...$excerpt_sources ) {
|
||||
$excerpts = array_merge( ...$excerpt_sources );
|
||||
usort(
|
||||
$excerpts,
|
||||
function ( $a, $b ) {
|
||||
return $b['hits'] - $a['hits'];
|
||||
}
|
||||
);
|
||||
$number_of_excerpts = get_option( 'relevanssi_max_excerpts', 1 );
|
||||
|
||||
$excerpts_with_hits = array_filter(
|
||||
$excerpts,
|
||||
function ( $excerpt ) {
|
||||
return $excerpt['hits'] > 0;
|
||||
}
|
||||
);
|
||||
|
||||
if ( count( $excerpts_with_hits ) > 0 ) {
|
||||
$excerpts = $excerpts_with_hits;
|
||||
}
|
||||
|
||||
$excerpts = array_slice(
|
||||
/**
|
||||
* Filters the excerpt.
|
||||
*
|
||||
* Filters the post excerpts generated by Relevanssi before the
|
||||
* highlighting is applied.
|
||||
*
|
||||
* @param array $excerpt An array of excerpts.
|
||||
* @param int $post->ID The post ID.
|
||||
*/
|
||||
apply_filters( 'relevanssi_excerpts', $excerpts, $post_id ),
|
||||
0,
|
||||
$number_of_excerpts
|
||||
);
|
||||
|
||||
return $excerpts;
|
||||
}
|
||||
@@ -1,412 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* /premium/gutenberg-sidebar.php
|
||||
*
|
||||
* The Gutenberg sidebar for Relevanssi Premium.
|
||||
*
|
||||
* @package Relevanssi_Premium
|
||||
* @author Mikko Saari
|
||||
* @license https://wordpress.org/about/gpl/ GNU General Public License
|
||||
* @see https://www.relevanssi.com/
|
||||
*/
|
||||
|
||||
add_action( 'init', 'relevanssi_register_gutenberg_meta' );
|
||||
add_action( 'enqueue_block_editor_assets', 'relevanssi_block_editor_assets' );
|
||||
add_action( 'rest_api_init', 'relevanssi_register_gutenberg_rest_routes' );
|
||||
add_filter( 'load_script_translation_file', 'relevanssi_rename_translation_file', 10, 2 );
|
||||
|
||||
/**
|
||||
* Registers the meta fields for the block editor.
|
||||
*
|
||||
* Attached to the 'init' custom hook, this function will register all the
|
||||
* necessary meta fields so that they are available in the block editor.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function relevanssi_register_gutenberg_meta() {
|
||||
$relevanssi_meta_fields = array(
|
||||
array(
|
||||
'meta_key' => '_relevanssi_hide_post',
|
||||
'description' => 'Hide this post',
|
||||
),
|
||||
array(
|
||||
'meta_key' => '_relevanssi_hide_content',
|
||||
'description' => 'Hide post content',
|
||||
),
|
||||
array(
|
||||
'meta_key' => '_relevanssi_pin_for_all',
|
||||
'description' => 'Pin for all searches',
|
||||
),
|
||||
array(
|
||||
'meta_key' => '_relevanssi_pin_keywords',
|
||||
'description' => 'Pin for these keywords',
|
||||
),
|
||||
array(
|
||||
'meta_key' => '_relevanssi_unpin_keywords',
|
||||
'description' => 'Block for these keywords',
|
||||
),
|
||||
array(
|
||||
'meta_key' => '_relevanssi_related_keywords',
|
||||
'description' => 'Keywords for related posts searches',
|
||||
),
|
||||
array(
|
||||
'meta_key' => '_relevanssi_related_include_ids',
|
||||
'description' => 'Post IDs for included related posts',
|
||||
),
|
||||
array(
|
||||
'meta_key' => '_relevanssi_related_exclude_ids',
|
||||
'description' => 'Post IDs for excluded related posts',
|
||||
),
|
||||
array(
|
||||
'meta_key' => '_relevanssi_related_no_append',
|
||||
'description' => "Don't append related posts to this post",
|
||||
),
|
||||
array(
|
||||
'meta_key' => '_relevanssi_related_not_related',
|
||||
'description' => 'Disable related posts for this post',
|
||||
),
|
||||
array(
|
||||
'meta_key' => '_relevanssi_related_posts',
|
||||
'description' => 'Related posts for this post',
|
||||
),
|
||||
array(
|
||||
'meta_key' => '_relevanssi_noindex_reason',
|
||||
'description' => 'Reason this post is not indexed',
|
||||
),
|
||||
);
|
||||
|
||||
foreach ( $relevanssi_meta_fields as $meta_field ) {
|
||||
register_meta(
|
||||
'post',
|
||||
$meta_field['meta_key'],
|
||||
array(
|
||||
'type' => 'string',
|
||||
'description' => $meta_field['description'],
|
||||
'single' => true,
|
||||
'show_in_rest' => true,
|
||||
'auth_callback' => '__return_true',
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the Gutenberg sidebar script.
|
||||
*
|
||||
* Registers the Gutenberg sidebar script, exact version depending on whether
|
||||
* the RELEVANSSI_DEVELOP constant is set or not, includes the dependencies and
|
||||
* the translations.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function relevanssi_register_gutenberg_script() {
|
||||
global $relevanssi_variables;
|
||||
|
||||
if ( ! function_exists( 'wp_set_script_translations' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
global $post;
|
||||
if ( ! $post ) {
|
||||
return;
|
||||
}
|
||||
if ( $post && ! post_type_supports( $post->post_type, 'custom-fields' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! current_user_can(
|
||||
/**
|
||||
* Filters the capability required to access the Relevanssi sidebar.
|
||||
*
|
||||
* @param string The capability required, default 'edit_others_posts'.
|
||||
*/
|
||||
apply_filters( 'relevanssi_sidebar_capability', $relevanssi_variables['sidebar_capability'] )
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$file_location = 'premium/gutenberg-sidebar/';
|
||||
if ( RELEVANSSI_DEVELOP ) {
|
||||
$file_location = 'build/';
|
||||
}
|
||||
wp_register_script(
|
||||
'relevanssi-sidebar',
|
||||
plugin_dir_url( $relevanssi_variables['plugin_basename'] ) . $file_location . 'index.js',
|
||||
array( 'wp-api-fetch', 'wp-i18n', 'wp-blocks', 'wp-edit-post', 'wp-element', 'wp-editor', 'wp-components', 'wp-data', 'wp-plugins', 'wp-edit-post' ),
|
||||
1,
|
||||
true
|
||||
);
|
||||
wp_set_script_translations( 'relevanssi-sidebar', 'relevanssi', WP_CONTENT_DIR . '/languages/plugins' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues the Gutenberg sidebar script.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function relevanssi_block_editor_assets() {
|
||||
relevanssi_register_gutenberg_script();
|
||||
wp_enqueue_script( 'relevanssi-sidebar' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a REST API endpoint for "How Relevanssi sees this post".
|
||||
*
|
||||
* Takes in a post ID and returns the "How Relevanssi sees this post" data for
|
||||
* that post.
|
||||
*
|
||||
* @param array $data The post ID in $data['id'].
|
||||
*
|
||||
* @return array The indexed terms for various parts of the post in an
|
||||
* associative array.
|
||||
*
|
||||
* @uses relevanssi_fetch_sees_data()
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function relevanssi_sees_post_endpoint( $data ) {
|
||||
return relevanssi_fetch_sees_data( $data['id'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a REST API endpoint for listing the related posts.
|
||||
*
|
||||
* @param array $data The post ID in $data['id'].
|
||||
*
|
||||
* @return array The related posts in an array format (id, URL and title).
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function relevanssi_list_related_posts_endpoint( $data ) {
|
||||
return relevanssi_generate_related_list( $data['id'], 'ARRAY' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a REST API endpoint for listing the excluded related posts.
|
||||
*
|
||||
* @param array $data The post ID in $data['id'].
|
||||
*
|
||||
* @return array The excluded posts in an array format (id, URL and title).
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function relevanssi_list_excluded_posts_endpoint( $data ) {
|
||||
return relevanssi_generate_excluded_list( $data['id'], 'ARRAY' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a REST API endpoint for excluding a post from related posts.
|
||||
*
|
||||
* @param array $data The post ID in $data['post_id'], the ID of the post to
|
||||
* exclude in $data['exclude'].
|
||||
*
|
||||
* @return array The excluded posts in an array format (id, URL and title).
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function relevanssi_exclude_related_post_endpoint( $data ) {
|
||||
relevanssi_exclude_a_related_post( $data['post_id'], $data['exclude'] );
|
||||
return relevanssi_generate_excluded_list( $data['post_id'], 'ARRAY' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a REST API endpoint for unexcluding a post from related posts.
|
||||
*
|
||||
* @param array $data The post ID in $data['post_id'], the ID of the post to
|
||||
* return in $data['return'].
|
||||
*
|
||||
* @return array The excluded posts in an array format (id, URL and title).
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function relevanssi_unexclude_related_post_endpoint( $data ) {
|
||||
relevanssi_unexclude_a_related_post( $data['post_id'], $data['return'] );
|
||||
return relevanssi_generate_excluded_list( $data['post_id'], 'ARRAY' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a REST API endpoint for regenerating the related posts list.
|
||||
*
|
||||
* This is triggered when either the keywords or the post ID list for the
|
||||
* related posts is changed. This will get the key and the value of the changed
|
||||
* meta field as a parameter and will either empty or update the meta field and
|
||||
* then trigger related posts list regeneration.
|
||||
*
|
||||
* @param array $data The post ID in $data['id'], the meta key name in
|
||||
* $data['meta_key'] and the new value in $data['meta_value'].
|
||||
*
|
||||
* @return array The related posts in an array format (id, URL and title).
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function relevanssi_regenerate_related_endpoint( $data ) {
|
||||
if ( 0 === $data['meta_value'] ) {
|
||||
delete_post_meta( $data['id'], $data['meta_key'] );
|
||||
} else {
|
||||
update_post_meta( $data['id'], $data['meta_key'], $data['meta_value'] );
|
||||
}
|
||||
delete_post_meta( $data['id'], '_relevanssi_related_posts' );
|
||||
return relevanssi_generate_related_list( $data['id'], 'ARRAY' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a REST API endpoint for listing common search terms.
|
||||
*
|
||||
* @param array $data The post ID in $data['id'].
|
||||
*
|
||||
* @return array The common terms in an array format (id, query, and count).
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function relevanssi_list_insights_common_terms( $data ) {
|
||||
return relevanssi_generate_tracking_insights_most_common( $data['id'], 'ARRAY' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a REST API endpoint for listing low-ranking search terms.
|
||||
*
|
||||
* @param array $data The post ID in $data['id'].
|
||||
*
|
||||
* @return array The terms in an array format (id, query, rank).
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function relevanssi_list_insights_low_ranking_terms( $data ) {
|
||||
return relevanssi_generate_tracking_insights_low_ranking( $data['id'], 'ARRAY' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the REST API endpoints.
|
||||
*
|
||||
* @see register_rest_route()
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function relevanssi_register_gutenberg_rest_routes() {
|
||||
$routes = array(
|
||||
array(
|
||||
'path' => '/excluderelatedpost/(?P<exclude>\d+)/(?P<post_id>\d+)',
|
||||
'callback' => 'relevanssi_exclude_related_post_endpoint',
|
||||
'args' => array(
|
||||
'exclude' => 'numeric',
|
||||
'post_id' => 'numeric',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'path' => '/unexcluderelatedpost/(?P<return>\d+)/(?P<post_id>\d+)',
|
||||
'callback' => 'relevanssi_unexclude_related_post_endpoint',
|
||||
'args' => array(
|
||||
'return' => 'numeric',
|
||||
'post_id' => 'numeric',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'path' => '/listexcluded/(?P<id>\d+)',
|
||||
'callback' => 'relevanssi_list_excluded_posts_endpoint',
|
||||
'args' => array(
|
||||
'id' => 'numeric',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'path' => '/listrelated/(?P<id>\d+)',
|
||||
'callback' => 'relevanssi_list_related_posts_endpoint',
|
||||
'args' => array(
|
||||
'id' => 'numeric',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'path' => '/sees/(?P<id>\d+)',
|
||||
'callback' => 'relevanssi_sees_post_endpoint',
|
||||
'args' => array(
|
||||
'id' => 'numeric',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'path' => '/regeneraterelatedposts/(?P<id>\d+)/(?P<meta_key>\w+)/(?P<meta_value>[^/]+)',
|
||||
'callback' => 'relevanssi_regenerate_related_endpoint',
|
||||
'args' => array(
|
||||
'id' => 'numeric',
|
||||
'meta_key' => 'metakey',
|
||||
'meta_value' => 'urldecode',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'path' => '/listinsightscommon/(?P<id>\d+)',
|
||||
'callback' => 'relevanssi_list_insights_common_terms',
|
||||
'args' => array(
|
||||
'id' => 'numeric',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'path' => '/listinsightslowranking/(?P<id>\d+)',
|
||||
'callback' => 'relevanssi_list_insights_low_ranking_terms',
|
||||
'args' => array(
|
||||
'id' => 'numeric',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
foreach ( $routes as $route ) {
|
||||
$args = array();
|
||||
foreach ( $route['args'] as $name => $type ) {
|
||||
switch ( $type ) {
|
||||
case 'metakey':
|
||||
$args[ $name ] = array(
|
||||
'validate_callback' => function ( $param ) {
|
||||
return in_array( $param, array( '_relevanssi_related_keywords', '_relevanssi_related_include_ids' ), true );
|
||||
},
|
||||
);
|
||||
break;
|
||||
case 'urldecode':
|
||||
$args[ $name ] = array(
|
||||
'sanitize_callback' => function ( $param ) {
|
||||
return urldecode( $param );
|
||||
},
|
||||
);
|
||||
break;
|
||||
case 'numeric':
|
||||
default:
|
||||
$args[ $name ] = array(
|
||||
'validate_callback' => function ( $param ) {
|
||||
return is_numeric( $param );
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
register_rest_route(
|
||||
'relevanssi/v1',
|
||||
$route['path'],
|
||||
array(
|
||||
'methods' => 'GET',
|
||||
'callback' => $route['callback'],
|
||||
'args' => $args,
|
||||
'permission_callback' => function () {
|
||||
global $relevanssi_variables;
|
||||
// Filter documented in /premium/gutenberg-sidebar.php.
|
||||
return current_user_can( apply_filters( 'relevanssi_sidebar_capability', $relevanssi_variables['sidebar_capability'] ) );
|
||||
},
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename the Relevanssi Gutenberg sidebar translation file.
|
||||
*
|
||||
* WordPress assumes the file name is relevanssi-LOCALE-relevanssi-sidebar.json,
|
||||
* but the file from TranslationsPress is relevanssi-LOCALE.json. We rename the
|
||||
* file WP is looking for here.
|
||||
*
|
||||
* @param string $file The original file name.
|
||||
* @param string $handle The script handle.
|
||||
*
|
||||
* @return string The corrected filename.
|
||||
*/
|
||||
function relevanssi_rename_translation_file( $file, $handle ) {
|
||||
if ( 'relevanssi-sidebar' !== $handle ) {
|
||||
return $file;
|
||||
}
|
||||
return str_replace( '-relevanssi-sidebar', '', $file );
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
<?php return array('dependencies' => array('wp-components', 'wp-compose', 'wp-data', 'wp-edit-post', 'wp-element', 'wp-i18n', 'wp-plugins', 'wp-polyfill'), 'version' => 'b81b50e9375d8f85569a43863b885812');
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,11 +0,0 @@
|
||||
button.removepost, button.returnpost {
|
||||
border: none;
|
||||
text-decoration: underline;
|
||||
padding: 0px;
|
||||
color: #c92c2c;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button.returnpost {
|
||||
color: #28c62b;
|
||||
}
|
||||
@@ -1,186 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* /premium/network-options.php
|
||||
*
|
||||
* Relevanssi Premium network options menu.
|
||||
*
|
||||
* @package Relevanssi_Premium
|
||||
* @author Mikko Saari
|
||||
* @license https://wordpress.org/about/gpl/ GNU General Public License
|
||||
* @see https://www.relevanssi.com/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adds the network level menu for Relevanssi Premium.
|
||||
*
|
||||
* @global array $relevanssi_variables The Relevanssi variables array, used for the plugin file name.
|
||||
*/
|
||||
function relevanssi_network_menu() {
|
||||
global $relevanssi_variables;
|
||||
RELEVANSSI_PREMIUM ? $name = 'Relevanssi Premium' : $name = 'Relevanssi';
|
||||
add_menu_page(
|
||||
$name,
|
||||
$name,
|
||||
/**
|
||||
* Capability required to see the Relevanssi network options.
|
||||
*
|
||||
* The capability level required to see the Relevanssi Premium network options.
|
||||
*
|
||||
* @since Unknown
|
||||
*
|
||||
* @param string $capability The capability required. Default 'manage_options'.
|
||||
*/
|
||||
apply_filters( 'relevanssi_options_capability', 'manage_options' ),
|
||||
$relevanssi_variables['file'],
|
||||
'relevanssi_network_options'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints out the Relevanssi Premium network options.
|
||||
*
|
||||
* @global array $relevanssi_variables The Relevanssi variables array, used for the plugin file name.
|
||||
*/
|
||||
function relevanssi_network_options() {
|
||||
global $relevanssi_variables;
|
||||
|
||||
printf( '<div class="wrap"><h2>%s</h2>', esc_html__( 'Relevanssi network options', 'relevanssi' ) );
|
||||
|
||||
if ( ! empty( $_POST ) ) { // WPCS: Input var okay.
|
||||
if ( isset( $_REQUEST['submit'] ) ) { // WPCS: Input var okay.
|
||||
check_admin_referer( plugin_basename( $relevanssi_variables['file'] ), 'relevanssi_network_options' );
|
||||
relevanssi_update_network_options();
|
||||
}
|
||||
if ( isset( $_REQUEST['copytoall'] ) ) { // WPCS: Input var okay.
|
||||
check_admin_referer( plugin_basename( $relevanssi_variables['file'] ), 'relevanssi_network_options' );
|
||||
relevanssi_copy_options_to_subsites( $_REQUEST ); // WPCS: Input var okay.
|
||||
}
|
||||
}
|
||||
|
||||
$this_page = '?page=relevanssi/relevanssi.php';
|
||||
if ( RELEVANSSI_PREMIUM ) {
|
||||
$this_page = '?page=relevanssi-premium/relevanssi.php';
|
||||
}
|
||||
|
||||
printf( "<form method='post' action='admin.php%s'>", esc_attr( $this_page ) );
|
||||
|
||||
wp_nonce_field( plugin_basename( $relevanssi_variables['file'] ), 'relevanssi_network_options' );
|
||||
|
||||
?>
|
||||
<table class="form-table">
|
||||
<?php
|
||||
relevanssi_form_api_key( 'network' );
|
||||
?>
|
||||
</table>
|
||||
<input type='submit' name='submit' value='<?php esc_attr_e( 'Save the options', 'relevanssi' ); ?>' class='button button-primary' />
|
||||
</form>
|
||||
|
||||
<h2><?php esc_html_e( 'Copy options from one site to other sites', 'relevanssi' ); ?></h2>
|
||||
<p><?php esc_html_e( "Choose a blog and copy all the options from that blog to all other blogs that have active Relevanssi Premium. Be careful! There's no way to undo the procedure!", 'relevanssi' ); ?></p>
|
||||
|
||||
<form id='copy_config' method='post' action='admin.php?page=relevanssi-premium/relevanssi.php'>
|
||||
<?php wp_nonce_field( plugin_basename( $relevanssi_variables['file'] ), 'relevanssi_network_options' ); ?>
|
||||
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Copy options', 'relevanssi' ); ?></th>
|
||||
<td>
|
||||
<?php
|
||||
|
||||
$raw_blog_list = get_sites( array( 'number' => 2000 ) );
|
||||
$blog_list = array();
|
||||
foreach ( $raw_blog_list as $blog ) {
|
||||
$details = get_blog_details( $blog->blog_id );
|
||||
$blog_list[ $details->blogname ] = $blog->blog_id;
|
||||
}
|
||||
ksort( $blog_list );
|
||||
echo "<select id='sourceblog' name='sourceblog'>";
|
||||
foreach ( $blog_list as $name => $id ) {
|
||||
echo "<option value='" . esc_attr( $id ) . "'>" . esc_html( $name ) . '</option>';
|
||||
}
|
||||
echo '</select>';
|
||||
|
||||
?>
|
||||
<input type='submit' name='copytoall' value='<?php esc_attr_e( 'Copy options to all other subsites', 'relevanssi' ); ?>' class='button button-primary' />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the network options.
|
||||
*
|
||||
* @global array $relevanssi_variables Relevanssi global variables, used to check the plugin file name.
|
||||
*
|
||||
* Saves the Relevanssi Premium network options.
|
||||
*/
|
||||
function relevanssi_update_network_options() {
|
||||
global $relevanssi_variables;
|
||||
|
||||
if ( empty( $_REQUEST['relevanssi_api_key'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
unset( $_REQUEST['relevanssi_api_key'] ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
}
|
||||
|
||||
if ( isset( $_REQUEST['relevanssi_remove_api_key'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
update_site_option( 'relevanssi_api_key', '' );
|
||||
}
|
||||
if ( isset( $_REQUEST['relevanssi_api_key'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$value = sanitize_text_field( wp_unslash( $_REQUEST['relevanssi_api_key'] ) ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
update_site_option( 'relevanssi_api_key', $value );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies options from one subsite to other subsites.
|
||||
*
|
||||
* @global $wpdb The WordPress database interface.
|
||||
*
|
||||
* @param array $data Copy parameters.
|
||||
*/
|
||||
function relevanssi_copy_options_to_subsites( $data ) {
|
||||
if ( ! isset( $data['sourceblog'] ) ) {
|
||||
return;
|
||||
}
|
||||
$sourceblog = $data['sourceblog'];
|
||||
if ( ! is_numeric( $sourceblog ) ) {
|
||||
return;
|
||||
}
|
||||
$sourceblog = esc_sql( $sourceblog );
|
||||
|
||||
/* translators: %s has the source blog ID */
|
||||
printf( '<h2>' . esc_html__( 'Copying options from blog %s', 'relevanssi' ) . '</h2>', esc_html( $sourceblog ) );
|
||||
global $wpdb;
|
||||
switch_to_blog( $sourceblog );
|
||||
$q = "SELECT * FROM $wpdb->options WHERE option_name LIKE 'relevanssi%'";
|
||||
restore_current_blog();
|
||||
|
||||
$results = $wpdb->get_results( $q ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared
|
||||
|
||||
$blog_list = get_sites( array( 'number' => 2000 ) );
|
||||
foreach ( $blog_list as $blog ) {
|
||||
if ( $blog->blog_id === $sourceblog ) {
|
||||
continue;
|
||||
}
|
||||
switch_to_blog( $blog->blog_id );
|
||||
|
||||
/* translators: %s is the blog ID */
|
||||
printf( '<p>' . esc_html__( 'Processing blog %s:', 'relevanssi' ) . '<br />', esc_html( $blog->blog_id ) );
|
||||
if ( ! is_plugin_active( 'relevanssi-premium/relevanssi.php' ) ) {
|
||||
echo esc_html__( 'Relevanssi is not active in this blog.', 'relevanssi' ) . '</p>';
|
||||
continue;
|
||||
}
|
||||
foreach ( $results as $option ) {
|
||||
if ( is_serialized( $option->option_value ) ) {
|
||||
$value = unserialize( $option->option_value ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions
|
||||
} else {
|
||||
$value = $option->option_value;
|
||||
}
|
||||
update_option( $option->option_name, $value );
|
||||
}
|
||||
echo esc_html__( 'Options updated.', 'relevanssi' ) . '</p>';
|
||||
restore_current_blog();
|
||||
}
|
||||
}
|
||||
@@ -1,920 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* /premium/pdf-upload.php
|
||||
*
|
||||
* @package Relevanssi_Premium
|
||||
* @author Mikko Saari
|
||||
* @license https://wordpress.org/about/gpl/ GNU General Public License
|
||||
* @see https://www.relevanssi.com/
|
||||
*/
|
||||
|
||||
add_action( 'add_attachment', 'relevanssi_read_attachment', 10 );
|
||||
add_action( 'add_meta_boxes_attachment', 'relevanssi_add_pdf_metaboxes' );
|
||||
add_filter( 'relevanssi_hits_to_show', 'relevanssi_prime_pdf_content', 10, 2 );
|
||||
add_filter( 'relevanssi_index_custom_fields', 'relevanssi_add_pdf_customfield' );
|
||||
add_filter( 'relevanssi_pre_excerpt_content', 'relevanssi_add_pdf_content_to_excerpt', 10, 2 );
|
||||
add_filter( 'wp_media_attach_action', 'relevanssi_media_attach_action', 10, 3 );
|
||||
|
||||
define( 'RELEVANSSI_ERROR_01', 'R_ERR01: ' . __( 'Post excluded from the index by the user.', 'relevanssi' ) );
|
||||
define( 'RELEVANSSI_ERROR_02', 'R_ERR02: ' . __( 'Relevanssi is in privacy mode and not allowed to contact Relevanssiservices.com.', 'relevanssi' ) );
|
||||
define( 'RELEVANSSI_ERROR_03', 'R_ERR03: ' . __( 'Attachment MIME type blocked.', 'relevanssi' ) );
|
||||
define( 'RELEVANSSI_ERROR_04', 'R_ERR04: ' . __( 'Attachment file size is too large.', 'relevanssi' ) );
|
||||
define( 'RELEVANSSI_ERROR_05', 'R_ERR05: ' . __( 'Attachment reading in process, please try again later.', 'relevanssi' ) );
|
||||
define( 'RELEVANSSI_ERROR_06', 'R_ERR06: ' . __( 'Server did not respond.', 'relevanssi' ) );
|
||||
|
||||
/**
|
||||
* Reads the attachment content when an attachment is saved.
|
||||
*
|
||||
* Uses relevanssi_index_pdf() to read in the attachment content whenever an
|
||||
* attachment is saved. Works on the 'add_attachment' filter hook.
|
||||
*
|
||||
* @param int $post_id The post ID for the attachment.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function relevanssi_read_attachment( $post_id ) {
|
||||
$post_status = get_post_status( $post_id );
|
||||
if ( 'auto-draft' === $post_status ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( 'on' !== get_option( 'relevanssi_read_new_files' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$mime_type = get_post_mime_type( $post_id );
|
||||
$read_this = relevanssi_mime_type_ok( $mime_type );
|
||||
if ( $read_this ) {
|
||||
relevanssi_launch_ajax_action(
|
||||
'relevanssi_index_pdf',
|
||||
array( 'post_id' => $post_id )
|
||||
);
|
||||
// Remove the usual relevanssi_publish action because
|
||||
// relevanssi_index_pdf() already indexes the post.
|
||||
remove_action( 'add_attachment', 'relevanssi_publish', 12 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the MIME type of the attachment to determine if it's allowed or not.
|
||||
*
|
||||
* By default this function blocks all images, all video, and zip files.
|
||||
*
|
||||
* @param string $mime_type The attachment MIME type.
|
||||
*
|
||||
* @return boolean True, if ok to read the attachment, false if not.
|
||||
*/
|
||||
function relevanssi_mime_type_ok( $mime_type ) {
|
||||
$read_this = true;
|
||||
$mime_parts = explode( '/', $mime_type );
|
||||
if ( in_array( $mime_parts[0], array( 'image', 'video' ), true ) ) {
|
||||
$read_this = false;
|
||||
}
|
||||
if ( isset( $mime_parts[1] ) && in_array( $mime_parts[1], array( 'zip', 'octet-stream', 'x-zip-compressed', 'x-zip' ), true ) ) {
|
||||
$read_this = false;
|
||||
}
|
||||
/**
|
||||
* Allows the filtering of attachment reading based on MIME type.
|
||||
*
|
||||
* @param boolean $read_this True, if ok to read the attachment, false if not.
|
||||
* @param string $mime_type The attachment MIME type.
|
||||
*
|
||||
* @return boolean True, if ok to read the attachment, false if not.
|
||||
*/
|
||||
$read_this = apply_filters( 'relevanssi_accept_mime_type', $read_this, $mime_type );
|
||||
return $read_this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Includes the PDF content custom field in the list of custom fields.
|
||||
*
|
||||
* This function works on 'relevanssi_index_custom_fields' filter and makes sure the
|
||||
* '_relevanssi_pdf_content' custom field is included.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param array $custom_fields The custom fields array.
|
||||
*
|
||||
* @return array $custom_fields The custom fields array.
|
||||
*/
|
||||
function relevanssi_add_pdf_customfield( $custom_fields ) {
|
||||
if ( ! is_array( $custom_fields ) ) {
|
||||
$custom_fields = array();
|
||||
}
|
||||
if ( ! in_array( '_relevanssi_pdf_content', $custom_fields, true ) ) {
|
||||
$custom_fields[] = '_relevanssi_pdf_content';
|
||||
}
|
||||
return $custom_fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads in all _relevanssi_pdf_content for found posts to avoid database calls.
|
||||
*
|
||||
* @global array An array of the PDF content.
|
||||
*
|
||||
* @param array $hits An array of posts found.
|
||||
* @param WP_Query $query The WP_Query object.
|
||||
*
|
||||
* @return array The posts found, untouched.
|
||||
*/
|
||||
function relevanssi_prime_pdf_content( $hits, $query ) {
|
||||
global $relevanssi_pdf_content;
|
||||
|
||||
if ( ! isset( $query->query_vars['fields'] ) || empty( $query->query_vars['fields'] ) ) {
|
||||
$relevanssi_pdf_content = relevanssi_get_post_meta_for_all_posts(
|
||||
wp_list_pluck( $hits, 'ID' ),
|
||||
'_relevanssi_pdf_content'
|
||||
);
|
||||
}
|
||||
|
||||
return $hits;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Includes the PDF content custom field for excerpt-building.
|
||||
*
|
||||
* This function works on 'relevanssi_pre_excerpt_content' filter and makes sure
|
||||
* the '_relevanssi_pdf_content' custom field content is included when excerpts
|
||||
* are built.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @see relevanssi_prime_pdf_content
|
||||
*
|
||||
* @param string $content The post content.
|
||||
* @param object $post The post object.
|
||||
*
|
||||
* @return string $content The post content.
|
||||
*/
|
||||
function relevanssi_add_pdf_content_to_excerpt( $content, $post ) {
|
||||
global $relevanssi_pdf_content;
|
||||
$pdf_content = $relevanssi_pdf_content[ $post->ID ] ?? '';
|
||||
$content .= ' ' . $pdf_content;
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the PDF control metabox.
|
||||
*
|
||||
* Adds the PDF control metaboxes on post edit pages for posts in the
|
||||
* 'attachment' post type, with a MIME type that is not 'image/*' or
|
||||
* 'video/*'.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param object $post The post object.
|
||||
*/
|
||||
function relevanssi_add_pdf_metaboxes( $post ) {
|
||||
// Do not display on image pages.
|
||||
$mime_parts = explode( '/', $post->post_mime_type );
|
||||
if ( in_array( $mime_parts[0], array( 'image', 'video' ), true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_meta_box(
|
||||
'relevanssi_pdf_box',
|
||||
__( 'Relevanssi attachment controls', 'relevanssi' ),
|
||||
'relevanssi_attachment_metabox',
|
||||
$post->post_type
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints out the attachment control metabox.
|
||||
*
|
||||
* Prints out the attachment control metabox used for reading attachments and
|
||||
* examining the read attachment content.
|
||||
*
|
||||
* @global object $post The global post object.
|
||||
* @global array $relevanssi_variables The Relevanssi global variables array,
|
||||
* used to get the file name for nonce.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function relevanssi_attachment_metabox() {
|
||||
global $post, $relevanssi_variables;
|
||||
wp_nonce_field( plugin_basename( $relevanssi_variables['file'] ), 'relevanssi_pdfcontent' );
|
||||
|
||||
$pdf_modified = get_post_meta( $post->ID, '_relevanssi_pdf_modified', true );
|
||||
|
||||
/**
|
||||
* Filters the attachment URL.
|
||||
*
|
||||
* If you want to make Relevanssi index attached file content from
|
||||
* files that are stored outside the WP attachment system, use this
|
||||
* filter to provide the URL of the file.
|
||||
*
|
||||
* @param string The URL of the attached file.
|
||||
* @param int The post ID of the attachment post.
|
||||
*/
|
||||
$url = apply_filters(
|
||||
'relevanssi_get_attachment_url',
|
||||
wp_get_attachment_url( $post->ID ),
|
||||
$post->ID
|
||||
);
|
||||
$id = $post->ID;
|
||||
$button_text = $pdf_modified ? __( 'Reread the attachment content', 'relevanssi' ) : __( 'Read the attachment content', 'relevanssi' );
|
||||
$api_key = get_network_option( null, 'relevanssi_api_key' );
|
||||
$action = 'sendUrl';
|
||||
$explanation = __( 'Indexer will fetch the file from your server.', 'relevanssi' );
|
||||
if ( 'on' === get_option( 'relevanssi_send_pdf_files' ) ) {
|
||||
$action = 'sendPdf';
|
||||
$explanation = __( 'The file will be uploaded to the indexer.', 'relevanssi' );
|
||||
}
|
||||
|
||||
if ( ! $api_key ) {
|
||||
// get_network_option() falls back to get_option(), but if this is a single
|
||||
// install on a multisite, it won't work correctly.
|
||||
$api_key = get_option( 'relevanssi_api_key' );
|
||||
}
|
||||
|
||||
if ( ! $api_key ) {
|
||||
printf( '<p>%s</p>', esc_html__( 'No API key set. API key is required for attachment indexing.', 'relevanssi' ) );
|
||||
} else {
|
||||
printf(
|
||||
'<p><input type="button" id="%s" value="%s" class="button-primary button-large" data-api_key="%s" data-post_id="%d" data-url="%s" title="%s"/></p>',
|
||||
esc_attr( $action ),
|
||||
esc_attr( $button_text ),
|
||||
esc_attr( $api_key ),
|
||||
intval( $id ),
|
||||
esc_attr( $url ),
|
||||
esc_attr( $explanation )
|
||||
);
|
||||
|
||||
if ( $pdf_modified ) {
|
||||
esc_html_e( "The attachment content has been modified and won't be reread from the file when doing a general rereading. If you want to reread the attachment contents from the file, you can force rereading here.", 'relevanssi' );
|
||||
}
|
||||
|
||||
$pdf_content = get_post_meta( $post->ID, '_relevanssi_pdf_content', true );
|
||||
if ( $pdf_content ) {
|
||||
$pdf_content_title = __( 'Attachment content', 'relevanssi' );
|
||||
printf(
|
||||
'<h3><label for="relevanssi_pdf_content">%s</label></h3> <p><textarea id="relevanssi_pdf_content" name="relevanssi_pdf_content" cols="80" rows="4">%s</textarea></p>',
|
||||
esc_html( $pdf_content_title ),
|
||||
esc_html( $pdf_content )
|
||||
);
|
||||
}
|
||||
|
||||
$pdf_error = get_post_meta( $post->ID, '_relevanssi_pdf_error', true );
|
||||
if ( false !== strpos( $pdf_error, 'R_ERR05' ) ) {
|
||||
printf(
|
||||
'<h3>%s</h3>',
|
||||
esc_html__( 'Relevanssi is currently in process of reading the file contents, please return here later.', 'relevanssi' )
|
||||
);
|
||||
} elseif ( $pdf_error ) {
|
||||
$pdf_error_title = __( 'Attachment error message', 'relevanssi' );
|
||||
printf(
|
||||
'<h3><label for="relevanssi_pdf_error">%s</label></h3> <p><textarea id="relevanssi_pdf_error" cols="80" rows="4" readonly>%s</textarea></p>',
|
||||
esc_html( $pdf_error_title ),
|
||||
esc_html( $pdf_error )
|
||||
);
|
||||
}
|
||||
|
||||
if ( empty( $pdf_content ) && empty( $pdf_error ) ) {
|
||||
printf(
|
||||
'<p>%s</p>',
|
||||
esc_html__( 'No attachment content found for this post at the moment.', 'relevanssi' )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads in attachment content from a attachment file.
|
||||
*
|
||||
* Reads in the attachment content, either by sending an URL or the file itself to
|
||||
* the Relevanssi attachment reading service.
|
||||
*
|
||||
* @param int $post_id The attachment post ID.
|
||||
* @param boolean $ajax Is this in AJAX context? Default false.
|
||||
* @param string $send_file Should the file be sent ('on'), or just the URL ('off')?
|
||||
* Default null.
|
||||
*
|
||||
* @return array An array with two items: boolean 'success' and 'error'
|
||||
* containing the possible error message.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function relevanssi_index_pdf( $post_id, $ajax = false, $send_file = null ) {
|
||||
$hide_post = get_post_meta( $post_id, '_relevanssi_hide_post', true );
|
||||
/**
|
||||
* Filters whether the attachment should be read or not.
|
||||
*
|
||||
* @param boolean $hide_post True if the attachment shouldn't be read,
|
||||
* false if it should.
|
||||
* @param int $post_id The attachment post ID.
|
||||
*/
|
||||
$hide_post = apply_filters( 'relevanssi_do_not_read', $hide_post, $post_id );
|
||||
if ( $hide_post ) {
|
||||
delete_post_meta( $post_id, '_relevanssi_pdf_content' );
|
||||
update_post_meta( $post_id, '_relevanssi_pdf_error', RELEVANSSI_ERROR_01 );
|
||||
|
||||
$result = array(
|
||||
'success' => false,
|
||||
'error' => RELEVANSSI_ERROR_01,
|
||||
);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
$mime_type = get_post_mime_type( $post_id );
|
||||
if ( ! relevanssi_mime_type_ok( $mime_type ) ) {
|
||||
delete_post_meta( $post_id, '_relevanssi_pdf_content' );
|
||||
update_post_meta( $post_id, '_relevanssi_pdf_error', RELEVANSSI_ERROR_03 );
|
||||
|
||||
$result = array(
|
||||
'success' => false,
|
||||
'error' => RELEVANSSI_ERROR_03,
|
||||
);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
if ( is_null( $send_file ) ) {
|
||||
$send_file = get_option( 'relevanssi_send_pdf_files' );
|
||||
} elseif ( $send_file ) {
|
||||
$send_file = 'on';
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters whether the PDF files are uploaded for indexing or not.
|
||||
*
|
||||
* If you have some files that need to be uploaded and some where it's
|
||||
* better if the indexer reads them from a URL, you can use this filter
|
||||
* hook to adjust the setting on a per-file basis.
|
||||
*
|
||||
* @param string $sendfile If 'on', upload the file, otherwise the file
|
||||
* will be read from the URL.
|
||||
* @param int $post_id The post ID of the attachment post.
|
||||
*/
|
||||
$send_file = apply_filters( 'relevanssi_send_pdf_files', $send_file, $post_id );
|
||||
|
||||
$api_key = get_network_option( null, 'relevanssi_api_key' );
|
||||
if ( ! $api_key ) {
|
||||
$api_key = get_option( 'relevanssi_api_key' );
|
||||
}
|
||||
$server_url = relevanssi_get_server_url();
|
||||
|
||||
if ( 'on' === get_option( 'relevanssi_do_not_call_home' ) ) {
|
||||
if ( in_array( $server_url, array( RELEVANSSI_EU_SERVICES_URL, RELEVANSSI_US_SERVICES_URL ), true ) ) {
|
||||
delete_post_meta( $post_id, '_relevanssi_pdf_content' );
|
||||
update_post_meta( $post_id, '_relevanssi_pdf_error', RELEVANSSI_ERROR_02 );
|
||||
|
||||
$result = array(
|
||||
'success' => false,
|
||||
'error' => RELEVANSSI_ERROR_02,
|
||||
);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
if ( 'on' === $send_file ) {
|
||||
/**
|
||||
* Filters the attachment file name.
|
||||
*
|
||||
* If you want to make Relevanssi index attached file content from
|
||||
* files that are stored outside the WP attachment system, use this
|
||||
* filter to provide the name of the file.
|
||||
*
|
||||
* @param string The filename of the attached file.
|
||||
* @param int The post ID of the attachment post.
|
||||
*/
|
||||
$file_name = apply_filters(
|
||||
'relevanssi_get_attached_file',
|
||||
get_attached_file( $post_id ),
|
||||
$post_id
|
||||
);
|
||||
|
||||
$file = fopen( $file_name, 'r' ); // phpcs:ignore WordPress.WP.AlternativeFunctions
|
||||
if ( false === $file ) {
|
||||
$response = new WP_Error( 'fopen', 'Could not open the file for reading.' );
|
||||
} else {
|
||||
$file_size = filesize( $file_name );
|
||||
$file_data = fread( $file, $file_size ); // phpcs:ignore WordPress.WP.AlternativeFunctions
|
||||
$args = array(
|
||||
'headers' => array(
|
||||
'accept' => 'application/json', // The API returns JSON.
|
||||
'content-type' => 'application/binary', // Set content type to binary.
|
||||
),
|
||||
'body' => $file_data,
|
||||
/**
|
||||
* Changes the default reading timeout.
|
||||
*
|
||||
* By default, the timeout period is 45 seconds. If that's not
|
||||
* enough, you can adjust the timeout period with this filter.
|
||||
*
|
||||
* @param int $timeout The timeout in seconds, default 45.
|
||||
*/
|
||||
'timeout' => apply_filters( 'relevanssi_pdf_read_timeout', 45 ),
|
||||
);
|
||||
$response = wp_safe_remote_post(
|
||||
$server_url . 'index.php?key=' . $api_key . '&upload=true',
|
||||
$args
|
||||
);
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* Filters the attachment URL.
|
||||
*
|
||||
* If you want to make Relevanssi index attached file content from
|
||||
* files that are stored outside the WP attachment system, use this
|
||||
* filter to provide the URL of the file.
|
||||
*
|
||||
* @param string The URL of the attached file.
|
||||
* @param int The post ID of the attachment post.
|
||||
*/
|
||||
$url = apply_filters(
|
||||
'relevanssi_get_attachment_url',
|
||||
wp_get_attachment_url( $post_id ),
|
||||
$post_id
|
||||
);
|
||||
|
||||
$args = array(
|
||||
'body' => array(
|
||||
'key' => $api_key,
|
||||
'url' => $url,
|
||||
),
|
||||
'method' => 'POST',
|
||||
/**
|
||||
* Changes the default reading timeout.
|
||||
*
|
||||
* By default, the timeout period is 45 seconds. If that's not
|
||||
* enough, you can adjust the timeout period with this filter.
|
||||
*
|
||||
* @param int $timeout The timeout in seconds, default 45.
|
||||
*/
|
||||
'timeout' => apply_filters( 'relevanssi_pdf_read_timeout', 45 ),
|
||||
);
|
||||
|
||||
$response = wp_safe_remote_post( $server_url, $args );
|
||||
}
|
||||
|
||||
$result = relevanssi_process_server_response( $response, $post_id );
|
||||
|
||||
if ( $ajax ) {
|
||||
echo wp_json_encode( $result );
|
||||
wp_die();
|
||||
}
|
||||
|
||||
// The PDF count is cached because the query is slow; delete the cache now, as
|
||||
// the value just changed.
|
||||
wp_cache_delete( 'relevanssi_pdf_count' );
|
||||
wp_cache_delete( 'relevanssi_pdf_error_count' );
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the attachment reading server response.
|
||||
*
|
||||
* Takes in the response from the attachment reading server and stores the attachment
|
||||
* content or the error message to the appropriate custom fields.
|
||||
*
|
||||
* @param array|object $response The server response.
|
||||
* @param int $post_id The attachment post ID.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function relevanssi_process_server_response( $response, $post_id ) {
|
||||
$success = null;
|
||||
$response_error = '';
|
||||
if ( is_wp_error( $response ) ) {
|
||||
$error_message = $response->get_error_message();
|
||||
$response_error .= $error_message . '\n';
|
||||
|
||||
delete_post_meta( $post_id, '_relevanssi_pdf_content' );
|
||||
delete_post_meta( $post_id, '_relevanssi_pdf_modified' );
|
||||
update_post_meta( $post_id, '_relevanssi_pdf_error', $error_message );
|
||||
$success = false;
|
||||
} elseif ( isset( $response['body'] ) ) {
|
||||
$content = $response['body'];
|
||||
$content = json_decode( $content );
|
||||
|
||||
$content_error = '';
|
||||
|
||||
if ( 413 === $response['response']['code'] ) {
|
||||
$content_error = RELEVANSSI_ERROR_04;
|
||||
}
|
||||
|
||||
if ( 504 === $response['response']['code'] ) {
|
||||
$content_error = RELEVANSSI_ERROR_06;
|
||||
}
|
||||
|
||||
if ( isset( $content->error ) ) {
|
||||
$content_error = $content->error;
|
||||
$content = $content->error;
|
||||
}
|
||||
|
||||
if ( $content && stristr( $content, 'java.lang.OutOfMemoryError' ) ) {
|
||||
$content_error = RELEVANSSI_ERROR_04;
|
||||
}
|
||||
|
||||
if ( $content && stristr( $content, 'Tika server returned error code' ) ) {
|
||||
$content_error = RELEVANSSI_ERROR_06;
|
||||
}
|
||||
|
||||
if ( empty( $content ) ) {
|
||||
$content_error = RELEVANSSI_ERROR_06;
|
||||
}
|
||||
|
||||
if ( ! empty( $content_error ) ) {
|
||||
delete_post_meta( $post_id, '_relevanssi_pdf_content' );
|
||||
delete_post_meta( $post_id, '_relevanssi_pdf_modified' );
|
||||
update_post_meta( $post_id, '_relevanssi_pdf_error', $content_error );
|
||||
|
||||
$response_error .= $content_error;
|
||||
$success = false;
|
||||
} else {
|
||||
delete_post_meta( $post_id, '_relevanssi_pdf_error' );
|
||||
delete_post_meta( $post_id, '_relevanssi_pdf_modified' );
|
||||
/**
|
||||
* Filters the read file content before it is saved.
|
||||
*
|
||||
* @param string $content The file content as a string.
|
||||
* @param int $post_id The post ID of the attachment post.
|
||||
*/
|
||||
$success = update_post_meta( $post_id, '_relevanssi_pdf_content', apply_filters( 'relevanssi_file_content', $content, $post_id ) );
|
||||
relevanssi_index_doc( $post_id, false, relevanssi_get_custom_fields(), true );
|
||||
if ( 'on' === get_option( 'relevanssi_index_pdf_parent' ) ) {
|
||||
if ( function_exists( 'get_post_parent' ) ) {
|
||||
$parent = get_post_parent( $post_id );
|
||||
} else {
|
||||
// For WP < 5.7 compatibility, remove eventually.
|
||||
$_post = get_post( $post_id );
|
||||
$parent = ! empty( $_post->post_parent ) ? get_post( $_post->post_parent ) : null;
|
||||
}
|
||||
if ( $parent ) {
|
||||
relevanssi_index_doc( $parent->ID, true, relevanssi_get_custom_fields(), true );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $success ) {
|
||||
$response_error = __( 'Could not save the file content to the custom field.', 'relevanssi' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$response = array(
|
||||
'success' => $success,
|
||||
'error' => $response_error,
|
||||
);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the posts with attachments.
|
||||
*
|
||||
* Finds the posts with non-image attachments that don't have read content or
|
||||
* errors. The posts that have timeout or connection errors (cURL error 7 and
|
||||
* 28, R_ERR06) and those that haven't been read for privacy mode issues
|
||||
* (R_ERR02) will be included for indexing, but the posts with other errors
|
||||
* (R_ERR01: post excluded by user, R_ERR03: blocked MIME type and R_ERR04: file
|
||||
* too large) will not be indexed.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param int $limit The number of posts to fetch, default 1.
|
||||
*
|
||||
* @return array The posts with attachments.
|
||||
*/
|
||||
function relevanssi_get_posts_with_attachments( $limit = 1 ) {
|
||||
global $wpdb;
|
||||
|
||||
$meta_query_args = array(
|
||||
'relation' => 'AND',
|
||||
array(
|
||||
'key' => '_relevanssi_pdf_content',
|
||||
'compare' => 'NOT EXISTS',
|
||||
),
|
||||
array(
|
||||
'relation' => 'OR',
|
||||
array(
|
||||
'key' => '_relevanssi_pdf_error',
|
||||
'compare' => 'NOT EXISTS',
|
||||
),
|
||||
array(
|
||||
'key' => '_relevanssi_pdf_error',
|
||||
'compare' => 'LIKE',
|
||||
'value' => 'R_ERR02:',
|
||||
),
|
||||
array(
|
||||
'key' => '_relevanssi_pdf_error',
|
||||
'compare' => 'LIKE',
|
||||
'value' => 'cURL error 7:',
|
||||
),
|
||||
array(
|
||||
'key' => '_relevanssi_pdf_error',
|
||||
'compare' => 'LIKE',
|
||||
'value' => 'cURL error 28:',
|
||||
),
|
||||
array(
|
||||
'key' => '_relevanssi_pdf_error',
|
||||
'compare' => 'LIKE',
|
||||
'value' => 'is not valid.',
|
||||
),
|
||||
),
|
||||
);
|
||||
$meta_query = new WP_Meta_Query( $meta_query_args );
|
||||
$meta_query_sql = $meta_query->get_sql( 'post', $wpdb->posts, 'ID' );
|
||||
$meta_join = '';
|
||||
$meta_where = '';
|
||||
if ( $meta_query_sql ) {
|
||||
$meta_join = $meta_query_sql['join'];
|
||||
$meta_where = $meta_query_sql['where'];
|
||||
}
|
||||
|
||||
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared
|
||||
if ( $limit > 0 ) {
|
||||
$query = $wpdb->prepare(
|
||||
/**
|
||||
* Filters the SQL query that fetches posts with attachments.
|
||||
*
|
||||
* If you want to make Relevanssi index attachments that are not in
|
||||
* the WP Media Library, you need to adjust this filter to change
|
||||
* the SQL query so that it fetches the correct posts.
|
||||
*
|
||||
* @param string The SQL query
|
||||
* @param int $limit The number of posts to fetch.
|
||||
* @param string $meta_join The SQL query join clause.
|
||||
* @param string $meta_where The SQL query where clause.
|
||||
*/
|
||||
apply_filters(
|
||||
'relevanssi_get_attachment_posts_query',
|
||||
"SELECT DISTINCT(ID) FROM $wpdb->posts $meta_join WHERE post_type = 'attachment' AND post_status = 'inherit' AND post_mime_type LIKE %s $meta_where LIMIT %d",
|
||||
$limit,
|
||||
$meta_join,
|
||||
$meta_where
|
||||
),
|
||||
'application/%',
|
||||
$limit
|
||||
);
|
||||
} else {
|
||||
$query = $wpdb->prepare(
|
||||
/** Filter documented in /premium/pdf-upload.php. */
|
||||
apply_filters(
|
||||
'relevanssi_get_attachment_posts_query',
|
||||
"SELECT DISTINCT(ID) FROM $wpdb->posts $meta_join WHERE post_type = 'attachment' AND post_status = 'inherit' AND post_mime_type LIKE %s $meta_where",
|
||||
0,
|
||||
$meta_join,
|
||||
$meta_where
|
||||
),
|
||||
'application/%'
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Filters the final SQL query that fetches posts with attachments.
|
||||
*
|
||||
* @param string $query The SQL query.
|
||||
* @param int $limit The number of posts to fetch.
|
||||
* @param string $meta_join The SQL query join clause.
|
||||
* @param string $meta_where The SQL query where clause.
|
||||
*/
|
||||
$query = apply_filters( 'relevanssi_get_attachment_posts_query_final', $query, $limit, $meta_join, $meta_where );
|
||||
// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared
|
||||
$posts = $wpdb->get_col( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared
|
||||
|
||||
return $posts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints out the Javascript for PDF content reading.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function relevanssi_pdf_action_javascript() {
|
||||
$list_pdfs_nonce = wp_create_nonce( 'relevanssi-list-pdfs' );
|
||||
$wipe_pdfs_nonce = wp_create_nonce( 'relevanssi-wipe-pdfs' );
|
||||
$wipe_errors_nonce = wp_create_nonce( 'relevanssi-wipe-errors' );
|
||||
$index_pdfs_nonce = wp_create_nonce( 'relevanssi-index-pdfs' );
|
||||
|
||||
$server_error = __( 'Server error', 'relevanssi' );
|
||||
|
||||
?>
|
||||
<script type="text/javascript" >
|
||||
var time = 0;
|
||||
var intervalID = 0;
|
||||
|
||||
function relevanssiUpdateClock( ) {
|
||||
time++;
|
||||
var time_formatted = rlv_format_time(Math.round(time));
|
||||
document.getElementById("relevanssi_elapsed").innerHTML = time_formatted;
|
||||
}
|
||||
|
||||
jQuery(document).ready(function($ ) {
|
||||
$("#index").on("click", function( ) {
|
||||
$("#relevanssi-progress").show();
|
||||
$("#relevanssi_results").show();
|
||||
$("#relevanssi-timer").show();
|
||||
$("#stateofthepdfindex").html(relevanssi.reload_state);
|
||||
|
||||
intervalID = window.setInterval(relevanssiUpdateClock, 1000);
|
||||
|
||||
var data = {
|
||||
'action': 'relevanssi_list_pdfs',
|
||||
'security': '<?php echo esc_html( $list_pdfs_nonce ); ?>'
|
||||
};
|
||||
|
||||
console.log("Getting a list of pdfs.");
|
||||
|
||||
var relevanssi_results = document.getElementById("relevanssi_results");
|
||||
relevanssi_results.value += relevanssi.counting_attachments;
|
||||
|
||||
var pdf_ids;
|
||||
|
||||
jQuery.post(ajaxurl, data, function(response ) {
|
||||
pdf_ids = JSON.parse(response);
|
||||
console.log(pdf_ids);
|
||||
console.log("Fetching response: " + response);
|
||||
console.log("Heading into step 0");
|
||||
console.log(pdf_ids.length);
|
||||
relevanssi_results.value += pdf_ids.length + ' ' + relevanssi.attachments_found + "\n";
|
||||
relevanssi_results.value += relevanssi.indexing_attachments + "\n";
|
||||
process_step(0, pdf_ids.length, 0);
|
||||
})
|
||||
.fail(function(response ) {
|
||||
console.log("Error: " + response);
|
||||
relevanssi_results.value += relevanssi.error + "\n";
|
||||
relevanssi_results.value += response.responseText;
|
||||
});
|
||||
});
|
||||
$("#reset").on("click", function($ ) {
|
||||
if (confirm( relevanssi.pdf_reset_confirm ) ) {
|
||||
var data = {
|
||||
'action': 'relevanssi_wipe_pdfs',
|
||||
'security': '<?php echo esc_html( $wipe_pdfs_nonce ); ?>'
|
||||
}
|
||||
jQuery.post(ajaxurl, data, function(response ) {
|
||||
var delete_response = JSON.parse(response);
|
||||
if ( ! delete_response.deleted_content && ! delete_response.deleted_errors ) {
|
||||
alert( relevanssi.pdf_reset_problems );
|
||||
} else {
|
||||
alert( relevanssi.pdf_reset_done );
|
||||
}
|
||||
jQuery("#stateofthepdfindex").html(relevanssi.reload_state);
|
||||
});
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
$("#clearservererrors").on("click", function($ ) {
|
||||
var data = {
|
||||
'action': 'relevanssi_wipe_server_errors',
|
||||
'security': '<?php echo esc_html( $wipe_errors_nonce ); ?>'
|
||||
}
|
||||
jQuery.post(ajaxurl, data, function(response ) {
|
||||
var delete_response = JSON.parse(response);
|
||||
if ( ! delete_response.deleted_rows ) {
|
||||
alert( relevanssi.error_reset_problems );
|
||||
} else {
|
||||
alert( relevanssi.error_reset_done );
|
||||
}
|
||||
jQuery("#stateofthepdfindex").html(relevanssi.reload_state);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function process_step(completed, total, total_seconds ) {
|
||||
var t0 = performance.now();
|
||||
jQuery.ajax({
|
||||
type: 'POST',
|
||||
url: ajaxurl,
|
||||
data: {
|
||||
action: 'relevanssi_index_pdfs',
|
||||
security: '<?php echo esc_html( $index_pdfs_nonce ); ?>',
|
||||
completed: completed,
|
||||
total: total,
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function(response ) {
|
||||
console.log(response);
|
||||
var relevanssi_results = document.getElementById("relevanssi_results");
|
||||
if (response.completed == 'done' ) {
|
||||
relevanssi_results.value += response.feedback;
|
||||
jQuery( '.rpi-progress div').animate({
|
||||
width: response.percentage + '%',
|
||||
}, 50, function( ) {
|
||||
// Animation complete.
|
||||
});
|
||||
|
||||
clearInterval(intervalID);
|
||||
}
|
||||
else {
|
||||
var t1 = performance.now();
|
||||
var time_seconds = (t1 - t0) / 1000;
|
||||
time_seconds = Math.round(time_seconds * 100) / 100;
|
||||
total_seconds += time_seconds;
|
||||
|
||||
var estimated_time = rlv_format_approximate_time(Math.round(total_seconds / response.percentage * 100 - total_seconds));
|
||||
document.getElementById("relevanssi_estimated").innerHTML = estimated_time;
|
||||
|
||||
relevanssi_results.value += response.feedback;
|
||||
relevanssi_results.scrollTop = relevanssi_results.scrollHeight;
|
||||
jQuery( '.rpi-progress div').animate({
|
||||
width: response.percentage + '%',
|
||||
}, 50, function( ) {
|
||||
// Animation complete.
|
||||
});
|
||||
console.log("Heading into step " + response.completed);
|
||||
process_step(parseInt(response.completed), total, total_seconds);
|
||||
}
|
||||
},
|
||||
error: function(response ) {
|
||||
console.log("Error: ", response.status);
|
||||
var relevanssi_results = document.getElementById("relevanssi_results");
|
||||
relevanssi_results.value += "<?php echo esc_html( $server_error ); ?>: " + response.status + " " + response.statusText + "\n";
|
||||
relevanssi_results.scrollTop = relevanssi_results.scrollHeight;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves attachment edit page metadata.
|
||||
*
|
||||
* Saves the attachment content metadata if it has been edited and sets the
|
||||
* _relevanssi_pdf_modified flag if necessary.
|
||||
*
|
||||
* @global $relevanssi_variables The global Relevanssi variables array.
|
||||
*
|
||||
* @param int $post_id The attachment post ID.
|
||||
*/
|
||||
function relevanssi_save_pdf_postdata( $post_id ) {
|
||||
global $relevanssi_variables;
|
||||
// Verify if this is an auto save routine. If it is, our form has not been
|
||||
// submitted, so we dont want to do anything.
|
||||
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify the nonce.
|
||||
if ( isset( $_POST['relevanssi_pdfcontent'] ) ) { // WPCS: input var okey.
|
||||
if ( ! wp_verify_nonce(
|
||||
sanitize_key( $_POST['relevanssi_pdfcontent'] ),
|
||||
plugin_basename( $relevanssi_variables['file'] )
|
||||
)
|
||||
) { // WPCS: input var okey.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$post = $_POST; // WPCS: input var okey.
|
||||
|
||||
// If relevanssi_pdf_content is not set, it's a quick edit.
|
||||
if ( ! isset( $post['relevanssi_pdf_content'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check permissions.
|
||||
if ( ! current_user_can( 'edit_post', $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$original_post_meta = get_post_meta( $post_id, '_relevanssi_pdf_content', true );
|
||||
$new_post_meta = stripslashes( $post['relevanssi_pdf_content'] );
|
||||
if ( $new_post_meta !== $original_post_meta ) {
|
||||
if ( $new_post_meta ) {
|
||||
update_post_meta(
|
||||
$post_id,
|
||||
'_relevanssi_pdf_content',
|
||||
$new_post_meta
|
||||
);
|
||||
update_post_meta(
|
||||
$post_id,
|
||||
'_relevanssi_pdf_modified',
|
||||
true
|
||||
);
|
||||
} else {
|
||||
delete_post_meta(
|
||||
$post_id,
|
||||
'_relevanssi_pdf_content'
|
||||
);
|
||||
delete_post_meta(
|
||||
$post_id,
|
||||
'_relevanssi_pdf_modified'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If attachments are indexed for the parent post, reindex the parent post.
|
||||
*
|
||||
* When attachments are attached or detached, this triggers a reindexing of the
|
||||
* parent post.
|
||||
*
|
||||
* @param string $action The attachment action.
|
||||
* @param int $attachment_id The attachment post ID.
|
||||
* @param int $parent_id The parent post ID.
|
||||
*/
|
||||
function relevanssi_media_attach_action( $action, $attachment_id, $parent_id ) {
|
||||
$index_pdf_parent = get_option( 'relevanssi_index_pdf_parent' );
|
||||
if ( 'on' === $index_pdf_parent ) {
|
||||
relevanssi_publish( $parent_id );
|
||||
}
|
||||
}
|
||||
@@ -1,260 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* /premium/pinning.php
|
||||
*
|
||||
* Pinning feature.
|
||||
*
|
||||
* @package Relevanssi_Premium
|
||||
* @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_add_pinned_words_to_post_content', 10, 2 );
|
||||
add_filter( 'relevanssi_post_title_before_tokenize', 'relevanssi_pinning_backup', 10, 2 );
|
||||
add_filter( 'relevanssi_hits_filter', 'relevanssi_pinning' );
|
||||
|
||||
/**
|
||||
* Adds the pinned posts to searches.
|
||||
*
|
||||
* Finds the posts that are pinned to the search terms and adds them to the search
|
||||
* results if necessary. This function is triggered from the 'relevanssi_hits_filter'
|
||||
* filter hook.
|
||||
*
|
||||
* @global $wpdb The WordPress database interface.
|
||||
* @global $wp_filter The global filter array.
|
||||
*
|
||||
* @param array $hits The hits found.
|
||||
*
|
||||
* @return array $hits The hits, with pinned posts.
|
||||
*/
|
||||
function relevanssi_pinning( $hits ) {
|
||||
global $wpdb, $wp_filter;
|
||||
|
||||
// Is pinning used?
|
||||
$results = $wpdb->get_results( "SELECT * FROM $wpdb->postmeta WHERE ( meta_key = '_relevanssi_pin' OR meta_key = '_relevanssi_unpin' OR meta_key = '_relevanssi_pin_for_all' ) AND meta_value != '' LIMIT 1" );
|
||||
if ( ! is_multisite() && empty( $results ) ) {
|
||||
// No, nothing is pinned.
|
||||
return $hits;
|
||||
}
|
||||
|
||||
// Disable all filter functions on 'relevanssi_stemmer'.
|
||||
if ( isset( $wp_filter['relevanssi_stemmer'] ) ) {
|
||||
$callbacks = $wp_filter['relevanssi_stemmer']->callbacks;
|
||||
$wp_filter['relevanssi_stemmer']->callbacks = null;
|
||||
}
|
||||
|
||||
$terms = relevanssi_tokenize( $hits[1], false, -1, 'search_query' );
|
||||
|
||||
// Re-enable the removed filters.
|
||||
if ( isset( $wp_filter['relevanssi_stemmer'] ) ) {
|
||||
$wp_filter['relevanssi_stemmer']->callbacks = $callbacks;
|
||||
}
|
||||
|
||||
$escaped_terms = array();
|
||||
foreach ( array_keys( $terms ) as $term ) {
|
||||
$escaped_terms[] = esc_sql( trim( $term ) );
|
||||
}
|
||||
|
||||
$term_list = array();
|
||||
$count_escaped_terms = count( $escaped_terms );
|
||||
for ( $length = 1; $length <= $count_escaped_terms; $length++ ) {
|
||||
for ( $offset = 0; $offset <= $count_escaped_terms - $length; $offset++ ) {
|
||||
$slice = array_slice( $escaped_terms, $offset, $length );
|
||||
$term_list[] = implode( ' ', $slice );
|
||||
}
|
||||
}
|
||||
|
||||
$full_search_phrase = esc_sql( trim( $hits[1] ) );
|
||||
if ( ! in_array( $full_search_phrase, $term_list, true ) ) {
|
||||
$term_list[] = $full_search_phrase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Doing this instead of individual get_post_meta() calls can cut hundreds
|
||||
* of database queries!
|
||||
*/
|
||||
$posts_pinned_for_all = array_flip(
|
||||
$wpdb->get_col(
|
||||
"SELECT post_id FROM $wpdb->postmeta
|
||||
WHERE meta_key = '_relevanssi_pin_for_all'
|
||||
AND meta_value = 'on'"
|
||||
)
|
||||
);
|
||||
|
||||
$pin_weights_sql = $wpdb->get_results(
|
||||
"SELECT post_id, meta_value FROM $wpdb->postmeta
|
||||
WHERE meta_key = '_relevanssi_pin_weights'"
|
||||
);
|
||||
|
||||
$pin_weights = array();
|
||||
foreach ( $pin_weights_sql as $row ) {
|
||||
$pin_weights[ $row->post_id ] = $row->meta_value;
|
||||
}
|
||||
unset( $pin_weights_sql );
|
||||
|
||||
/**
|
||||
* If the search query is "foo bar baz", $term_list now contains "foo", "bar",
|
||||
*"baz", "foo bar", "bar baz", and "foo bar baz".
|
||||
*/
|
||||
if ( is_array( $term_list ) ) {
|
||||
$term_list_array = $term_list;
|
||||
|
||||
array_multisort( array_map( 'relevanssi_strlen', $term_list_array ), SORT_DESC, $term_list_array );
|
||||
|
||||
$term_list = implode( "','", $term_list );
|
||||
$term_list = "'$term_list'";
|
||||
|
||||
$positive_ids = array();
|
||||
$negative_ids = array();
|
||||
|
||||
$pins_fetched = false;
|
||||
$pinned_posts = array();
|
||||
$other_posts = array();
|
||||
foreach ( $hits[0] as $hit ) {
|
||||
$object_array = relevanssi_get_an_object( $hit );
|
||||
$hit = $object_array['object'];
|
||||
$return_value = $object_array['format'];
|
||||
|
||||
$blog_id = 0;
|
||||
if ( isset( $hit->blog_id ) && function_exists( 'switch_to_blog' ) ) {
|
||||
// Multisite, so switch_to_blog() to correct blog and process
|
||||
// the pinned hits per blog.
|
||||
$blog_id = $hit->blog_id;
|
||||
switch_to_blog( $blog_id );
|
||||
if ( ! isset( $pins_fetched[ $blog_id ] ) ) {
|
||||
$positive_ids[ $blog_id ] = $wpdb->get_col( 'SELECT post_id FROM ' . $wpdb->prefix . "postmeta WHERE meta_key = '_relevanssi_pin' AND meta_value IN ( $term_list )" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
$negative_ids[ $blog_id ] = $wpdb->get_col( 'SELECT post_id FROM ' . $wpdb->prefix . "postmeta WHERE meta_key = '_relevanssi_unpin' AND meta_value IN ( $term_list )" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
if ( ! is_array( $pins_fetched ) ) {
|
||||
$pins_fetched = array();
|
||||
}
|
||||
$pins_fetched[ $blog_id ] = true;
|
||||
}
|
||||
restore_current_blog();
|
||||
} elseif ( ! $pins_fetched ) { // Single site.
|
||||
$positive_ids[0] = $wpdb->get_col( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_pin' AND meta_value IN ( $term_list )" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
$negative_ids[0] = $wpdb->get_col( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_unpin' AND meta_value IN ( $term_list )" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
$pins_fetched = true;
|
||||
}
|
||||
$hit_id = strval( $hit->ID ); // The IDs from the database are strings, the one from the post is an integer in some contexts.
|
||||
|
||||
$positive_match = isset( $positive_ids[ $blog_id ] )
|
||||
&& is_array( $positive_ids[ $blog_id ] )
|
||||
&& in_array( $hit_id, $positive_ids[ $blog_id ], true );
|
||||
$negative_match = isset( $negative_ids[ $blog_id ] )
|
||||
&& is_array( $negative_ids[ $blog_id ] )
|
||||
&& in_array( $hit_id, $negative_ids[ $blog_id ], true );
|
||||
$pinned_for_all = isset( $hit->ID ) && isset( $posts_pinned_for_all[ $hit->ID ] );
|
||||
|
||||
$pin_weight = 0;
|
||||
$weights = unserialize( $pin_weights[ $hit->ID ] ?? '' ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_unserialize
|
||||
foreach ( $term_list_array as $term ) {
|
||||
if ( isset( $weights[ $term ] ) ) {
|
||||
$pin_weight = $weights[ $term ];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( 0 === $pin_weight ) {
|
||||
$term = $term_list_array[0];
|
||||
$pin_weight = 1;
|
||||
}
|
||||
|
||||
if ( $hit_id && $positive_match && ! $negative_match ) {
|
||||
$hit->relevanssi_pinned = 1;
|
||||
$pinned_posts[ $term ][ $pin_weight ][] = relevanssi_return_value( $hit, $return_value );
|
||||
} elseif ( $pinned_for_all && ! $negative_match ) {
|
||||
$hit->relevanssi_pinned = 1;
|
||||
$pinned_posts[0][0][] = relevanssi_return_value( $hit, $return_value );
|
||||
} elseif ( ! $negative_match ) {
|
||||
$other_posts[] = relevanssi_return_value( $hit, $return_value );
|
||||
}
|
||||
}
|
||||
array_multisort( array_map( 'relevanssi_strlen', array_keys( $pinned_posts ) ), SORT_DESC, $pinned_posts );
|
||||
|
||||
$all_pinned_posts = array();
|
||||
foreach ( $pinned_posts as $term => $posts_for_term ) {
|
||||
krsort( $posts_for_term, SORT_NUMERIC );
|
||||
$posts_for_term = call_user_func_array( 'array_merge', $posts_for_term );
|
||||
$all_pinned_posts = array_merge( $all_pinned_posts, $posts_for_term );
|
||||
}
|
||||
|
||||
$hits[0] = array_merge( $all_pinned_posts, $other_posts );
|
||||
}
|
||||
return $hits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds pinned words to post content.
|
||||
*
|
||||
* Adds pinned terms to post content to make sure posts are found with the
|
||||
* pinned terms.
|
||||
*
|
||||
* @param string $content Post content.
|
||||
* @param object $post The post object.
|
||||
*/
|
||||
function relevanssi_add_pinned_words_to_post_content( $content, $post ) {
|
||||
$pin_words = get_post_meta( $post->ID, '_relevanssi_pin', false );
|
||||
foreach ( $pin_words as $word ) {
|
||||
$content .= " $word";
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds pinned words to post title.
|
||||
*
|
||||
* If the `relevanssi_index_content` filter hook returns `false`, ie. post
|
||||
* content is not indexed, this function will add the pinned words to the post
|
||||
* title instead to guarantee they are found in the search.
|
||||
*
|
||||
* @param string $content Titlecontent.
|
||||
* @param object $post The post object.
|
||||
*/
|
||||
function relevanssi_pinning_backup( $content, $post ) {
|
||||
if ( false === apply_filters( 'relevanssi_index_content', true ) ) {
|
||||
$content = relevanssi_add_pinned_words_to_post_content( $content, $post );
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the pinning functionality for the admin search.
|
||||
*
|
||||
* @param object $post The post object.
|
||||
* @param string $query The search query.
|
||||
*
|
||||
* @return array First item is a string containing the pinning buttons, the second
|
||||
* item is a string containing the "pinned" notice if the post is
|
||||
* pinned.
|
||||
*/
|
||||
function relevanssi_admin_search_pinning( $post, $query ) {
|
||||
$pinned = '';
|
||||
$pinning_buttons = array();
|
||||
|
||||
$pinned_words = array();
|
||||
if ( isset( $post->relevanssi_pinned ) ) {
|
||||
$pinned_words = get_post_meta( $post->ID, '_relevanssi_pin' );
|
||||
$pinned = '<strong>' . __( '(pinned)', 'relevanssi' ) . '</strong>';
|
||||
}
|
||||
|
||||
if ( ! current_user_can( 'edit_post', $post->ID ) ) {
|
||||
return array( '', $pinned );
|
||||
}
|
||||
|
||||
$tokens = relevanssi_tokenize( $query, true, -1, 'search_query' );
|
||||
foreach ( array_keys( $tokens ) as $token ) {
|
||||
if ( ! in_array( $token, $pinned_words, true ) ) {
|
||||
/* Translators: %s is the search term. */
|
||||
$pinning_button = sprintf( '<button type="button" class="pin" data-postid="%1$d" data-keyword="%2$s">%3$s</button>', $post->ID, $token, sprintf( __( "Pin for '%s'", 'relevanssi' ), $token ) );
|
||||
$pinning_buttons[] = $pinning_button;
|
||||
} else {
|
||||
/* Translators: %s is the search term. */
|
||||
$pinning_button = sprintf( '<button type="button" class="unpin" data-postid="%1$d" data-keyword="%2$s">%3$s</button>', $post->ID, $token, sprintf( __( "Unpin for '%s'", 'relevanssi' ), $token ) );
|
||||
$pinning_buttons[] = $pinning_button;
|
||||
}
|
||||
}
|
||||
$pinning_buttons = implode( ' ', $pinning_buttons );
|
||||
|
||||
return array( $pinning_buttons, $pinned );
|
||||
}
|
||||
@@ -1,607 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* /premium/post-metabox.php
|
||||
*
|
||||
* Relevanssi Premium post metaboxes controls.
|
||||
*
|
||||
* @package Relevanssi_Premium
|
||||
* @author Mikko Saari
|
||||
* @license https://wordpress.org/about/gpl/ GNU General Public License
|
||||
* @see https://www.relevanssi.com/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adds the Relevanssi metaboxes for post edit pages.
|
||||
*
|
||||
* Adds the Relevanssi Post Controls meta box on the post edit pages on post
|
||||
* types that are indexed by Relevanssi.
|
||||
*/
|
||||
function relevanssi_add_metaboxes() {
|
||||
global $post, $relevanssi_variables;
|
||||
if ( null === $post ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! current_user_can(
|
||||
/**
|
||||
* Filters the capability required to access the Relevanssi sidebar.
|
||||
*
|
||||
* @param string The capability required, default 'edit_others_posts'.
|
||||
*/
|
||||
apply_filters( 'relevanssi_sidebar_capability', $relevanssi_variables['sidebar_capability'] )
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$indexed_post_types = get_option( 'relevanssi_index_post_types', array() );
|
||||
if ( ! in_array( $post->post_type, $indexed_post_types, true ) ) {
|
||||
return;
|
||||
}
|
||||
add_meta_box(
|
||||
'relevanssi_hidebox',
|
||||
__( 'Relevanssi', 'relevanssi' ),
|
||||
'relevanssi_post_metabox',
|
||||
array( $post->post_type, 'edit-category' ),
|
||||
'side',
|
||||
'default',
|
||||
array( '__back_compat_meta_box' => true )
|
||||
);
|
||||
add_thickbox(); // Make sure Thickbox is enabled.
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints out the Relevanssi Post Controls meta box.
|
||||
*
|
||||
* Prints out the Relevanssi Post Controls meta box that is displayed on the post edit pages.
|
||||
*
|
||||
* @global array $relevanssi_variables The Relevanssi global variables array, used to get the file name for nonce.
|
||||
* @global object $post The global post object.
|
||||
*/
|
||||
function relevanssi_post_metabox() {
|
||||
global $relevanssi_variables, $post;
|
||||
wp_nonce_field( plugin_basename( $relevanssi_variables['file'] ), 'relevanssi_hidepost' );
|
||||
|
||||
$hide_post = checked( 'on', get_post_meta( $post->ID, '_relevanssi_hide_post', true ), false );
|
||||
$hide_content = checked( 'on', get_post_meta( $post->ID, '_relevanssi_hide_content', true ), false );
|
||||
$pin_for_all = checked( 'on', get_post_meta( $post->ID, '_relevanssi_pin_for_all', true ), false );
|
||||
|
||||
$pins = get_post_meta( $post->ID, '_relevanssi_pin', false );
|
||||
$pin_weights = get_post_meta( $post->ID, '_relevanssi_pin_weights', true );
|
||||
$weighted_pins = array();
|
||||
foreach ( $pins as $pin ) {
|
||||
if ( isset( $pin_weights[ $pin ] ) ) {
|
||||
$pin .= ' (' . $pin_weights[ $pin ] . ')';
|
||||
}
|
||||
$weighted_pins[] = $pin;
|
||||
}
|
||||
$pin = implode( ', ', $weighted_pins );
|
||||
|
||||
$unpins = get_post_meta( $post->ID, '_relevanssi_unpin', false );
|
||||
$unpin = implode( ', ', $unpins );
|
||||
|
||||
// The actual fields for data entry.
|
||||
?>
|
||||
<input type="hidden" id="relevanssi_metabox" name="relevanssi_metabox" value="true" />
|
||||
|
||||
<p><strong><a name="<?php esc_html_e( 'How Relevanssi sees this post', 'relevanssi' ); ?>" href="#TB_inline?width=800&height=600&inlineId=relevanssi_sees_container" class="thickbox"><?php esc_html_e( 'How Relevanssi sees this post', 'relevanssi' ); ?></a></strong></p>
|
||||
|
||||
<p><strong><?php esc_html_e( 'Pin this post', 'relevanssi' ); ?></strong></p>
|
||||
<p><?php esc_html_e( 'A comma-separated list of single word keywords or multi-word phrases. If any of these keywords are present in the search query, this post will be moved on top of the search results.', 'relevanssi' ); ?></p>
|
||||
<label for="relevanssi_pin" class="screen-reader-text"><?php esc_html_e( 'Pinned keywords for this post', 'relevanssi' ); ?></label>
|
||||
<textarea id="relevanssi_pin" name="relevanssi_pin" cols="30" rows="2" style="max-width: 100%"><?php echo esc_html( $pin ); ?></textarea/>
|
||||
|
||||
<p><?php esc_html_e( "You can add weights to pinned keywords like this: 'keyword (100)'. The post with the highest weight will be sorted first if there are multiple posts pinned to the same keyword.", 'relevanssi' ); ?></p>
|
||||
|
||||
<?php
|
||||
if ( 0 === intval( get_option( 'relevanssi_content_boost' ) ) ) {
|
||||
?>
|
||||
<p><?php esc_html_e( "NOTE: You have set the post content weight to 0. This means that keywords that don't appear elsewhere in the post won't work, because they are indexed as part of the post content. If you set the post content weight to any positive value, the pinned keywords will work again.", 'relevanssi' ); ?></p>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
<p><input type="checkbox" id="relevanssi_pin_for_all" name="relevanssi_pin_for_all" <?php echo esc_attr( $pin_for_all ); ?> />
|
||||
<label for="relevanssi_pin_for_all">
|
||||
<?php esc_html_e( 'Pin this post for all searches it appears in.', 'relevanssi' ); ?>
|
||||
</label></p>
|
||||
|
||||
<p><strong><?php esc_html_e( 'Exclude this post', 'relevanssi' ); ?></strong></p>
|
||||
<p><?php esc_html_e( 'A comma-separated list of single word keywords or multi-word phrases. If any of these keywords are present in the search query, this post will be removed from the search results.', 'relevanssi' ); ?></p>
|
||||
<label for="relevanssi_unpin" class="screen-reader-text"><?php esc_html_e( 'Excluded keywords for this post', 'relevanssi' ); ?></label>
|
||||
<textarea id="relevanssi_unpin" name="relevanssi_unpin" cols="30" rows="2" style="max-width: 100%"><?php echo esc_html( $unpin ); ?></textarea>
|
||||
|
||||
<p><input type="checkbox" id="relevanssi_hide_post" name="relevanssi_hide_post" <?php echo esc_attr( $hide_post ); ?> />
|
||||
<label for="relevanssi_hide_post">
|
||||
<?php esc_html_e( 'Exclude this post or page from the index.', 'relevanssi' ); ?>
|
||||
</label></p>
|
||||
|
||||
<p><input type="checkbox" id="relevanssi_hide_content" name="relevanssi_hide_content" <?php echo esc_attr( $hide_content ); ?> />
|
||||
<label for="relevanssi_hide_content">
|
||||
<?php esc_html_e( 'Ignore post content in the indexing.', 'relevanssi' ); ?>
|
||||
</label></p>
|
||||
|
||||
<?php
|
||||
$related_posts_settings = get_option( 'relevanssi_related_settings', relevanssi_related_default_settings() );
|
||||
if ( isset( $related_posts_settings['enabled'] ) && 'on' === $related_posts_settings['enabled'] ) {
|
||||
relevanssi_related_posts_metabox( $post->ID );
|
||||
}
|
||||
|
||||
$display = false;
|
||||
$element = relevanssi_generate_how_relevanssi_sees( $post->ID, $display );
|
||||
echo $element; // phpcs:ignore WordPress.Security.EscapeOutput
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the Relevanssi Gutenberg sidebar meta data.
|
||||
*
|
||||
* When a post is saved in Gutenberg, this function saves the Relevanssi
|
||||
* sidebar meta data.
|
||||
*
|
||||
* @param object $post The post object.
|
||||
*/
|
||||
function relevanssi_save_gutenberg_postdata( $post ) {
|
||||
// Verify if this is an auto save routine.
|
||||
// If it is, our form has not been submitted, so we dont want to do anything.
|
||||
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check nonce here?
|
||||
|
||||
$keywords = get_post_meta( $post->ID, '_relevanssi_pin_keywords', true );
|
||||
relevanssi_update_pin_fields( $post->ID, $keywords );
|
||||
|
||||
$keywords = get_post_meta( $post->ID, '_relevanssi_unpin_keywords', true );
|
||||
relevanssi_update_unpin_fields( $post->ID, $keywords );
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the _relevanssi_pin custom fields based on a list of keywords.
|
||||
*
|
||||
* @param int $post_id The post ID.
|
||||
* @param string $keywords The keywords.
|
||||
*/
|
||||
function relevanssi_update_pin_fields( $post_id, $keywords ) {
|
||||
$pin_weights = array();
|
||||
if ( $keywords ) {
|
||||
delete_post_meta( $post_id, '_relevanssi_pin' );
|
||||
$pins = explode( ',', sanitize_text_field( wp_unslash( $keywords ) ) );
|
||||
foreach ( $pins as $pin ) {
|
||||
list( $pin, $weight ) = array_pad( explode( '(', $pin, 2 ), 2, '1' );
|
||||
|
||||
$weight = str_replace( ')', '', $weight );
|
||||
$weight = intval( $weight );
|
||||
if ( $weight < 1 ) {
|
||||
$weight = 1;
|
||||
}
|
||||
$pin = trim( $pin );
|
||||
|
||||
if ( $weight > 1 ) {
|
||||
$pin_weights[ $pin ] = $weight;
|
||||
}
|
||||
|
||||
if ( ! empty( $pin ) ) {
|
||||
add_post_meta( $post_id, '_relevanssi_pin', $pin );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
delete_post_meta( $post_id, '_relevanssi_pin' );
|
||||
}
|
||||
if ( ! empty( $pin_weights ) ) {
|
||||
update_post_meta( $post_id, '_relevanssi_pin_weights', $pin_weights );
|
||||
} else {
|
||||
delete_post_meta( $post_id, '_relevanssi_pin_weights' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the _relevanssi_unpin custom fields based on a list of keywords.
|
||||
*
|
||||
* @param int $post_id The post ID.
|
||||
* @param string $keywords The keywords.
|
||||
*/
|
||||
function relevanssi_update_unpin_fields( $post_id, $keywords ) {
|
||||
if ( $keywords ) {
|
||||
delete_post_meta( $post_id, '_relevanssi_unpin' );
|
||||
$pins = explode( ',', sanitize_text_field( wp_unslash( $keywords ) ) );
|
||||
foreach ( $pins as $pin ) {
|
||||
$pin = trim( $pin );
|
||||
if ( ! empty( $pin ) ) {
|
||||
add_post_meta( $post_id, '_relevanssi_unpin', $pin );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
delete_post_meta( $post_id, '_relevanssi_unpin' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves Relevanssi metabox data.
|
||||
*
|
||||
* When a post is saved in the Classic Editor, this function saves the
|
||||
* Relevanssi Post Controls metabox data.
|
||||
*
|
||||
* @param int $post_id The post ID that is being saved.
|
||||
*/
|
||||
function relevanssi_save_postdata( $post_id ) {
|
||||
global $relevanssi_variables;
|
||||
// Verify if this is an auto save routine. If it is, our form has not been
|
||||
// submitted, so we dont want to do anything.
|
||||
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify the nonce.
|
||||
if ( isset( $_POST['relevanssi_hidepost'] ) ) { // WPCS: input var okey.
|
||||
if ( ! wp_verify_nonce(
|
||||
sanitize_key( $_POST['relevanssi_hidepost'] ),
|
||||
plugin_basename( $relevanssi_variables['file'] )
|
||||
)
|
||||
) { // WPCS: input var okey.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$post = $_POST; // WPCS: input var okey.
|
||||
|
||||
// If relevanssi_metabox is not set, it's a quick edit.
|
||||
if ( ! isset( $post['relevanssi_metabox'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check permissions.
|
||||
if ( isset( $post['post_type'] ) ) {
|
||||
if ( 'page' === $post['post_type'] ) {
|
||||
if ( ! current_user_can( 'edit_page', $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
} elseif ( ! current_user_can( 'edit_post', $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$hide = '';
|
||||
if ( isset( $post['relevanssi_hide_post'] ) && 'on' === $post['relevanssi_hide_post'] ) {
|
||||
$hide = 'on';
|
||||
}
|
||||
|
||||
if ( 'on' === $hide ) {
|
||||
// Post is marked hidden, so remove it from the index.
|
||||
relevanssi_remove_doc( $post_id );
|
||||
}
|
||||
|
||||
if ( 'on' === $hide ) {
|
||||
update_post_meta( $post_id, '_relevanssi_hide_post', $hide );
|
||||
} else {
|
||||
delete_post_meta( $post_id, '_relevanssi_hide_post' );
|
||||
}
|
||||
|
||||
$hide_content = '';
|
||||
if ( isset( $post['relevanssi_hide_content'] ) && 'on' === $post['relevanssi_hide_content'] ) {
|
||||
$hide_content = 'on';
|
||||
}
|
||||
|
||||
if ( 'on' === $hide_content ) {
|
||||
update_post_meta( $post_id, '_relevanssi_hide_content', $hide_content );
|
||||
} else {
|
||||
delete_post_meta( $post_id, '_relevanssi_hide_content' );
|
||||
}
|
||||
|
||||
$pin_for_all = '';
|
||||
if ( isset( $post['relevanssi_pin_for_all'] ) && 'on' === $post['relevanssi_pin_for_all'] ) {
|
||||
$pin_for_all = 'on';
|
||||
}
|
||||
|
||||
if ( 'on' === $pin_for_all ) {
|
||||
update_post_meta( $post_id, '_relevanssi_pin_for_all', $pin_for_all );
|
||||
} else {
|
||||
delete_post_meta( $post_id, '_relevanssi_pin_for_all' );
|
||||
}
|
||||
|
||||
if ( isset( $post['relevanssi_pin'] ) ) {
|
||||
relevanssi_update_pin_fields( $post_id, $post['relevanssi_pin'] );
|
||||
} else {
|
||||
delete_post_meta( $post_id, '_relevanssi_pin' );
|
||||
}
|
||||
|
||||
if ( isset( $post['relevanssi_unpin'] ) ) {
|
||||
delete_post_meta( $post_id, '_relevanssi_unpin' );
|
||||
$pins = explode( ',', sanitize_text_field( wp_unslash( $post['relevanssi_unpin'] ) ) );
|
||||
foreach ( $pins as $pin ) {
|
||||
$pin = trim( $pin );
|
||||
if ( ! empty( $pin ) ) {
|
||||
add_post_meta( $post_id, '_relevanssi_unpin', $pin );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
delete_post_meta( $post_id, '_relevanssi_unpin' );
|
||||
}
|
||||
|
||||
$no_append = '';
|
||||
if ( isset( $post['relevanssi_related_no_append'] ) && 'on' === $post['relevanssi_related_no_append'] ) {
|
||||
$no_append = 'on';
|
||||
}
|
||||
|
||||
if ( 'on' === $no_append ) {
|
||||
update_post_meta( $post_id, '_relevanssi_related_no_append', $no_append );
|
||||
} else {
|
||||
delete_post_meta( $post_id, '_relevanssi_related_no_append' );
|
||||
}
|
||||
|
||||
$not_related = '';
|
||||
if ( isset( $post['relevanssi_related_not_related'] ) && 'on' === $post['relevanssi_related_not_related'] ) {
|
||||
$not_related = 'on';
|
||||
}
|
||||
|
||||
if ( 'on' === $not_related ) {
|
||||
update_post_meta( $post_id, '_relevanssi_related_not_related', $not_related );
|
||||
} else {
|
||||
delete_post_meta( $post_id, '_relevanssi_related_not_related' );
|
||||
}
|
||||
|
||||
if ( isset( $post['relevanssi_related_keywords'] ) ) {
|
||||
delete_post_meta( $post_id, '_relevanssi_related_keywords' );
|
||||
$keywords = sanitize_text_field( $post['relevanssi_related_keywords'] );
|
||||
if ( $keywords ) {
|
||||
add_post_meta( $post_id, '_relevanssi_related_keywords', $keywords );
|
||||
}
|
||||
} else {
|
||||
delete_post_meta( $post_id, '_relevanssi_related_keywords' );
|
||||
}
|
||||
|
||||
if ( isset( $post['relevanssi_related_include_ids'] ) ) {
|
||||
delete_post_meta( $post_id, '_relevanssi_related_include_ids' );
|
||||
$include_ids_array = explode( ',', $post['relevanssi_related_include_ids'] );
|
||||
$valid_ids = array();
|
||||
foreach ( $include_ids_array as $id ) {
|
||||
$id = (int) trim( $id );
|
||||
if ( is_int( $id ) ) {
|
||||
if ( get_post( $id ) ) {
|
||||
$valid_ids[] = $id;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! empty( $valid_ids ) ) {
|
||||
$id_string = implode( ',', $valid_ids );
|
||||
add_post_meta( $post_id, '_relevanssi_related_include_ids', $id_string );
|
||||
}
|
||||
} else {
|
||||
delete_post_meta( $post_id, '_relevanssi_related_include_ids' );
|
||||
}
|
||||
|
||||
// Clear the related posts cache for this post.
|
||||
delete_post_meta( $post_id, '_relevanssi_related_posts' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints out the metabox part for related posts.
|
||||
*
|
||||
* @param int $post_id The post ID.
|
||||
*/
|
||||
function relevanssi_related_posts_metabox( $post_id ) {
|
||||
$related = get_post_meta( $post_id, '_relevanssi_related_keywords', true );
|
||||
$include_ids = get_post_meta( $post_id, '_relevanssi_related_include_ids', true );
|
||||
$no_append = checked( 'on', get_post_meta( $post_id, '_relevanssi_related_no_append', true ), false );
|
||||
$not_related = checked( 'on', get_post_meta( $post_id, '_relevanssi_related_not_related', true ), false );
|
||||
|
||||
if ( '0' === $include_ids ) {
|
||||
$include_ids = '';
|
||||
}
|
||||
?>
|
||||
<p><strong><?php esc_html_e( 'Related Posts', 'relevanssi' ); ?></strong></p>
|
||||
|
||||
<p><label><input type="checkbox" name="relevanssi_related_no_append" id="relevanssi_related_no_append" <?php echo esc_attr( $no_append ); ?>/>
|
||||
<?php esc_html_e( "Don't append the related posts to this page.", 'relevanssi' ); ?></label></p>
|
||||
|
||||
<p><label><input type="checkbox" name="relevanssi_related_not_related" id="relevanssi_related_not_related" <?php echo esc_attr( $not_related ); ?>/>
|
||||
<?php esc_html_e( "Don't show this as a related post for any post.", 'relevanssi' ); ?></label></p>
|
||||
|
||||
<p><strong><?php esc_html_e( 'Related Posts keywords', 'relevanssi' ); ?></strong></p>
|
||||
<p><?php esc_html_e( 'A comma-separated list of keywords to use for the Related Posts feature. Anything entered here will be used when searching for related posts. Using phrases with quotes is allowed, but will restrict the related posts to posts including that phrase.', 'relevanssi' ); ?></p>
|
||||
<label for="relevanssi_related_keywords" class="screen-reader-text"><?php esc_html_e( 'Related posts keywords for this post', 'relevanssi' ); ?></label>
|
||||
<p><textarea id="relevanssi_related_keywords" name="relevanssi_related_keywords" cols="30" rows="2" style="max-width: 100%"><?php echo esc_html( $related ); ?></textarea></p>
|
||||
|
||||
<p><label for="relevanssi_related_include_ids"><?php esc_html_e( 'A comma-separated list of post IDs to use as related posts for this post', 'relevanssi' ); ?></label>:</p>
|
||||
<p><input type="text" id="relevanssi_related_include_ids" name="relevanssi_related_include_ids" value="<?php echo esc_html( $include_ids ); ?>"/></p>
|
||||
|
||||
<p><?php esc_html_e( 'These are the related posts Relevanssi currently will show for this post:', 'relevanssi' ); ?></p>
|
||||
|
||||
<input type="hidden" id="this_post_id" value="<?php echo esc_attr( $post_id ); ?>" />
|
||||
<ol id='related_posts_list'>
|
||||
<?php
|
||||
echo relevanssi_generate_related_list( $post_id ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
?>
|
||||
</ol>
|
||||
|
||||
<p><?php esc_html_e( 'These posts are excluded from related posts for this post', 'relevanssi' ); ?>:</p>
|
||||
<ul id='excluded_posts_list'>
|
||||
<?php
|
||||
echo relevanssi_generate_excluded_list( $post_id ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
?>
|
||||
</ul>
|
||||
|
||||
<p><strong><?php esc_html_e( 'Insights', 'relevanssi' ); ?></strong></p>
|
||||
<p>The most common search terms for this post:</p>
|
||||
<ol id='most_common_terms'>
|
||||
<?php
|
||||
echo relevanssi_generate_tracking_insights_most_common( $post_id ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
?>
|
||||
</ol>
|
||||
|
||||
<p>Low-ranking search terms for this post:</p>
|
||||
<ol id='low_ranking_terms'>
|
||||
<?php
|
||||
echo relevanssi_generate_tracking_insights_low_ranking( $post_id ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
?>
|
||||
</ol>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates tracking insights.
|
||||
*
|
||||
* @param int $post_id The post ID.
|
||||
* @param string $output If 'HTML', output HTML code. If 'ARRAY', output an
|
||||
* array. Default value is 'HTML'.
|
||||
*/
|
||||
function relevanssi_generate_tracking_insights_most_common( int $post_id, string $output = 'HTML' ) {
|
||||
global $wpdb, $relevanssi_variables;
|
||||
$table = $relevanssi_variables['tracking_table'];
|
||||
|
||||
$output_html = 'ARRAY' !== $output ? true : false;
|
||||
if ( $output_html ) {
|
||||
$list = '';
|
||||
} else {
|
||||
$list = array();
|
||||
}
|
||||
|
||||
$common_terms = $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT DISTINCT(query), COUNT(*) AS `count` FROM $table" . // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared
|
||||
' WHERE post_id = %d
|
||||
GROUP BY query
|
||||
ORDER BY count DESC
|
||||
LIMIT 5',
|
||||
$post_id
|
||||
)
|
||||
);
|
||||
|
||||
if ( $common_terms ) {
|
||||
if ( $output_html ) {
|
||||
$list = '<li>' . implode(
|
||||
'</li><li>',
|
||||
array_map(
|
||||
function ( $v ) {
|
||||
return "$v->query ($v->count)";
|
||||
},
|
||||
$common_terms
|
||||
)
|
||||
) . '</li></ol>';
|
||||
} else {
|
||||
$list = $common_terms;
|
||||
}
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates tracking insights.
|
||||
*
|
||||
* @param int $post_id The post ID.
|
||||
* @param string $output If 'HTML', output HTML code. If 'ARRAY', output an
|
||||
* array. Default value is 'HTML'.
|
||||
*/
|
||||
function relevanssi_generate_tracking_insights_low_ranking( int $post_id, string $output = 'HTML' ) {
|
||||
global $wpdb, $relevanssi_variables;
|
||||
$table = $relevanssi_variables['tracking_table'];
|
||||
|
||||
$output_html = 'ARRAY' !== $output ? true : false;
|
||||
if ( $output_html ) {
|
||||
$list = '';
|
||||
} else {
|
||||
$list = array();
|
||||
}
|
||||
|
||||
$low_ranking_terms = $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT `query`, `rank` FROM $table" . // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared
|
||||
' WHERE post_id = %d
|
||||
AND `rank` > 1
|
||||
ORDER BY `rank` DESC
|
||||
LIMIT 5',
|
||||
$post_id
|
||||
)
|
||||
);
|
||||
|
||||
if ( $low_ranking_terms ) {
|
||||
if ( $output_html ) {
|
||||
$list = '<li>' . implode(
|
||||
'</li><li>',
|
||||
array_map(
|
||||
function ( $v ) {
|
||||
return "$v->query ($v->rank)";
|
||||
},
|
||||
$low_ranking_terms
|
||||
)
|
||||
) . '</li></ol>';
|
||||
} else {
|
||||
$list = $low_ranking_terms;
|
||||
}
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a list of related posts for the related posts metabox.
|
||||
*
|
||||
* @param int $post_id The post ID.
|
||||
* @param string $output If 'HTML', output HTML code. If 'ARRAY', output an
|
||||
* array. Default value is 'HTML'.
|
||||
*/
|
||||
function relevanssi_generate_related_list( $post_id, $output = 'HTML' ) {
|
||||
$output_html = 'ARRAY' !== $output ? true : false;
|
||||
if ( $output_html ) {
|
||||
$list = '';
|
||||
} else {
|
||||
$list = array();
|
||||
}
|
||||
$related_posts = relevanssi_get_related_post_ids( $post_id );
|
||||
foreach ( $related_posts as $related_post_id ) {
|
||||
$title = get_the_title( $related_post_id );
|
||||
$link = get_permalink( $related_post_id );
|
||||
if ( $output_html ) {
|
||||
$list .= '<li><a href="' . esc_attr( $link ) . '">'
|
||||
. esc_html( $title ) . '</a> '
|
||||
. '(<button type="button" class="removepost" data-removepost="'
|
||||
. esc_attr( $related_post_id ) . '">'
|
||||
. esc_html__( 'not this', 'relevanssi' ) .
|
||||
'</button>)</li>';
|
||||
} else {
|
||||
$list[] = array(
|
||||
'id' => $related_post_id,
|
||||
'title' => $title,
|
||||
'link' => $link,
|
||||
);
|
||||
}
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a list of excluded posts for the related posts metabox.
|
||||
*
|
||||
* @param int $post_id The post ID.
|
||||
* @param string $output If 'HTML', output HTML code. If 'ARRAY', output an
|
||||
* array. Default value is 'HTML'.
|
||||
*/
|
||||
function relevanssi_generate_excluded_list( $post_id, $output = 'HTML' ) {
|
||||
$output_html = 'ARRAY' !== $output ? true : false;
|
||||
if ( $output_html ) {
|
||||
$list = '';
|
||||
} else {
|
||||
$list = array();
|
||||
}
|
||||
$excluded_posts = get_post_meta( $post_id, '_relevanssi_related_exclude_ids', true );
|
||||
if ( $excluded_posts ) {
|
||||
$excluded_array = explode( ',', $excluded_posts );
|
||||
foreach ( $excluded_array as $excluded_post_id ) {
|
||||
$title = get_the_title( $excluded_post_id );
|
||||
$link = get_permalink( $excluded_post_id );
|
||||
if ( $output_html ) {
|
||||
$list .= '<li><a href="' . esc_attr( $link ) . '">' . esc_html( $title ) . '</a> (<button type="button" class="returnpost" data-returnpost="' . esc_attr( $excluded_post_id ) . '">' . esc_html__( 'use this', 'relevanssi' ) . '</button>)</li>';
|
||||
} else {
|
||||
$list[] = array(
|
||||
'id' => $excluded_post_id,
|
||||
'title' => $title,
|
||||
'link' => $link,
|
||||
);
|
||||
}
|
||||
}
|
||||
} elseif ( $output_html ) {
|
||||
$list .= '<li>' . esc_html__( 'Nothing excluded.', 'relevanssi' ) . '</li>';
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
@@ -1,189 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* /premium/proximity.php
|
||||
*
|
||||
* @package Relevanssi_Premium
|
||||
* @author Mikko Saari
|
||||
* @license https://wordpress.org/about/gpl/ GNU General Public License
|
||||
* @see https://www.relevanssi.com/
|
||||
*/
|
||||
|
||||
add_action( 'init', 'relevanssi_enable_proximity_sorting' );
|
||||
|
||||
/**
|
||||
* Adds the proximity sorting filters.
|
||||
*
|
||||
* If the relevanssi_proximity_sorting filter returns true, adds the required
|
||||
* filters to make the proximity searching work.
|
||||
*/
|
||||
function relevanssi_enable_proximity_sorting() {
|
||||
/**
|
||||
* Controls whether the proximity searching is enabled or not.
|
||||
*
|
||||
* @param boolean If true, enable proximity sorting. Default false.
|
||||
*/
|
||||
if ( apply_filters( 'relevanssi_proximity_sorting', false ) ) {
|
||||
add_filter( 'relevanssi_results', 'relevanssi_add_distance', 1 );
|
||||
add_filter( 'relevanssi_search_params', 'relevanssi_pick_up_coordinates', 10, 2 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the distances to the found posts.
|
||||
*
|
||||
* The coordinates from each post come from the relevanssi_proximity_coordinates
|
||||
* filter hook based on the post ID. The comparison coordinates come from the
|
||||
* global $relevanssi_coordinates variable, filtered by the
|
||||
* relevanssi_proximity_comparison filter hook. The coordinates need to be in
|
||||
* the floating point format, separated with a comma, latitude first.
|
||||
*
|
||||
* The distance for each post to the comparison coordinates is stored to the
|
||||
* global $relevanssi_distance array for the post ID.
|
||||
*
|
||||
* @uses relevanssi_get_distance()
|
||||
*
|
||||
* @param array $doc_weight An array of post ID => weight pairs. This function
|
||||
* ignores the weight and only cares about the post ID.
|
||||
*
|
||||
* @return array The $doc_weight array untouched.
|
||||
*/
|
||||
function relevanssi_add_distance( $doc_weight ) {
|
||||
global $relevanssi_coordinates;
|
||||
|
||||
/**
|
||||
* Filters the comparison coordinates Relevanssi uses.
|
||||
*
|
||||
* @param string The coordinates in "latitude, longitude" format.
|
||||
*/
|
||||
$compare_coordinates = apply_filters(
|
||||
'relevanssi_proximity_comparison',
|
||||
$relevanssi_coordinates // // phpcs:ignore WordPress.Security.NonceVerification
|
||||
);
|
||||
|
||||
if ( ! $compare_coordinates ) {
|
||||
return $doc_weight;
|
||||
}
|
||||
|
||||
list( $latitude_from, $longitude_from ) = explode( ',', $compare_coordinates );
|
||||
|
||||
$latitude_from = floatval( $latitude_from );
|
||||
$longitude_from = floatval( $longitude_from );
|
||||
|
||||
global $relevanssi_distance;
|
||||
$relevanssi_distance = array();
|
||||
|
||||
foreach ( array_keys( $doc_weight ) as $post_id ) {
|
||||
/**
|
||||
* Filters the coordinates for each post.
|
||||
*
|
||||
* @param string The coordinates.
|
||||
* @param int The post ID.
|
||||
*/
|
||||
$hit_coordinates = apply_filters(
|
||||
'relevanssi_proximity_coordinates',
|
||||
'',
|
||||
$post_id
|
||||
);
|
||||
if ( ! $hit_coordinates ) {
|
||||
/**
|
||||
* Filters the default distance for posts without coordinates.
|
||||
*
|
||||
* @param int The default distance, default PHP_INT_MAX.
|
||||
*/
|
||||
$default_distance = apply_filters(
|
||||
'relevanssi_proximity_default_distance',
|
||||
PHP_INT_MAX
|
||||
);
|
||||
$relevanssi_distance[ $post_id ] = $default_distance;
|
||||
}
|
||||
|
||||
list( $latitude_to, $longitude_to ) = explode( ',', $hit_coordinates );
|
||||
|
||||
$latitude_to = floatval( $latitude_to );
|
||||
$longitude_to = floatval( $longitude_to );
|
||||
|
||||
$distance = relevanssi_get_distance(
|
||||
$latitude_from,
|
||||
$longitude_from,
|
||||
$latitude_to,
|
||||
$longitude_to
|
||||
);
|
||||
|
||||
$relevanssi_distance[ $post_id ] = $distance;
|
||||
}
|
||||
|
||||
return $doc_weight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the great-circle distance between two points.
|
||||
*
|
||||
* Uses the Haversine formula.
|
||||
*
|
||||
* @param float $latitude_from Latitude of start point in [deg decimal].
|
||||
* @param float $longitude_from Longitude of start point in [deg decimal].
|
||||
* @param float $latitude_to Latitude of target point in [deg decimal].
|
||||
* @param float $longitude_to Longitude of target point in [deg decimal].
|
||||
*
|
||||
* @return float Distance between points in kilometers.
|
||||
*/
|
||||
function relevanssi_get_distance( float $latitude_from, float $longitude_from, float $latitude_to, float $longitude_to ): float {
|
||||
$earth_radius = 6371;
|
||||
|
||||
$lat_from = deg2rad( $latitude_from );
|
||||
$lon_from = deg2rad( $longitude_from );
|
||||
$lat_to = deg2rad( $latitude_to );
|
||||
$lon_to = deg2rad( $longitude_to );
|
||||
|
||||
$lat_delta = $lat_to - $lat_from;
|
||||
$lon_delta = $lon_to - $lon_from;
|
||||
|
||||
$angle = 2 * asin(
|
||||
sqrt(
|
||||
pow( sin( $lat_delta / 2 ), 2 )
|
||||
+ cos( $lat_from ) * cos( $lat_to )
|
||||
* pow( sin( $lon_delta / 2 ), 2 )
|
||||
)
|
||||
);
|
||||
|
||||
return $angle * $earth_radius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the distances for compared posts.
|
||||
*
|
||||
* Gets the distances from the $relevanssi_distance global array.
|
||||
*
|
||||
* @param object $post_a The first post object.
|
||||
* @param object $post_b The second post object.
|
||||
*
|
||||
* @return array Array containing the distance to post A and to post B. Default
|
||||
* value is 0.
|
||||
*/
|
||||
function relevanssi_get_proximity_values( $post_a, $post_b ) {
|
||||
global $relevanssi_distance;
|
||||
|
||||
$distance_to_a = $relevanssi_distance[ $post_a->ID ] ?? 0;
|
||||
$distance_to_b = $relevanssi_distance[ $post_b->ID ] ?? 0;
|
||||
return array( $distance_to_a, $distance_to_b );
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the 'coordinates' query variable and stores it to a global variable.
|
||||
*
|
||||
* Stores the comparison coordinates from the 'coordinates' query variable in
|
||||
* the $relevanssi_coordinates global variable, because that is the easiest way
|
||||
* to access that data in the relevanssi_add_distance() function.
|
||||
*
|
||||
* @see relevanssi_add_distance().
|
||||
*
|
||||
* @param array $params The search parameters; ignored.
|
||||
* @param WP_Query $query The query object.
|
||||
*
|
||||
* @return array The search parameters untouched.
|
||||
*/
|
||||
function relevanssi_pick_up_coordinates( $params, $query ) {
|
||||
global $relevanssi_coordinates;
|
||||
$relevanssi_coordinates = $query->query_vars['coordinates'];
|
||||
return $params;
|
||||
}
|
||||
@@ -1,216 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* /premium/redirects.php
|
||||
*
|
||||
* Handles straight redirects based on keywords.
|
||||
*
|
||||
* @package Relevanssi_Premium
|
||||
* @author Mikko Saari
|
||||
* @license https://wordpress.org/about/gpl/ GNU General Public License
|
||||
* @see https://www.relevanssi.com/
|
||||
*/
|
||||
|
||||
add_action( 'template_redirect', 'relevanssi_redirects' );
|
||||
|
||||
/**
|
||||
* Handles the template redirects.
|
||||
*
|
||||
* Reads the redirects from the 'relevanssi_redirects' option and performs the
|
||||
* redirect if there's a match.
|
||||
*/
|
||||
function relevanssi_redirects() {
|
||||
global $wp_query;
|
||||
|
||||
$url = false;
|
||||
$redirects = get_option( 'relevanssi_redirects', array() );
|
||||
if ( empty( $redirects ) || ! is_array( $redirects ) ) {
|
||||
return;
|
||||
}
|
||||
$query = relevanssi_strtolower( get_search_query( false ) );
|
||||
|
||||
if ( empty( $query ) && function_exists( 'FWP' ) ) {
|
||||
$query = relevanssi_get_facetwp_query();
|
||||
}
|
||||
|
||||
foreach ( $redirects as $redirect ) {
|
||||
if ( ! $redirect || is_string( $redirect ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( $redirect['partial'] ) {
|
||||
$match = false;
|
||||
if ( stristr( $query, $redirect['query'] ) ) {
|
||||
$match = true;
|
||||
}
|
||||
$pattern = '/^' . str_replace( '/', '\/', $redirect['query'] ) . '$/';
|
||||
if ( preg_match( $pattern, $query ) ) {
|
||||
$match = true;
|
||||
}
|
||||
if ( $match ) {
|
||||
$url = $redirect['url'];
|
||||
|
||||
$redirect['hits'] = ! empty( $redirect['hits'] ) ? $redirect['hits'] + 1 : 1;
|
||||
relevanssi_update_redirect( $redirect );
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$match = false;
|
||||
if ( $query === $redirect['query'] ) {
|
||||
$match = true;
|
||||
}
|
||||
$pattern = '/^' . str_replace( '/', '\/', $redirect['query'] ) . '$/';
|
||||
if ( preg_match( $pattern, $query ) ) {
|
||||
$match = true;
|
||||
}
|
||||
if ( $match ) {
|
||||
$url = $redirect['url'];
|
||||
|
||||
$redirect['hits'] = ! empty( $redirect['hits'] ) ? $redirect['hits'] + 1 : 1;
|
||||
relevanssi_update_redirect( $redirect );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $wp_query->is_search && ! $url ) {
|
||||
if ( empty( $query ) && isset( $redirects['no_terms'] ) ) {
|
||||
$url = $redirects['no_terms'];
|
||||
} elseif ( 0 === $wp_query->found_posts && isset( $redirects['empty'] ) ) {
|
||||
$url = $redirects['empty'];
|
||||
}
|
||||
}
|
||||
|
||||
if ( $url ) {
|
||||
if ( wp_redirect( $url ) ) { // phpcs:ignore WordPress.Security.SafeRedirect
|
||||
exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to update the redirect for the hit counting.
|
||||
*
|
||||
* Takes the new redirect, finds the old one by the `query` field and replaces
|
||||
* the redirect in the option.
|
||||
*
|
||||
* @param array $redirect The redirect array to be added to the option.
|
||||
*/
|
||||
function relevanssi_update_redirect( $redirect ) {
|
||||
$redirects = get_option( 'relevanssi_redirects', array() );
|
||||
$key = array_search(
|
||||
$redirect['query'],
|
||||
array_column( $redirects, 'query' ),
|
||||
true
|
||||
);
|
||||
|
||||
update_option(
|
||||
'relevanssi_redirects',
|
||||
array_replace( $redirects, array( $key => $redirect ) )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes relatives URLs absolute and validates all URLs.
|
||||
*
|
||||
* Uses site_url() to make relative URLs absolute and then passes all URLs
|
||||
* through wp_http_validate_url().
|
||||
*
|
||||
* @see wp_http_validate_url()
|
||||
*
|
||||
* @param string $value A relative or absolute URL to validate.
|
||||
*
|
||||
* @return string|false The URL, converted to absolute if necessary, and
|
||||
* validated. Returns false on failure.
|
||||
*/
|
||||
function relevanssi_validate_url( $value ) {
|
||||
if ( 'http' !== substr( $value, 0, 4 ) ) {
|
||||
// Relative URL, make absolute.
|
||||
if ( '/' !== substr( $value, 0, 1 ) ) {
|
||||
$value = '/' . $value;
|
||||
}
|
||||
$value = site_url() . $value;
|
||||
}
|
||||
return wp_http_validate_url( $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the redirects from the request array and validates the URLs.
|
||||
*
|
||||
* All relative URLs are converted to absolute URLs for validation and redirects
|
||||
* with both the query and URL parameters are kept.
|
||||
*
|
||||
* @param array $request The options request array.
|
||||
*
|
||||
* @return array The redirect array.
|
||||
*
|
||||
* @since 2.2.3
|
||||
*/
|
||||
function relevanssi_process_redirects( $request ) {
|
||||
$redirects = array();
|
||||
foreach ( $request as $key => $value ) {
|
||||
if ( 'redirect_empty_searches' === $key && ! empty( $value ) ) {
|
||||
$url = relevanssi_validate_url( $value );
|
||||
if ( ! empty( $url ) ) {
|
||||
$redirects['empty'] = $url;
|
||||
}
|
||||
}
|
||||
if ( 'redirect_no_terms' === $key && ! empty( $value ) ) {
|
||||
$url = relevanssi_validate_url( $value );
|
||||
if ( ! empty( $url ) ) {
|
||||
$redirects['no_terms'] = $url;
|
||||
}
|
||||
}
|
||||
if ( 'query' !== substr( $key, 0, 5 ) ) {
|
||||
continue;
|
||||
}
|
||||
$suffix = substr( $key, 5 );
|
||||
$query = stripslashes( relevanssi_strtolower( $value ) );
|
||||
$partial = false;
|
||||
if ( isset( $request[ 'partial' . $suffix ] ) ) {
|
||||
$partial = true;
|
||||
}
|
||||
$url = null;
|
||||
if ( isset( $request[ 'url' . $suffix ] ) ) {
|
||||
$url = relevanssi_validate_url( $request[ 'url' . $suffix ] );
|
||||
}
|
||||
$hits = $request[ 'hits' . $suffix ] ?? 0;
|
||||
if ( ! empty( $url ) && ! empty( $query ) ) {
|
||||
$redirect = array(
|
||||
'query' => $query,
|
||||
'partial' => $partial,
|
||||
'url' => $url,
|
||||
'hits' => $hits,
|
||||
);
|
||||
$redirects[] = $redirect;
|
||||
}
|
||||
}
|
||||
return $redirects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the search query for FacetWP searches.
|
||||
*
|
||||
* @return string The search query, empty string if nothing is found.
|
||||
*
|
||||
* @author Jan Willem Oostendorp
|
||||
*/
|
||||
function relevanssi_get_facetwp_query() {
|
||||
$query = '';
|
||||
|
||||
if ( ! empty( FWP()->helper->settings['facets'] ) && ! empty( FWP()->request->url_vars ) ) {
|
||||
$facet_searches = array();
|
||||
$url_vars = FWP()->request->url_vars;
|
||||
foreach ( FWP()->helper->settings['facets'] as $facet ) {
|
||||
if ( 'search' === $facet['type'] && 'relevanssi' === $facet['search_engine'] && ! empty( $url_vars[ $facet['name'] ] ) ) {
|
||||
$facet_searches = array_merge( $facet_searches, $url_vars[ $facet['name'] ] );
|
||||
}
|
||||
}
|
||||
|
||||
// If there are multiple search queries we won't even try.
|
||||
if ( 1 === count( $facet_searches ) ) {
|
||||
$query = $facet_searches[0];
|
||||
}
|
||||
}
|
||||
|
||||
return strtolower( $query );
|
||||
}
|
||||
@@ -1,763 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* /premium/related.php
|
||||
*
|
||||
* A related posts feature.
|
||||
*
|
||||
* @package Relevanssi_Premium
|
||||
* @author Mikko Saari
|
||||
* @license https://wordpress.org/about/gpl/ GNU General Public License
|
||||
* @see https://www.relevanssi.com/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adds the the_content filter for related posts.
|
||||
*
|
||||
* If related posts are enabled and auto-append option is in use, adds the_content
|
||||
* filter. This function is called from relevanssi_premium_init().
|
||||
*/
|
||||
function relevanssi_related_init() {
|
||||
$related_posts_settings = get_option( 'relevanssi_related_settings', relevanssi_related_default_settings() );
|
||||
if ( isset( $related_posts_settings['enabled'] ) && 'on' === $related_posts_settings['enabled'] ) {
|
||||
/**
|
||||
* Filters the priority for Relevanssi the_content filter.
|
||||
*
|
||||
* By default the relevanssi_related_posts_the_content_wrapper filter is added to
|
||||
* the_content with priority 99. This filter can be used to alter that value.
|
||||
*
|
||||
* @param int Priority, default 99.
|
||||
*/
|
||||
add_filter( 'the_content', 'relevanssi_related_posts_the_content_wrapper', apply_filters( 'relevanssi_related_priority', 99 ) );
|
||||
add_action( 'transition_post_status', 'relevanssi_flush_caches_on_transition', 99, 3 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns related posts.
|
||||
*
|
||||
* @param int $post_id The post ID. Default null, in which case global $post
|
||||
* is used.
|
||||
* @param boolean $just_objects If true, don't generate the related posts HTML code.
|
||||
* The transient will only contain the post objects for
|
||||
* the related posts. Default false.
|
||||
* @param boolean $no_template If true, don't generate the related posts code. The
|
||||
* transient will not be generated, only the meta field
|
||||
* is generated with the post IDs. Used in the metabox
|
||||
* to avoid problems with running the templates in admin
|
||||
* context. Default false.
|
||||
*
|
||||
* @global array $relevanssi_variables The Relevanssi global variables.
|
||||
*
|
||||
* @return string The related posts HTML element.
|
||||
*/
|
||||
function relevanssi_related_posts( $post_id = null, $just_objects = false, $no_template = false ) {
|
||||
global $relevanssi_variables;
|
||||
|
||||
$related = '';
|
||||
|
||||
if ( $just_objects ) {
|
||||
trigger_error( "You're using relevanssi_related_posts() to fetch post objects. This is deprecated, use relevanssi_get_related_post_objects() instead.", E_USER_DEPRECATED ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
||||
}
|
||||
if ( $no_template ) {
|
||||
trigger_error( "You're using relevanssi_related_posts() to generate related posts without printing out the template. This is deprecated, use relevanssi_get_related_post_ids() instead.", E_USER_DEPRECATED ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
||||
}
|
||||
|
||||
if ( ! $post_id ) {
|
||||
$post_id = get_the_ID();
|
||||
if ( ! $post_id ) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
$settings = get_option( 'relevanssi_related_settings', relevanssi_related_default_settings() );
|
||||
|
||||
/**
|
||||
* Filters the related posts transient cache name.
|
||||
*
|
||||
* @param string The transient name, defaults to relevanssi_related_posts_[ID].
|
||||
*/
|
||||
$transient_name = apply_filters( 'relevanssi_related_posts_cache_id', 'relevanssi_related_posts_' . $post_id );
|
||||
if ( $just_objects ) {
|
||||
$transient_name .= '_jo';
|
||||
}
|
||||
if ( $no_template ) {
|
||||
$transient_name .= '_nt';
|
||||
}
|
||||
|
||||
$use_cache = relevanssi_related_cache_available( $post_id, $settings );
|
||||
|
||||
if ( $use_cache ) {
|
||||
$related = get_transient( $transient_name );
|
||||
if ( $related ) {
|
||||
if ( ! $just_objects && ! $no_template ) {
|
||||
$related .= '<!-- Fetched from cache -->';
|
||||
}
|
||||
/**
|
||||
* Filters the related posts output.
|
||||
*
|
||||
* @param string The output, ready to be displayed.
|
||||
*/
|
||||
return apply_filters( 'relevanssi_related_output', $related );
|
||||
} else {
|
||||
// Post ID custom field returned results, but the transient has
|
||||
// expired. Let's refresh the custom field as well.
|
||||
$use_cache = false;
|
||||
}
|
||||
}
|
||||
|
||||
$related_posts = relevanssi_get_related_post_ids( $post_id, $use_cache );
|
||||
|
||||
if ( $just_objects ) {
|
||||
// Deprecated, remove this functionality eventually.
|
||||
$related_post_objects = array();
|
||||
foreach ( $related_posts as $related_id ) {
|
||||
array_push( $related_post_objects, get_post( $related_id ) );
|
||||
}
|
||||
set_transient( $transient_name, $related_post_objects, WEEK_IN_SECONDS * 2 );
|
||||
} elseif ( ! $no_template ) {
|
||||
$template = locate_template( 'templates/relevanssi-related.php', false );
|
||||
if ( ! $template ) {
|
||||
$template = $relevanssi_variables['plugin_dir'] . 'premium/templates/relevanssi-related.php';
|
||||
}
|
||||
|
||||
ob_start();
|
||||
include $template;
|
||||
$related = ob_get_clean();
|
||||
|
||||
set_transient( $transient_name, $related, WEEK_IN_SECONDS * 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the related posts output.
|
||||
*
|
||||
* @param string The output, ready to be displayed.
|
||||
*/
|
||||
return apply_filters( 'relevanssi_related_output', $related );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns related post objects for the specific post.
|
||||
*
|
||||
* @param int $post_id The post ID. Default null, in which case global $post
|
||||
* is used.
|
||||
*
|
||||
* @return WP_Post[] An array of WordPress post objects.
|
||||
*/
|
||||
function relevanssi_get_related_post_objects( $post_id ) {
|
||||
if ( ! $post_id ) {
|
||||
$post_id = get_the_ID();
|
||||
if ( ! $post_id ) {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
$settings = get_option(
|
||||
'relevanssi_related_settings',
|
||||
relevanssi_related_default_settings()
|
||||
);
|
||||
|
||||
$transient_name = apply_filters( 'relevanssi_related_posts_cache_id', 'relevanssi_related_posts_' . $post_id . '_jo' );
|
||||
$use_cache = relevanssi_related_cache_available( $post_id, $settings );
|
||||
|
||||
if ( $use_cache ) {
|
||||
$related = get_transient( $transient_name );
|
||||
if ( $related ) {
|
||||
return $related;
|
||||
} else {
|
||||
$use_cache = false;
|
||||
}
|
||||
}
|
||||
|
||||
$related_posts = relevanssi_get_related_post_ids( $post_id, $use_cache );
|
||||
|
||||
$related_post_objects = array();
|
||||
foreach ( $related_posts as $related_id ) {
|
||||
array_push( $related_post_objects, get_post( $related_id ) );
|
||||
}
|
||||
set_transient( $transient_name, $related_post_objects, WEEK_IN_SECONDS * 2 );
|
||||
|
||||
return $related_post_objects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if related post cache is available for the current post.
|
||||
*
|
||||
* @param int $post_id The post ID.
|
||||
* @param array $settings The Relevanssi related posts settings.
|
||||
*
|
||||
* @return boolean True, if related post IDs have been cached for the post.
|
||||
*/
|
||||
function relevanssi_related_cache_available( $post_id, $settings ) {
|
||||
$use_cache = true;
|
||||
/**
|
||||
* Disables the caching for related posts. Do not use unless you know
|
||||
* what you are doing.
|
||||
*
|
||||
* @param boolean Set true to disable caching. Default false.
|
||||
*/
|
||||
if ( apply_filters( 'relevanssi_disable_related_cache', false ) ) {
|
||||
$use_cache = false;
|
||||
} elseif ( 'on' !== $settings['cache_for_admins'] && current_user_can( 'manage_options' ) ) {
|
||||
$use_cache = false;
|
||||
} else {
|
||||
// For cache control: if the meta field is empty, cache has been flushed.
|
||||
$post_ids = get_post_meta( $post_id, '_relevanssi_related_posts', true );
|
||||
if ( empty( $post_ids ) ) {
|
||||
$use_cache = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $use_cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches related post IDs.
|
||||
*
|
||||
* @param int $post_id The post ID.
|
||||
* @param boolean $use_cache If false, discard cached results. Default true.
|
||||
*
|
||||
* @return int[] An array of related post IDs.
|
||||
*/
|
||||
function relevanssi_get_related_post_ids( $post_id, $use_cache = true ) {
|
||||
global $wpdb;
|
||||
|
||||
$settings = get_option(
|
||||
'relevanssi_related_settings',
|
||||
relevanssi_related_default_settings()
|
||||
);
|
||||
|
||||
$related_posts_string = get_post_meta(
|
||||
$post_id,
|
||||
'_relevanssi_related_posts',
|
||||
true
|
||||
);
|
||||
|
||||
if ( ! empty( $related_posts_string ) && $use_cache ) {
|
||||
$related_posts = explode( ',', $related_posts_string );
|
||||
return $related_posts;
|
||||
}
|
||||
|
||||
$post_types = explode( ',', $settings['post_types'] );
|
||||
|
||||
if ( 'matching_post_type' === $settings['post_types'] || empty( $post_types ) ) {
|
||||
$post_types = array( get_post_type( $post_id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs before the related posts searches and can be used to adjust the
|
||||
* Relevanssi settings. By default disables query logging.
|
||||
*/
|
||||
do_action( 'pre_relevanssi_related' );
|
||||
|
||||
$words = relevanssi_related_generate_keywords( $post_id );
|
||||
$related_posts = array();
|
||||
|
||||
$include_ids = get_post_meta(
|
||||
$post_id,
|
||||
'_relevanssi_related_include_ids',
|
||||
true
|
||||
);
|
||||
if ( $include_ids ) {
|
||||
$related_posts = explode( ',', $include_ids );
|
||||
}
|
||||
|
||||
$exclude_ids = get_post_meta(
|
||||
$post_id,
|
||||
'_relevanssi_related_exclude_ids',
|
||||
true
|
||||
);
|
||||
if ( $exclude_ids ) {
|
||||
$exclude_ids = explode( ',', $exclude_ids );
|
||||
}
|
||||
if ( ! is_array( $exclude_ids ) ) {
|
||||
$exclude_ids = array();
|
||||
}
|
||||
$exclude_ids[] = $post_id; // Always exclude the current post.
|
||||
|
||||
// These posts are marked as "not related to anything".
|
||||
$global_exclude_ids = $wpdb->get_col(
|
||||
"SELECT post_id FROM $wpdb->postmeta
|
||||
WHERE meta_key = '_relevanssi_related_not_related'
|
||||
AND meta_value <> ''"
|
||||
);
|
||||
|
||||
$exclude_ids = array_merge( $exclude_ids, $global_exclude_ids );
|
||||
$exclude_ids = array_merge( $exclude_ids, $related_posts );
|
||||
$exclude_ids = array_keys( array_flip( $exclude_ids ) );
|
||||
|
||||
$date_query = array();
|
||||
if ( isset( $settings['months'] ) && intval( $settings['months'] ) > 0 ) {
|
||||
$date_query = array(
|
||||
'after' => '-' . $settings['months'] . ' months',
|
||||
);
|
||||
}
|
||||
if ( ! empty( $words ) ) {
|
||||
$count = count( $related_posts );
|
||||
if ( $settings['number'] - $count > 0 ) {
|
||||
$args = array(
|
||||
's' => $words,
|
||||
'posts_per_page' => $settings['number'] - $count,
|
||||
'post_type' => $post_types,
|
||||
'post__not_in' => $exclude_ids,
|
||||
'fields' => 'ids',
|
||||
'operator' => 'OR',
|
||||
'post_status' => 'publish',
|
||||
);
|
||||
if ( $date_query ) {
|
||||
$args['date_query'] = $date_query;
|
||||
}
|
||||
$related_posts_query = new WP_Query();
|
||||
$related_posts_query->parse_query(
|
||||
/**
|
||||
* Filters the related posts search arguments.
|
||||
*
|
||||
* Notice that the defaults vary depending on which related posts
|
||||
* query is done. Avoid overriding default values; preferably just
|
||||
* add extra criteria.
|
||||
*
|
||||
* @param array The related posts arguments.
|
||||
* @param string Which query is run. Values include "or",
|
||||
* "random fill", "random".
|
||||
*/
|
||||
apply_filters(
|
||||
'relevanssi_related_args',
|
||||
$args,
|
||||
'or'
|
||||
)
|
||||
);
|
||||
relevanssi_do_query( $related_posts_query );
|
||||
$related_posts = array_merge( $related_posts, $related_posts_query->posts );
|
||||
|
||||
// There may be null results in the set and those may cause problems
|
||||
// further down the line.
|
||||
$related_posts = array_filter(
|
||||
$related_posts,
|
||||
function ( $value ) {
|
||||
return $value;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs after the related posts searches and can be used to adjust the
|
||||
* Relevanssi settings.
|
||||
*/
|
||||
do_action( 'post_relevanssi_related' );
|
||||
|
||||
$tax_query = array();
|
||||
if ( 'random_cat' === $settings['notenough'] || 'random_cat' === $settings['nothing'] ) {
|
||||
$cats = get_the_category( $post_id );
|
||||
$cat_ids = array_map(
|
||||
function ( $cat ) {
|
||||
return $cat->term_id;
|
||||
},
|
||||
$cats
|
||||
);
|
||||
$tax_query = array(
|
||||
'relation' => 'OR',
|
||||
array(
|
||||
'taxonomy' => 'category',
|
||||
'field' => 'term_id',
|
||||
'terms' => $cat_ids,
|
||||
'operator' => 'IN',
|
||||
),
|
||||
);
|
||||
}
|
||||
$random_fill = in_array(
|
||||
$settings['notenough'],
|
||||
array( 'random', 'random_cat' ),
|
||||
true
|
||||
) ? true : false;
|
||||
if ( $random_fill && ( null === $related_posts || count( $related_posts ) < $settings['number'] ) ) {
|
||||
// Not enough results and user wants a random fillup.
|
||||
if ( null === $related_posts ) {
|
||||
$related_posts = array();
|
||||
}
|
||||
$count = count( $related_posts );
|
||||
|
||||
$exclude_ids = array_merge( $exclude_ids, $related_posts );
|
||||
$exclude_ids = array_keys( array_flip( $exclude_ids ) );
|
||||
|
||||
$args = array(
|
||||
'posts_per_page' => $settings['number'] - $count,
|
||||
'post_type' => $post_types,
|
||||
'post__not_in' => $exclude_ids,
|
||||
'fields' => 'ids',
|
||||
'orderby' => 'rand',
|
||||
'post_status' => 'publish',
|
||||
);
|
||||
if ( $date_query ) {
|
||||
$args['date_query'] = $date_query;
|
||||
}
|
||||
if ( 'random_cat' === $settings['notenough'] ) {
|
||||
$args['tax_query'] = $tax_query;
|
||||
}
|
||||
/** Documented in premium/related.php */
|
||||
$more_related_posts = new WP_Query(
|
||||
apply_filters(
|
||||
'relevanssi_related_args',
|
||||
$args,
|
||||
'random fill'
|
||||
)
|
||||
);
|
||||
$related_posts = array_merge(
|
||||
$related_posts,
|
||||
$more_related_posts->posts
|
||||
);
|
||||
}
|
||||
$all_random = in_array(
|
||||
$settings['nothing'],
|
||||
array( 'random', 'random_cat' ),
|
||||
true
|
||||
) ? true : false;
|
||||
if ( empty( $related_posts ) && $all_random ) {
|
||||
$query = new WP_Query();
|
||||
// No related posts found, user has requested random posts.
|
||||
$args = array(
|
||||
'posts_per_page' => $settings['number'],
|
||||
'post_type' => $post_types,
|
||||
'post__not_in' => $exclude_ids,
|
||||
'fields' => 'ids',
|
||||
'orderby' => 'rand',
|
||||
'post_status' => 'publish',
|
||||
);
|
||||
if ( $date_query ) {
|
||||
$args['date_query'] = $date_query;
|
||||
}
|
||||
if ( 'random_cat' === $settings['nothing'] ) {
|
||||
$args['tax_query'] = $tax_query;
|
||||
}
|
||||
$query->query(
|
||||
/** Documented in premium/related.php */
|
||||
apply_filters(
|
||||
'relevanssi_related_args',
|
||||
$args,
|
||||
'random'
|
||||
)
|
||||
);
|
||||
$related_posts = $query->posts;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sometimes a thoughtless relevanssi_hits_filter filter function may
|
||||
* cause the $related_posts array to contain post objects instead of
|
||||
* post IDs. This step makes sure the array has post IDs.
|
||||
*/
|
||||
$related_posts = array_map(
|
||||
function ( $item ) {
|
||||
if ( is_object( $item ) && isset( $item->ID ) ) {
|
||||
return $item->ID;
|
||||
} else {
|
||||
return $item;
|
||||
}
|
||||
},
|
||||
$related_posts
|
||||
);
|
||||
|
||||
if ( ! $related_posts ) {
|
||||
// For some reason nothing was found.
|
||||
$related_posts = array();
|
||||
}
|
||||
|
||||
$related_posts_string = implode( ',', $related_posts );
|
||||
update_post_meta( $post_id, '_relevanssi_related_posts', $related_posts_string );
|
||||
|
||||
return $related_posts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Echoes out the related posts.
|
||||
*
|
||||
* @param int $post_id The post ID. Default null, in which case global $post is used.
|
||||
*/
|
||||
function relevanssi_the_related_posts( $post_id = null ) {
|
||||
echo relevanssi_related_posts( $post_id ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the related posts for the relevanssi_related_posts shortcode.
|
||||
*
|
||||
* @param array $atts The shortcode parameters; only one used is post_id, which
|
||||
* defaults to null and global $post.
|
||||
*/
|
||||
function relevanssi_related_posts_shortcode( $atts ) {
|
||||
$post_id = null;
|
||||
if ( isset( $atts['post_id'] ) && is_int( $atts['post_id'] ) ) {
|
||||
$post_id = $atts['post_id'];
|
||||
}
|
||||
return relevanssi_related_posts( $post_id );
|
||||
}
|
||||
add_shortcode( 'relevanssi_related_posts', 'relevanssi_related_posts_shortcode' );
|
||||
|
||||
/**
|
||||
* Sets the default settings for related posts.
|
||||
*
|
||||
* @return array Array containing the default settings.
|
||||
*/
|
||||
function relevanssi_related_default_settings() {
|
||||
return array(
|
||||
'enabled' => 'off',
|
||||
'number' => 6,
|
||||
'nothing' => 'nothing',
|
||||
'notenough' => 'random',
|
||||
'post_types' => 'post',
|
||||
'keyword' => 'title',
|
||||
'append' => '',
|
||||
'cache_for_admins' => 'off',
|
||||
'months' => 0,
|
||||
'restrict' => '',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default styles for related posts.
|
||||
*
|
||||
* @return array Array containing the default styles.
|
||||
*/
|
||||
function relevanssi_related_default_styles() {
|
||||
return array(
|
||||
'width' => 250,
|
||||
'titles' => 'on',
|
||||
'excerpts' => 'off',
|
||||
'thumbnails' => 'on',
|
||||
'default_thumbnail' => '',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* A wrapper function to attach the related posts to the_content.
|
||||
*
|
||||
* @param string $content The post content.
|
||||
*
|
||||
* @return string The post content with the related posts appended.
|
||||
*/
|
||||
function relevanssi_related_posts_the_content_wrapper( $content ) {
|
||||
$settings = get_option(
|
||||
'relevanssi_related_settings',
|
||||
relevanssi_related_default_settings()
|
||||
);
|
||||
$post_types = explode( ',', $settings['append'] );
|
||||
if ( is_singular() && in_the_loop() && in_array( get_post_type(), $post_types, true ) ) {
|
||||
global $post;
|
||||
if ( 'on' !== get_post_meta( $post->ID, '_relevanssi_related_no_append', true ) ) {
|
||||
$content .= relevanssi_related_posts();
|
||||
}
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates keywords from the post.
|
||||
*
|
||||
* @param int $post_id The post ID.
|
||||
*/
|
||||
function relevanssi_related_generate_keywords( $post_id ) {
|
||||
global $wpdb, $relevanssi_variables;
|
||||
|
||||
$settings = get_option(
|
||||
'relevanssi_related_settings',
|
||||
relevanssi_related_default_settings()
|
||||
);
|
||||
$keywords = explode( ',', $settings['keyword'] );
|
||||
$restrict = explode( ',', $settings['restrict'] );
|
||||
|
||||
$title_words = array();
|
||||
$tag_words = array();
|
||||
$cat_words = array();
|
||||
$tax_words = array();
|
||||
|
||||
foreach ( $keywords as $keyword ) {
|
||||
if ( empty( $keyword ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( 'title' === $keyword ) {
|
||||
$title_words = $wpdb->get_col(
|
||||
$wpdb->prepare(
|
||||
'SELECT term FROM '
|
||||
. $relevanssi_variables['relevanssi_table'] // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared
|
||||
. ' WHERE doc = %d AND title > 0',
|
||||
$post_id
|
||||
)
|
||||
);
|
||||
} elseif ( 'post_tag' === $keyword ) {
|
||||
$tag_words = $wpdb->get_col(
|
||||
$wpdb->prepare(
|
||||
'SELECT term FROM '
|
||||
. $relevanssi_variables['relevanssi_table'] // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared
|
||||
. ' WHERE doc = %d AND tag > 0 ORDER BY tag DESC',
|
||||
$post_id
|
||||
)
|
||||
);
|
||||
} elseif ( 'category' === $keyword ) {
|
||||
$cat_words = $wpdb->get_col(
|
||||
$wpdb->prepare(
|
||||
'SELECT term FROM '
|
||||
. $relevanssi_variables['relevanssi_table'] // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared
|
||||
. ' WHERE doc = %d AND category > 0 ORDER BY category DESC',
|
||||
$post_id
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$new_tax_words = $wpdb->get_col(
|
||||
$wpdb->prepare(
|
||||
'SELECT term FROM '
|
||||
. $relevanssi_variables['relevanssi_table'] // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared
|
||||
. ' WHERE doc = %d AND taxonomy > 0 AND taxonomy_detail LIKE %s ORDER BY taxonomy DESC',
|
||||
$post_id,
|
||||
'%' . $keyword . '%'
|
||||
)
|
||||
);
|
||||
$new_tax_words = array_map(
|
||||
function ( $a ) use ( $keyword ) {
|
||||
return array(
|
||||
'word' => $a,
|
||||
'taxonomy' => $keyword,
|
||||
);
|
||||
},
|
||||
$new_tax_words
|
||||
);
|
||||
$tax_words = array_merge( $tax_words, $new_tax_words );
|
||||
}
|
||||
}
|
||||
|
||||
$custom_words = get_post_meta( $post_id, '_relevanssi_related_keywords', true );
|
||||
if ( $custom_words ) {
|
||||
$custom_words = explode( ',', $custom_words );
|
||||
} else {
|
||||
$custom_words = array();
|
||||
}
|
||||
|
||||
$tax_words = array_map(
|
||||
function ( $word ) use ( $restrict ) {
|
||||
return in_array(
|
||||
$word['taxonomy'],
|
||||
$restrict,
|
||||
true
|
||||
) ? '{' . $word['taxonomy'] . ':' . $word['word'] . '}' : $word['word'];
|
||||
},
|
||||
$tax_words
|
||||
);
|
||||
if ( in_array( 'post_tag', $restrict, true ) ) {
|
||||
$tag_words = array_map(
|
||||
function ( $word ) {
|
||||
return '{post_tag:' . $word . '}';
|
||||
},
|
||||
$tag_words
|
||||
);
|
||||
}
|
||||
if ( in_array( 'category', $restrict, true ) ) {
|
||||
$cat_words = array_map(
|
||||
function ( $word ) {
|
||||
return '{category:' . $word . '}';
|
||||
},
|
||||
$cat_words
|
||||
);
|
||||
}
|
||||
|
||||
$words = array_merge(
|
||||
$title_words,
|
||||
$tag_words,
|
||||
$cat_words,
|
||||
$tax_words,
|
||||
$custom_words
|
||||
);
|
||||
$words = array_keys( array_flip( $words ) );
|
||||
|
||||
/**
|
||||
* Filters the source words for related posts.
|
||||
*
|
||||
* This filter sees the words right before they are fed into Relevanssi to
|
||||
* find the related posts.
|
||||
*
|
||||
* @param string A space-separated list of keywords for related posts.
|
||||
* @param int The post ID.
|
||||
*/
|
||||
return apply_filters(
|
||||
'relevanssi_related_words',
|
||||
implode( ' ', $words ),
|
||||
$post_id
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes the related post caches.
|
||||
*
|
||||
* Deletes all the _relevanssi_related_posts meta fields. This flushes the
|
||||
* cache. The actual cache is stored in transients, but we don't have a list of
|
||||
* all the transient names and one shouldn't simply remove the transients from
|
||||
* the wp_options database table, because it's possible they're not there.
|
||||
*
|
||||
* So, instead of deleting the transients, Relevanssi deletes the meta fields
|
||||
* which contain a list of post IDs (this is helpful for other uses as well),
|
||||
* which then forces a cache flush.
|
||||
*
|
||||
* @global object $wpdb The WordPress database object.
|
||||
*
|
||||
* @param int $clean_id If specified, only remove meta fields that contain this
|
||||
* ID. Default null, which flushes all caches.
|
||||
*/
|
||||
function relevanssi_flush_related_cache( $clean_id = null ) {
|
||||
global $wpdb;
|
||||
|
||||
if ( is_int( $clean_id ) ) {
|
||||
$clean_id = '%' . $clean_id . '%';
|
||||
$wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"DELETE FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_related_posts' AND meta_value LIKE %s",
|
||||
$clean_id
|
||||
)
|
||||
);
|
||||
// Not perfect, since this will match also rows where post ID contains the
|
||||
// wanted ID, but it's an acceptable minor cost for a simple solution.
|
||||
} else {
|
||||
$wpdb->query(
|
||||
"DELETE FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_related_posts'"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes the caches when a post is made a draft or deleted.
|
||||
*
|
||||
* Called from 'transition_post_status' action hook when a post is made into a draft,
|
||||
* or deleted. Will flush the related post caches where that post appears.
|
||||
*
|
||||
* @global object $wpdb The WP database interface.
|
||||
*
|
||||
* @param string $new_status The new status.
|
||||
* @param string $old_status The old status.
|
||||
* @param object $post The post object.
|
||||
*/
|
||||
function relevanssi_flush_caches_on_transition( $new_status, $old_status, $post ) {
|
||||
// Safety check, for WordPress Editorial Calendar incompatibility.
|
||||
if ( ! isset( $post ) || ! isset( $post->ID ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( 'publish' !== $new_status ) {
|
||||
// The post isn't public anymore.
|
||||
relevanssi_flush_related_cache( $post->ID );
|
||||
}
|
||||
}
|
||||
|
||||
add_action( 'pre_relevanssi_related', 'relevanssi_pre_related_posts' );
|
||||
/**
|
||||
* Runs before the related posts queries and disables logging.
|
||||
*/
|
||||
function relevanssi_pre_related_posts() {
|
||||
// We don't want to log these queries.
|
||||
add_filter( 'relevanssi_ok_to_log', '__return_false' );
|
||||
add_filter( 'pre_option_relevanssi_searchblogs', '__return_false' );
|
||||
add_filter( 'pre_option_relevanssi_searchblogs_all', 'relevanssi_return_off' );
|
||||
}
|
||||
|
||||
add_action( 'post_relevanssi_related', 'relevanssi_post_related_posts' );
|
||||
/**
|
||||
* Runs after the related posts queries and enables logging.
|
||||
*/
|
||||
function relevanssi_post_related_posts() {
|
||||
remove_filter( 'relevanssi_ok_to_log', '__return_false' );
|
||||
remove_filter( 'pre_option_relevanssi_searchblogs', '__return_false' );
|
||||
remove_filter( 'pre_option_relevanssi_searchblogs_all', 'relevanssi_return_off' );
|
||||
}
|
||||
@@ -1,511 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* /premium/search-multi.php
|
||||
*
|
||||
* Multisite searching logic.
|
||||
*
|
||||
* @package Relevanssi_Premium
|
||||
* @author Mikko Saari
|
||||
* @license https://wordpress.org/about/gpl/ GNU General Public License
|
||||
* @see https://www.relevanssi.com/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Does multisite searches.
|
||||
*
|
||||
* Handles the multisite searching when the "searchblogs" parameter is present.
|
||||
* Has slightly limited set of options compared to the single-site searches.
|
||||
*
|
||||
* @global $wpdb The WordPress database interface.
|
||||
* @global $relevanssi_variables The global Relevanssi variables, used for the
|
||||
* database table names.
|
||||
*
|
||||
* @param array $multi_args Multisite search arguments. Possible parameters:
|
||||
* 'post_type', 'search_blogs', 'operator', 'meta_query', 'orderby', 'order'.
|
||||
*
|
||||
* @return array $results Hits found and other information about the result set.
|
||||
*/
|
||||
function relevanssi_search_multi( $multi_args ) {
|
||||
global $wpdb;
|
||||
|
||||
$hits = array();
|
||||
|
||||
/**
|
||||
* Filters the search arguments.
|
||||
*
|
||||
* @param array $multi_args An associative array of the search parameters.
|
||||
*/
|
||||
$filtered_args = apply_filters( 'relevanssi_search_filters', $multi_args );
|
||||
|
||||
$q = $filtered_args['q'] ?? '';
|
||||
if ( empty( $q ) ) {
|
||||
// No search term, can't proceed.
|
||||
return $hits;
|
||||
}
|
||||
|
||||
$search_blogs = $filtered_args['search_blogs'] ?? '';
|
||||
$operator = $filtered_args['operator'] ?? '';
|
||||
$meta_query = $filtered_args['meta_query'] ?? '';
|
||||
$orderby = $filtered_args['orderby'] ?? '';
|
||||
$order = $filtered_args['order'] ?? '';
|
||||
|
||||
$total_hits = 0;
|
||||
|
||||
$match_arrays = relevanssi_initialize_match_arrays();
|
||||
$term_hits = array();
|
||||
$hitsbyweight = array();
|
||||
|
||||
if ( 'all' === $search_blogs ) {
|
||||
$raw_blog_list = get_sites( array( 'number' => 2000 ) ); // There's likely flaming death with even lower values of 'number'.
|
||||
$blog_list = array();
|
||||
foreach ( $raw_blog_list as $blog ) {
|
||||
$blog_list[] = $blog->blog_id;
|
||||
}
|
||||
$search_blogs = implode( ',', $blog_list );
|
||||
}
|
||||
|
||||
$search_blogs = explode( ',', $search_blogs );
|
||||
if ( ! is_array( $search_blogs ) ) {
|
||||
// No blogs to search, so let's quit.
|
||||
return $hits;
|
||||
}
|
||||
|
||||
$post_type_weights = get_option( 'relevanssi_post_type_weights' );
|
||||
|
||||
foreach ( $search_blogs as $blogid ) {
|
||||
$search_again = false;
|
||||
|
||||
if ( ! relevanssi_is_blog_ok( $blogid ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ok, we should have a valid blog.
|
||||
switch_to_blog( $blogid );
|
||||
$relevanssi_table = $wpdb->prefix . 'relevanssi';
|
||||
|
||||
$list_of_tables = $wpdb->get_col( 'SHOW TABLES' );
|
||||
if ( ! in_array( $relevanssi_table, $list_of_tables, true ) ) {
|
||||
restore_current_blog();
|
||||
continue;
|
||||
}
|
||||
|
||||
$query_data = relevanssi_process_multi_query_args( $filtered_args );
|
||||
$query_restrictions = $query_data['query_restrictions'];
|
||||
$query_join = $query_data['query_join'];
|
||||
$q = $query_data['query_query'];
|
||||
$q_no_synonyms = $query_data['query_no_synonyms'];
|
||||
$phrase_queries = $query_data['phrase_queries'];
|
||||
|
||||
if ( 'OR' === $operator ) {
|
||||
$q = relevanssi_add_synonyms( $q );
|
||||
}
|
||||
|
||||
$remove_stopwords = false;
|
||||
$terms = relevanssi_tokenize( $q, $remove_stopwords, 1, 'search_query' );
|
||||
|
||||
if ( count( $terms ) < 1 ) {
|
||||
// Tokenizer killed all the search terms.
|
||||
restore_current_blog();
|
||||
continue;
|
||||
}
|
||||
$terms = array_keys( $terms ); // Don't care about tf in query.
|
||||
|
||||
/**
|
||||
* Filters the query restrictions in Relevanssi.
|
||||
*
|
||||
* Approximately the same purpose as the default 'posts_where' filter hook.
|
||||
* Can be used to add additional query restrictions to the Relevanssi query.
|
||||
*
|
||||
* @param string $query_restrictions MySQL added to the Relevanssi query.
|
||||
*
|
||||
* @author Charles St-Pierre.
|
||||
*/
|
||||
$query_restrictions = apply_filters( 'relevanssi_where', $query_restrictions );
|
||||
|
||||
// Go get the count from the options, but run the full query if it's not available.
|
||||
$doc_count = get_option( 'relevanssi_doc_count' );
|
||||
if ( ! $doc_count || $doc_count < 1 ) {
|
||||
$doc_count = relevanssi_update_doc_count();
|
||||
}
|
||||
|
||||
$no_matches = true;
|
||||
$doc_weight = array();
|
||||
$term_hits = array();
|
||||
|
||||
do {
|
||||
$df_counts = relevanssi_generate_df_counts(
|
||||
$terms,
|
||||
array(
|
||||
'no_terms' => false,
|
||||
'operator' => $operator,
|
||||
'phrase_queries' => $phrase_queries,
|
||||
'query_join' => $query_join,
|
||||
'query_restrictions' => $query_restrictions,
|
||||
'search_again' => $search_again,
|
||||
)
|
||||
);
|
||||
|
||||
foreach ( $df_counts as $term => $df ) {
|
||||
$this_query_restrictions = relevanssi_add_phrase_restrictions(
|
||||
$query_restrictions,
|
||||
$phrase_queries,
|
||||
$term,
|
||||
$operator
|
||||
);
|
||||
|
||||
$query = relevanssi_generate_search_query( $term, $search_again, false, $query_join, $this_query_restrictions );
|
||||
$matches = $wpdb->get_results( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared
|
||||
if ( count( $matches ) < 1 ) {
|
||||
continue;
|
||||
} else {
|
||||
$no_matches = false;
|
||||
}
|
||||
|
||||
$total_hits += count( $matches );
|
||||
|
||||
$idf = log( $doc_count / ( 1 + $df ) );
|
||||
foreach ( $matches as $match ) {
|
||||
$match->doc = relevanssi_adjust_match_doc( $match );
|
||||
$match->tf = relevanssi_calculate_tf( $match, $post_type_weights );
|
||||
$match->weight = relevanssi_calculate_weight( $match, $idf, $post_type_weights, $q );
|
||||
|
||||
/**
|
||||
* Documented in /lib/search.php.
|
||||
*/
|
||||
$match = apply_filters( 'relevanssi_match', $match, $idf, $term );
|
||||
|
||||
if ( $match->weight <= 0 ) {
|
||||
continue; // The filters killed the match.
|
||||
}
|
||||
|
||||
$post_ok = true;
|
||||
/**
|
||||
* Filters whether the user is allowed to see the post.
|
||||
*
|
||||
* Can this post be included in the search results? This is the hook
|
||||
* you’ll use if you want to add support for a membership plugin, for
|
||||
* example. Based on the post ID, your function needs to return true
|
||||
* or false.
|
||||
*
|
||||
* @param boolean $post_ok Can the post be shown in results?
|
||||
* @param int $doc The post ID.
|
||||
*/
|
||||
$post_ok = apply_filters( 'relevanssi_post_ok', $post_ok, $match->doc );
|
||||
if ( ! $post_ok ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
relevanssi_update_term_hits( $term_hits, $match_arrays, $match, $term );
|
||||
|
||||
$doc_id = $blogid . '|' . $match->doc;
|
||||
|
||||
$doc_terms[ $match->doc ][ $term ] = true; // Count how many terms are matched to a doc.
|
||||
if ( ! isset( $doc_weight[ $doc_id ] ) ) {
|
||||
$doc_weight[ $match->doc ] = 0;
|
||||
}
|
||||
$doc_weight[ $match->doc ] += $match->weight;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $no_matches ) {
|
||||
if ( $search_again ) {
|
||||
// No hits even with partial matching.
|
||||
$search_again = false;
|
||||
} elseif ( 'sometimes' === get_option( 'relevanssi_fuzzy' ) ) {
|
||||
$search_again = true;
|
||||
}
|
||||
} else {
|
||||
$search_again = false;
|
||||
}
|
||||
} while ( $search_again );
|
||||
|
||||
$strip_stopwords = true;
|
||||
$terms_without_stops = array_keys( relevanssi_tokenize( implode( ' ', $terms ), $strip_stopwords, -1, 'search_query' ) );
|
||||
$total_terms = count( $terms_without_stops );
|
||||
|
||||
if ( isset( $doc_weight ) ) {
|
||||
/**
|
||||
* Filters the results Relevanssi finds for one site in multisite
|
||||
* search.
|
||||
*
|
||||
* This is similar to 'relevanssi_results' in single site searching,
|
||||
* but only applies to results fetched from one subsite, the ID of
|
||||
* which can be found in the filter parameters.
|
||||
*
|
||||
* @param array $doc_weight An array of (post ID, weight) pairs.
|
||||
* @param int $blogid The blog ID.
|
||||
*/
|
||||
$doc_weight = apply_filters( 'relevanssi_site_results', $doc_weight, $blogid );
|
||||
}
|
||||
|
||||
if ( isset( $doc_weight ) && count( $doc_weight ) > 0 && ! $no_matches ) {
|
||||
arsort( $doc_weight );
|
||||
$i = 0;
|
||||
foreach ( $doc_weight as $doc => $weight ) {
|
||||
if ( count( $doc_terms[ $doc ] ) < $total_terms && 'AND' === $operator ) {
|
||||
// AND operator in action: $doc didn't match all terms, so it's discarded.
|
||||
continue;
|
||||
}
|
||||
|
||||
$post_object = relevanssi_get_multisite_post( $blogid, $doc );
|
||||
$post_object->blog_id = $blogid;
|
||||
|
||||
$object_id = $blogid . '|' . $doc;
|
||||
$hitsbyweight[ $object_id ] = $weight;
|
||||
$post_objects[ $object_id ] = $post_object;
|
||||
}
|
||||
}
|
||||
restore_current_blog();
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters all results found in the multisite search.
|
||||
*
|
||||
* This is similar to 'relevanssi_results', but is applied to multisite
|
||||
* searches (where 'relevanssi_results' is not used). This filter hook
|
||||
* filters an array of ID => weight pairs, where ID is in the format
|
||||
* '[blog ID]|[post ID]'.
|
||||
*
|
||||
* You can also use 'relevanssi_site_results', which is more like the
|
||||
* original 'relevanssi_results'; it's applied to results from a single
|
||||
* site.
|
||||
*
|
||||
* @param array $hitsbyweight The ID => weight pairs.
|
||||
*/
|
||||
$hitsbyweight = apply_filters( 'relevanssi_multi_results', $hitsbyweight );
|
||||
arsort( $hitsbyweight );
|
||||
|
||||
$i = 0;
|
||||
foreach ( $hitsbyweight as $hit => $weight ) {
|
||||
$hit = $post_objects[ $hit ];
|
||||
$hits[ intval( $i ) ] = $hit;
|
||||
$hits[ intval( $i ) ]->relevance_score = round( $weight, 2 );
|
||||
++$i;
|
||||
}
|
||||
|
||||
if ( count( $hits ) < 1 ) {
|
||||
if ( 'AND' === $operator && 'on' !== get_option( 'relevanssi_disable_or_fallback' ) ) {
|
||||
$or_args = $multi_args;
|
||||
$or_args['operator'] = 'OR';
|
||||
$return = relevanssi_search_multi( $or_args );
|
||||
$hits = $return['hits'];
|
||||
$match_arrays['body'] = $return['body_matches'];
|
||||
$match_arrays['title'] = $return['title_matches'];
|
||||
$match_arrays['tag'] = $return['tag_matches'];
|
||||
$match_arrays['category'] = $return['category_matches'];
|
||||
$match_arrays['taxonomy'] = $return['taxonomy_matches'];
|
||||
$match_arrays['comment'] = $return['comment_matches'];
|
||||
$match_arrays['link'] = $return['link_matches'];
|
||||
$match_arrays['author'] = $return['author_matches'];
|
||||
$match_arrays['customfield'] = $return['customfield_matches'];
|
||||
$match_arrays['mysqlcolumn'] = $return['mysqlcolumn_matches'];
|
||||
$match_arrays['excerpt'] = $return['excerpt_matches'];
|
||||
$term_hits = $return['term_hits'];
|
||||
$query = $return['query'];
|
||||
}
|
||||
}
|
||||
|
||||
relevanssi_sort_results( $hits, $orderby, $order, $meta_query );
|
||||
|
||||
$return = array(
|
||||
'hits' => $hits,
|
||||
'body_matches' => $match_arrays['body'],
|
||||
'title_matches' => $match_arrays['title'],
|
||||
'tag_matches' => $match_arrays['tag'],
|
||||
'category_matches' => $match_arrays['category'],
|
||||
'comment_matches' => $match_arrays['comment'],
|
||||
'taxonomy_matches' => $match_arrays['taxonomy'],
|
||||
'link_matches' => $match_arrays['link'],
|
||||
'customfield_matches' => $match_arrays['customfield'],
|
||||
'mysqlcolumn_matches' => $match_arrays['mysqlcolumn'],
|
||||
'author_matches' => $match_arrays['author'],
|
||||
'excerpt_matches' => $match_arrays['excerpt'],
|
||||
'term_hits' => $term_hits,
|
||||
'query' => $q,
|
||||
'query_no_synonyms' => $q_no_synonyms,
|
||||
);
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects the multisite search arguments from the query variables.
|
||||
*
|
||||
* @param object $query The WP_Query object that contains the parameters.
|
||||
* @param string $searchblogs A list of blogs to search, or 'all'.
|
||||
* @param string $q The search query.
|
||||
*
|
||||
* @return array The multisite search parameters.
|
||||
*/
|
||||
function relevanssi_compile_multi_args( $query, $searchblogs, $q ) {
|
||||
$multi_args = relevanssi_compile_common_args( $query );
|
||||
|
||||
$multi_args['q_no_synonyms'] = $q;
|
||||
$multi_args['q'] = $q;
|
||||
|
||||
if ( isset( $query->query_vars['searchblogs'] ) ) {
|
||||
$multi_args['search_blogs'] = $query->query_vars['searchblogs'];
|
||||
} else {
|
||||
$multi_args['search_blogs'] = $searchblogs;
|
||||
}
|
||||
|
||||
$query->query_vars['operator'] = $multi_args['operator'];
|
||||
|
||||
return $multi_args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks which blogs should be searched.
|
||||
*
|
||||
* @param object $query The WP Query object to check for the
|
||||
* $query->query_vars['searchblogs'] query variable.
|
||||
*
|
||||
* @return boolean|string False, if not a multisite search; list of blogs or
|
||||
* 'all' otherwise.
|
||||
*/
|
||||
function relevanssi_is_multisite_search( $query ) {
|
||||
$searchblogs = false;
|
||||
$search_multisite = false;
|
||||
if ( isset( $query->query_vars['searchblogs'] )
|
||||
&& (string) get_current_blog_id() !== $query->query_vars['searchblogs'] ) {
|
||||
$search_multisite = true;
|
||||
$searchblogs = $query->query_vars['searchblogs'];
|
||||
}
|
||||
|
||||
if ( ! isset( $query->query_vars['searchblogs'] ) && ! $search_multisite ) {
|
||||
// Is searching all blogs enabled?
|
||||
$searchblogs_all = get_option( 'relevanssi_searchblogs_all', 'off' );
|
||||
if ( 'off' === $searchblogs_all ) {
|
||||
$searchblogs_all = false;
|
||||
}
|
||||
if ( $searchblogs_all ) {
|
||||
$search_multisite = true;
|
||||
$searchblogs = 'all';
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! isset( $query->query_vars['searchblogs'] ) && ! $search_multisite ) {
|
||||
// Searchblogs is not set from the query variables, check the option.
|
||||
$searchblogs_setting = get_option( 'relevanssi_searchblogs' );
|
||||
if ( $searchblogs_setting ) {
|
||||
$search_multisite = true;
|
||||
$searchblogs = $searchblogs_setting;
|
||||
}
|
||||
}
|
||||
return $searchblogs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a blog is good to use.
|
||||
*
|
||||
* Blog must exist, it has to be public and not archived, spam or deleted. The
|
||||
* filter hook `relevanssi_multisite_public_status` can be used to allow
|
||||
* Relevanssi to search non-public blogs.
|
||||
*
|
||||
* @param int $blogid The blog ID.
|
||||
*
|
||||
* @return bool True, if blog is public.
|
||||
*/
|
||||
function relevanssi_is_blog_ok( $blogid ): bool {
|
||||
// Only search blogs that are publicly available (unless filter says otherwise).
|
||||
$public_status = (bool) get_blog_status( $blogid, 'public' );
|
||||
if ( null === $public_status ) {
|
||||
// Blog doesn't actually exist.
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the possible values of blog public status.
|
||||
*
|
||||
* By default Relevanssi requires blogs to be public so they can be searched.
|
||||
* If you want a non-public blog in the search results, make this filter
|
||||
* return true.
|
||||
*
|
||||
* @param boolean $public_status Is the blog public?
|
||||
* @param int $blogid Blog ID.
|
||||
*/
|
||||
if ( false === apply_filters( 'relevanssi_multisite_public_status', $public_status, $blogid ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't search blogs that are marked "archived", "spam" or "deleted".
|
||||
if ( get_blog_status( $blogid, 'archived' ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( get_blog_status( $blogid, 'spam' ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( get_blog_status( $blogid, 'delete' ) ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the arguments to create the query restrictions for multisite
|
||||
* searches.
|
||||
*
|
||||
* All individual parts are tested.
|
||||
*
|
||||
* @param array $args The query arguments.
|
||||
*
|
||||
* @return array An array containing `query_restriction` and `query_join`.
|
||||
*/
|
||||
function relevanssi_process_multi_query_args( $args ) {
|
||||
$query_restrictions = '';
|
||||
$query_join = '';
|
||||
$query = '';
|
||||
$query_no_synonyms = '';
|
||||
|
||||
$phrase_query_restrictions = array(
|
||||
'and' => '',
|
||||
'or' => array(),
|
||||
);
|
||||
|
||||
if ( function_exists( 'wp_encode_emoji' ) ) {
|
||||
$query = wp_encode_emoji( $args['q'] );
|
||||
$query_no_synonyms = wp_encode_emoji( $args['q_no_synonyms'] );
|
||||
}
|
||||
|
||||
if ( $args['sentence'] ) {
|
||||
$query = relevanssi_remove_quotes( $query );
|
||||
$query = '"' . $query . '"';
|
||||
}
|
||||
|
||||
if ( is_array( $args['meta_query'] ) ) {
|
||||
$processed_meta = relevanssi_process_meta_query( $args['meta_query'] );
|
||||
$query_restrictions .= $processed_meta['where'];
|
||||
$query_join .= $processed_meta['join'];
|
||||
}
|
||||
|
||||
if ( $args['date_query'] instanceof WP_Date_Query ) {
|
||||
$query_restrictions .= relevanssi_process_date_query( $args['date_query'] );
|
||||
}
|
||||
|
||||
if ( $args['by_date'] ) {
|
||||
$query_restrictions .= relevanssi_process_by_date( $args['by_date'] );
|
||||
}
|
||||
|
||||
$phrases = relevanssi_recognize_phrases( $query, $args['operator'] );
|
||||
if ( $phrases ) {
|
||||
$phrase_query_restrictions = $phrases;
|
||||
}
|
||||
|
||||
$query_restrictions .= relevanssi_process_post_type(
|
||||
$args['post_type'],
|
||||
$args['admin_search'],
|
||||
$args['include_attachments']
|
||||
);
|
||||
|
||||
if ( $args['post_status'] ) {
|
||||
$query_restrictions .= relevanssi_process_post_status( $args['post_status'] );
|
||||
}
|
||||
|
||||
return array(
|
||||
'query_restrictions' => $query_restrictions,
|
||||
'query_join' => $query_join,
|
||||
'query_query' => $query,
|
||||
'query_no_synonyms' => $query_no_synonyms,
|
||||
'phrase_queries' => $phrase_query_restrictions,
|
||||
);
|
||||
}
|
||||
@@ -1,244 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* /premium/search.php
|
||||
*
|
||||
* @package Relevanssi_Premium
|
||||
* @author Mikko Saari
|
||||
* @license https://wordpress.org/about/gpl/ GNU General Public License
|
||||
* @see https://www.relevanssi.com/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Recognizes negative search terms.
|
||||
*
|
||||
* Finds all the search terms that begin with a -.
|
||||
*
|
||||
* @param string $q Search query.
|
||||
*
|
||||
* @return array $negative_terms Array of negative search terms.
|
||||
*/
|
||||
function relevanssi_recognize_negatives( $q ) {
|
||||
$term = strtok( $q, ' ' );
|
||||
$negative_terms = array();
|
||||
while ( false !== $term ) {
|
||||
if ( '-' === substr( $term, 0, 1 ) ) {
|
||||
array_push( $negative_terms, substr( $term, 1 ) );
|
||||
}
|
||||
$term = strtok( ' ' );
|
||||
}
|
||||
return $negative_terms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recognizes positive search terms.
|
||||
*
|
||||
* Finds all the search terms that begin with a +.
|
||||
*
|
||||
* @param string $q Search query.
|
||||
*
|
||||
* @return array $positive_terms Array of positive search terms.
|
||||
*/
|
||||
function relevanssi_recognize_positives( $q ) {
|
||||
$term = strtok( $q, ' ' );
|
||||
$positive_terms = array();
|
||||
while ( false !== $term ) {
|
||||
if ( '+' === substr( $term, 0, 1 ) ) {
|
||||
$term_part = substr( $term, 1 );
|
||||
if ( ! empty( $term_part ) ) { // To avoid problems with just plus signs.
|
||||
array_push( $positive_terms, $term_part );
|
||||
}
|
||||
}
|
||||
$term = strtok( ' ' );
|
||||
}
|
||||
return $positive_terms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates SQL code for positive and negative terms.
|
||||
*
|
||||
* Creates the necessary SQL code for positive (AND) and negative (NOT) search terms.
|
||||
*
|
||||
* @param array $negative_terms Negative terms.
|
||||
* @param array $positive_terms Positive terms.
|
||||
*
|
||||
* @return string $query_restrictions MySQL code for the terms.
|
||||
*/
|
||||
function relevanssi_negatives_positives( $negative_terms, $positive_terms ) {
|
||||
global $relevanssi_variables;
|
||||
$relevanssi_table = $relevanssi_variables['relevanssi_table'];
|
||||
|
||||
$query_restrictions = '';
|
||||
if ( $negative_terms ) {
|
||||
$size = count( $negative_terms );
|
||||
for ( $i = 0; $i < $size; $i++ ) {
|
||||
$negative_terms[ $i ] = "'" . esc_sql( $negative_terms[ $i ] ) . "'";
|
||||
}
|
||||
$negatives = implode( ',', $negative_terms );
|
||||
$query_restrictions .= " AND doc NOT IN (SELECT DISTINCT(doc) FROM $relevanssi_table WHERE term IN ( $negatives))";
|
||||
// Clean: $negatives is escaped.
|
||||
}
|
||||
|
||||
if ( $positive_terms ) {
|
||||
$size = count( $positive_terms );
|
||||
for ( $i = 0; $i < $size; $i++ ) {
|
||||
$positive_term = esc_sql( $positive_terms[ $i ] );
|
||||
$query_restrictions .= " AND doc IN (SELECT DISTINCT(doc) FROM $relevanssi_table WHERE term = '$positive_term')";
|
||||
// Clean: $positive_term is escaped.
|
||||
}
|
||||
}
|
||||
return $query_restrictions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the recency bonus option.
|
||||
*
|
||||
* Gets the recency bonus and converts the cutoff day count to time().
|
||||
*
|
||||
* @return array $recency_bonus Array( recency bonus, cutoff date ).
|
||||
*/
|
||||
function relevanssi_get_recency_bonus() {
|
||||
$recency_bonus_option = get_option( 'relevanssi_recency_bonus' );
|
||||
$recency_bonus = false;
|
||||
$recency_cutoff_date = false;
|
||||
|
||||
if ( isset( $recency_bonus_option['bonus'] ) ) {
|
||||
$recency_bonus = floatval( $recency_bonus_option['bonus'] );
|
||||
}
|
||||
if ( $recency_bonus && isset( $recency_bonus_option['days'] ) ) {
|
||||
$recency_cutoff_date = time() - DAY_IN_SECONDS * $recency_bonus_option['days'];
|
||||
}
|
||||
|
||||
return array(
|
||||
'bonus' => $recency_bonus,
|
||||
'cutoff' => $recency_cutoff_date,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Introduces the query variables for Relevanssi Premium.
|
||||
*
|
||||
* @param array $qv The WordPress query variable array.
|
||||
*/
|
||||
function relevanssi_premium_query_vars( $qv ) {
|
||||
$qv[] = 'searchblogs';
|
||||
$qv[] = 'customfield_key';
|
||||
$qv[] = 'customfield_value';
|
||||
$qv[] = 'operator';
|
||||
$qv[] = 'include_attachments';
|
||||
$qv[] = 'coordinates';
|
||||
return $qv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the operator parameter.
|
||||
*
|
||||
* The operator parameter is taken from $query->query_vars['operator'],
|
||||
* or from the implicit operator setting.
|
||||
*
|
||||
* @param object $query The query object.
|
||||
*/
|
||||
function relevanssi_set_operator( $query ) {
|
||||
if ( isset( $query->query_vars['operator'] ) ) {
|
||||
$operator = $query->query_vars['operator'];
|
||||
} else {
|
||||
$operator = get_option( 'relevanssi_implicit_operator' );
|
||||
}
|
||||
return $operator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the negative and positive terms (ie. local AND and NOT operators).
|
||||
*
|
||||
* If negative terms are present, will remove them from the $terms array. If negative
|
||||
* or positive terms are present, will return the query restrictions MySQL for them.
|
||||
*
|
||||
* @param array $terms An array of search terms.
|
||||
* @param array $original_terms An array of unstemmed search terms.
|
||||
* @param string $query The search query as a string.
|
||||
*
|
||||
* @return array An array containing the updated terms and the query restrictions.
|
||||
*/
|
||||
function relevanssi_process_terms( $terms, $original_terms, $query ) {
|
||||
$negative_terms = relevanssi_recognize_negatives( $query );
|
||||
$positive_terms = relevanssi_recognize_positives( $query );
|
||||
|
||||
if ( $negative_terms ) {
|
||||
$terms = array_diff( $terms, $negative_terms );
|
||||
$original_terms = array_diff( $original_terms, $negative_terms );
|
||||
}
|
||||
|
||||
// Clean: escaped in the function.
|
||||
$query_restrictions = relevanssi_negatives_positives( $negative_terms, $positive_terms );
|
||||
|
||||
return array(
|
||||
'terms' => $terms,
|
||||
'original_terms' => $original_terms,
|
||||
'query_restrictions' => $query_restrictions,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the wildcards (?, *) with strings to let them pass intact.
|
||||
*
|
||||
* The wildcards are only allowed inside words, so they must have a word
|
||||
* character on both sides of them.
|
||||
*
|
||||
* @param string $str The query or content string to modify.
|
||||
*
|
||||
* @return string The parameter string modified.
|
||||
*/
|
||||
function relevanssi_wildcards_pre( $str ) {
|
||||
/**
|
||||
* If true, enables wildcard operators (*, ?).
|
||||
*
|
||||
* @param boolean If true, enable wildcard operator. Default false.
|
||||
*/
|
||||
if ( apply_filters( 'relevanssi_wildcard_search', false ) ) {
|
||||
$str = preg_replace( '/(\w)\?(\w)/', '\1SINGLEWILDCARDSYMBOL\2', $str );
|
||||
$str = preg_replace( '/(\w)\*(\w)/', '\1MULTIWILDCARDSYMBOL\2', $str );
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the wildcard strings with wildcards (?, *).
|
||||
*
|
||||
* @param string $str The query or content string to modify.
|
||||
*
|
||||
* @return string The parameter string modified.
|
||||
*/
|
||||
function relevanssi_wildcards_post( $str ) {
|
||||
/**
|
||||
* Documented in /premium/search.php.
|
||||
*/
|
||||
if ( apply_filters( 'relevanssi_wildcard_search', false ) ) {
|
||||
$str = preg_replace( '/SINGLEWILDCARDSYMBOL/', '?', $str );
|
||||
$str = preg_replace( '/MULTIWILDCARDSYMBOL/', '*', $str );
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the wildcards (?, *) with their MySQL equivalents (_, %).
|
||||
*
|
||||
* The ? is converted to _ (single character), while * is converted to %
|
||||
* (zero or more). Hooks to the relevanssi_term_where filter hook to only
|
||||
* apply this to the term WHERE condition part of the query.
|
||||
*
|
||||
* @see relevanssi_term_where
|
||||
*
|
||||
* @param string $query MySQL query to modify.
|
||||
* @param string $term The search term.
|
||||
*
|
||||
* @return string The modified MySQL query.
|
||||
*/
|
||||
function relevanssi_query_wildcards( $query, $term ) {
|
||||
/**
|
||||
* Documented in /premium/search.php.
|
||||
*/
|
||||
if ( apply_filters( 'relevanssi_wildcard_search', false ) ) {
|
||||
$query = str_replace( "= '$term'", "LIKE '$term'", $query );
|
||||
$query = str_replace( array( '?', '*' ), array( '_', '%' ), $query );
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* /premium/spamblock.php
|
||||
*
|
||||
* @package Relevanssi_Premium
|
||||
* @author Mikko Saari
|
||||
* @license https://wordpress.org/about/gpl/ GNU General Public License
|
||||
* @see https://www.relevanssi.com/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Runs on plugins_loaded and stops spam search requests based on keywords.
|
||||
*/
|
||||
function relevanssi_spamblock() {
|
||||
$is_highlight_match = false;
|
||||
if ( isset( $_REQUEST['s'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$query = $_REQUEST['s']; // phpcs:ignore WordPress.Security.NonceVerification
|
||||
} elseif ( isset( $_REQUEST['highlight'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$query = $_REQUEST['highlight']; // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$is_highlight_match = true;
|
||||
} else {
|
||||
/**
|
||||
* Filters the search URL prefix for spam blocking.
|
||||
*
|
||||
* If the search query is not found in $_REQUEST['s'], the spam block
|
||||
* looks for it in $_SERVER['REQUEST_URI'], in case pretty URLs are
|
||||
* used. Relevanssi assumes the pretty URL prefix is /search/, but in
|
||||
* case it's something else, you can adjust that with this filter.
|
||||
*
|
||||
* @param string The search URL prefix, default '/search/'.
|
||||
*/
|
||||
$url_prefix = apply_filters( 'relevanssi_search_url_prefix', '/search/' );
|
||||
if ( substr( $_SERVER['REQUEST_URI'], '0', strlen( $url_prefix ) ) === $url_prefix ) {
|
||||
$query = urldecode( str_replace( $url_prefix, '', $_SERVER['REQUEST_URI'] ) );
|
||||
}
|
||||
}
|
||||
if ( ! isset( $query ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$settings = get_option( 'relevanssi_spamblock', array() );
|
||||
$keywords = $settings['keywords'] ?? '';
|
||||
$regex = $settings['regex'] ?? '';
|
||||
$chinese = $settings['chinese'] ?? 'off';
|
||||
$cyrillic = $settings['cyrillic'] ?? 'off';
|
||||
$emoji = $settings['emoji'] ?? 'off';
|
||||
$bots = $settings['bots'] ?? 'off';
|
||||
|
||||
if ( 'on' === $chinese && relevanssi_string_contains_chinese( $query ) ) {
|
||||
http_response_code( 410 );
|
||||
exit();
|
||||
}
|
||||
|
||||
if ( 'on' === $cyrillic && relevanssi_string_contains_cyrillic( $query ) ) {
|
||||
http_response_code( 410 );
|
||||
exit();
|
||||
}
|
||||
|
||||
if ( 'on' === $emoji && relevanssi_string_contains_emoji( $query ) ) {
|
||||
http_response_code( 410 );
|
||||
exit();
|
||||
}
|
||||
|
||||
if ( 'on' === $bots && ! $is_highlight_match && relevanssi_user_agent_is_bot() ) {
|
||||
http_response_code( 410 );
|
||||
exit();
|
||||
}
|
||||
|
||||
foreach ( explode( "\n", $keywords ) as $keyword ) {
|
||||
$keyword = trim( $keyword );
|
||||
if ( empty( $keyword ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( false !== relevanssi_stripos( $query, $keyword ) ) {
|
||||
http_response_code( 410 );
|
||||
exit();
|
||||
}
|
||||
}
|
||||
foreach ( explode( "\n", $regex ) as $pattern ) {
|
||||
$pattern = trim( $pattern );
|
||||
if ( empty( $pattern ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( 1 === preg_match( '/' . $pattern . '/ui', $query ) ) {
|
||||
http_response_code( 410 );
|
||||
exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a string contains Chinese characters.
|
||||
*
|
||||
* @param string $text The text to check.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
function relevanssi_string_contains_chinese( string $text ): bool {
|
||||
return (bool) preg_match( '/\p{Han}/u', $text );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a string contains Cyrillic characters. Uses {Cyr} to check.
|
||||
*
|
||||
* @param string $text The text to check.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
function relevanssi_string_contains_cyrillic( string $text ): bool {
|
||||
return (bool) preg_match( '/\p{Cyrillic}/u', $text );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a string contains emoji characters.
|
||||
*
|
||||
* @param string $text The text to check.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
function relevanssi_string_contains_emoji( string $text ): bool {
|
||||
$emoji = array(
|
||||
'/[\x{1F1E6}-\x{1F1FF}]/u', // Flags.
|
||||
'/[\x{1F300}-\x{1F5FF}]/u', // Misc and pictographs.
|
||||
'/[\x{1F600}-\x{1F64F}]/u', // Emoticons.
|
||||
'/[\x{1F680}-\x{1F6FF}]/u', // Transport and maps.
|
||||
'/[\x{1F700}-\x{1F9FF}]/u', // Hotel and misc.
|
||||
'/[\x{2300}-\x{23FF}]/u', // Time.
|
||||
'/[\x{2600}-\x{26FF}]/u', // Miscellaneous.
|
||||
'/[\x{2700}-\x{27BF}]/u', // Dingbats.
|
||||
);
|
||||
|
||||
foreach ( $emoji as $pattern ) {
|
||||
if ( preg_match( $pattern, $text ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -1,197 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* /premium/tabs/attachments-tab.php
|
||||
*
|
||||
* Prints out the Premium Attachments tab in Relevanssi settings.
|
||||
*
|
||||
* @package Relevanssi_Premium
|
||||
* @author Mikko Saari
|
||||
* @license https://wordpress.org/about/gpl/ GNU General Public License
|
||||
* @see https://www.relevanssi.com/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Prints out the Premium attachments tab in Relevanssi settings.
|
||||
*/
|
||||
function relevanssi_attachments_tab() {
|
||||
$index_post_types = get_option( 'relevanssi_index_post_types', array() );
|
||||
$index_pdf_parent = get_option( 'relevanssi_index_pdf_parent' );
|
||||
|
||||
global $wpdb;
|
||||
$read_new_files = '';
|
||||
$send_pdf_files = '';
|
||||
$link_pdf_files = '';
|
||||
$us_selected = '';
|
||||
$eu_selected = '';
|
||||
|
||||
if ( 'on' === get_option( 'relevanssi_read_new_files' ) ) {
|
||||
$read_new_files = 'checked';
|
||||
}
|
||||
if ( 'on' === get_option( 'relevanssi_send_pdf_files' ) ) {
|
||||
$send_pdf_files = 'checked';
|
||||
}
|
||||
if ( 'on' === get_option( 'relevanssi_link_pdf_files' ) ) {
|
||||
$link_pdf_files = 'checked';
|
||||
}
|
||||
if ( 'us' === get_option( 'relevanssi_server_location' ) ) {
|
||||
$us_selected = 'selected';
|
||||
}
|
||||
if ( 'eu' === get_option( 'relevanssi_server_location' ) ) {
|
||||
$eu_selected = 'selected';
|
||||
}
|
||||
|
||||
$indexing_attachments = false;
|
||||
if ( in_array( 'attachment', $index_post_types, true ) ) {
|
||||
$indexing_attachments = true;
|
||||
}
|
||||
|
||||
?>
|
||||
<div id="attachments_tab">
|
||||
<table class="form-table" role="presentation">
|
||||
<tr>
|
||||
<td>
|
||||
<input type='button' id='index' value='<?php esc_html_e( 'Read all unread attachments', 'relevanssi' ); ?>' class='button-primary' /><br /><br />
|
||||
</td>
|
||||
<td>
|
||||
<p class="description" id="indexing_button_instructions">
|
||||
<?php /* translators: the placeholder has the name of the custom field for PDF content */ ?>
|
||||
<?php printf( esc_html__( 'Clicking the button will read the contents of all the unread attachments files and store the contents to the %s custom field for future indexing. Attachments with errors will be skipped, except for the files with timeout and connection related errors: those will be attempted again.', 'relevanssi' ), '<code>_relevanssi_pdf_content</code>' ); ?>
|
||||
</p>
|
||||
<div id='relevanssi-note' style='display: none'></div>
|
||||
<div id='relevanssi-progress' class='rpi-progress'><div></div></div>
|
||||
<div id='relevanssi-timer'><?php esc_html_e( 'Time elapsed', 'relevanssi' ); ?>: <span id="relevanssi_elapsed">0:00:00</span> | <?php esc_html_e( 'Time remaining', 'relevanssi' ); ?>: <span id="relevanssi_estimated"><?php esc_html_e( 'some time', 'relevanssi' ); ?></span></div>
|
||||
<label for="relevanssi_results" class="screen-reader-text"><?php esc_html_e( 'Results', 'relevanssi' ); ?></label>
|
||||
<textarea id='relevanssi_results' rows='10' cols='80'></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'State of the attachments', 'relevanssi' ); ?></td>
|
||||
<?php
|
||||
$pdf_count = wp_cache_get( 'relevanssi_pdf_count' );
|
||||
if ( false === $pdf_count ) {
|
||||
$pdf_count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_pdf_content' AND meta_value != ''" );
|
||||
wp_cache_set( 'relevanssi_pdf_count', $pdf_count );
|
||||
|
||||
}
|
||||
$pdf_error_count = wp_cache_get( 'relevanssi_pdf_error_count' );
|
||||
if ( false === $pdf_error_count ) {
|
||||
$pdf_error_count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_pdf_error' AND meta_value != ''" );
|
||||
wp_cache_set( 'relevanssi_pdf_error_count', $pdf_error_count );
|
||||
}
|
||||
?>
|
||||
<td id="stateofthepdfindex">
|
||||
<p><?php echo esc_html( $pdf_count ); ?> <?php echo esc_html( _n( 'document has read attachment content.', 'documents have read attachment content.', $pdf_count, 'relevanssi' ) ); ?></p>
|
||||
<p><?php echo esc_html( $pdf_error_count ); ?> <?php echo esc_html( _n( 'document has an attachment reading error.', 'documents have attachment reading errors.', $pdf_error_count, 'relevanssi' ) ); ?>
|
||||
<?php if ( $pdf_error_count > 0 ) : ?>
|
||||
<span id="relevanssi_show_pdf_errors"><?php esc_html_e( 'Show errors', 'relevanssi' ); ?></span>.
|
||||
<?php endif; ?></p>
|
||||
<label for="relevanssi_pdf_errors" class="screen-reader-text"><?php esc_html_e( 'Attachment reading errors', 'relevanssi' ); ?></label>
|
||||
<textarea id="relevanssi_pdf_errors" rows="4" cols="120"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="relevanssi_server_location"><?php esc_html_e( 'Server location', 'relevanssi' ); ?></label></th>
|
||||
<td>
|
||||
<select name="relevanssi_server_location" id="relevanssi_server_location">
|
||||
<option value="us" <?php echo esc_html( $us_selected ); ?>><?php esc_html_e( 'United States', 'relevanssi' ); ?></option>
|
||||
<option value="eu" <?php echo esc_html( $eu_selected ); ?>><?php esc_html_e( 'European Union', 'relevanssi' ); ?></option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Reset attachment content', 'relevanssi' ); ?></td>
|
||||
<td>
|
||||
<input type="button" id="reset" value="<?php esc_html_e( 'Reset all attachment data from posts', 'relevanssi' ); ?>" class="button-primary" />
|
||||
<?php /* translators: the placeholders are the names of the custom fields */ ?>
|
||||
<p class="description"><?php printf( esc_html__( "This will remove all %1\$s and %2\$s custom fields from all posts. If you want to reread all attachment files, use this to clean up; clicking the reading button doesn't wipe the slate clean like it does in regular indexing.", 'relevanssi' ), '<code>_relevanssi_pdf_content</code>', '<code>_relevanssi_pdf_error</code>' ); ?></p>
|
||||
<p class="description"><?php esc_html_e( 'If you have posts where you have modified the attachment content after reading it, this will leave those posts untouched.', 'relevanssi' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Clear server errors', 'relevanssi' ); ?></td>
|
||||
<td>
|
||||
<input type="button" id="clearservererrors" value="<?php esc_html_e( 'Clear server errors', 'relevanssi' ); ?>" class="button-primary" />
|
||||
<p class="description"><?php esc_html_e( "This will clear all 'Server did not respond' errors from the posts, so you can try reading those files again.", 'relevanssi' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<?php esc_html_e( 'Read new files', 'relevanssi' ); ?>
|
||||
</th>
|
||||
<td>
|
||||
<fieldset>
|
||||
<legend class="screen-reader-text"><?php esc_html_e( 'Read new files automatically', 'relevanssi' ); ?></legend>
|
||||
<label for='relevanssi_read_new_files'>
|
||||
<input type='checkbox' name='relevanssi_read_new_files' id='relevanssi_read_new_files' <?php echo esc_attr( $read_new_files ); ?> />
|
||||
<?php esc_html_e( 'Read new files automatically', 'relevanssi' ); ?>
|
||||
</label>
|
||||
<p class="description"><?php esc_html_e( 'If this option is enabled, Relevanssi will automatically read the contents of new attachments as they are uploaded. This may cause unexpected delays in uploading posts. If this is not enabled, new attachments are not read automatically and need to be manually read and reindexed.', 'relevanssi' ); ?></p>
|
||||
</fieldset>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<?php esc_html_e( 'Upload files', 'relevanssi' ); ?>
|
||||
</th>
|
||||
<td>
|
||||
<fieldset>
|
||||
<legend class="screen-reader-text"><?php esc_html_e( 'Upload files for reading', 'relevanssi' ); ?></legend>
|
||||
<label for='relevanssi_send_pdf_files'>
|
||||
<input type='checkbox' name='relevanssi_send_pdf_files' id='relevanssi_send_pdf_files' <?php echo esc_attr( $send_pdf_files ); ?> />
|
||||
<?php esc_html_e( 'Upload files for reading', 'relevanssi' ); ?>
|
||||
</label>
|
||||
<p class="description"><?php esc_html_e( "By default, Relevanssi only sends a link to the attachment to the attachment reader. If your files are not accessible (for example your site is inside an intranet, password protected, or a local dev site, and the files can't be downloaded if given the URL of the file), check this option to upload the whole file to the reader.", 'relevanssi' ); ?></p>
|
||||
</fieldset>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<?php esc_html_e( 'Link to files', 'relevanssi' ); ?>
|
||||
</th>
|
||||
<td>
|
||||
<fieldset>
|
||||
<legend class="screen-reader-text"><?php esc_html_e( 'Link search results directly to the files', 'relevanssi' ); ?></legend>
|
||||
<label for='relevanssi_link_pdf_files'>
|
||||
<input type='checkbox' name='relevanssi_link_pdf_files' id='relevanssi_link_pdf_files' <?php echo esc_attr( $link_pdf_files ); ?> />
|
||||
<?php esc_html_e( 'Link search results directly to the files', 'relevanssi' ); ?>
|
||||
</label>
|
||||
<p class="description"><?php esc_html_e( 'If this option is checked, attachment results in search results will link directly to the file. Otherwise the results will link to the attachment page.', 'relevanssi' ); ?></p>
|
||||
<?php if ( ! $indexing_attachments ) : ?>
|
||||
<?php /* translators: the placeholder has name of the post type */ ?>
|
||||
<p class="important description"><?php printf( esc_html__( "You're not indexing the %s post type, so this setting doesn't have any effect.", 'relevanssi' ), '<code>attachment</code>' ); ?>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! $indexing_attachments && ! $index_pdf_parent ) : ?>
|
||||
<?php /* translators: the placeholder has name of the post type */ ?>
|
||||
<p class="important description"><?php printf( esc_html__( "You're not indexing the %s post type and haven't connected the files to the parent posts in the indexing settings. You won't be seeing any files in the results.", 'relevanssi' ), '<code>attachment</code>' ); ?>
|
||||
<?php endif; ?>
|
||||
</fieldset>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Instructions', 'relevanssi' ); ?></th>
|
||||
<td>
|
||||
<?php /* translators: placeholder has the name of the custom field */ ?>
|
||||
<p><?php printf( esc_html__( 'When Relevanssi reads attachment content, the text is extracted and saved in the %s custom field for the attachment post. This alone does not add the attachment content in the Relevanssi index; it just makes the contents of the attachments easily available for the regular Relevanssi indexing process.', 'relevanssi' ), '<code>_relevanssi_pdf_content</code>' ); ?></p>
|
||||
<?php /* translators: placeholder has the name of the post type */ ?>
|
||||
<p><?php printf( esc_html__( 'There are two ways to index the attachment content. If you choose to index the %s post type, Relevanssi will show the attachment posts in the results.', 'relevanssi' ), '<code>attachment</code>' ); ?></p>
|
||||
<p><?php esc_html_e( "You can also choose to index the attachment content for the parent post, in which case Relevanssi will show the parent post in the results (this setting can be found on the indexing settings). Obviously this does not find the content in attachments that are not attached to another post – if you just upload a file to the WordPress Media Library, it is not attached and won't be found unless you index the attachment posts.", 'relevanssi' ); ?></p>
|
||||
<p><?php esc_html_e( "If you need to reread a file, you can do read individual files from Media Library. Choose an attachment and click 'Edit more details' to read the content.", 'relevanssi' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Key not valid?', 'relevanssi' ); ?></th>
|
||||
<td>
|
||||
<p><?php esc_html_e( "Are you a new Relevanssi customer and seeing 'Key xxxxxx is not valid' error messages? New API keys are delivered to the server once per hour, so if try again an hour later, the key should work.", 'relevanssi' ); ?></p>
|
||||
<p><?php esc_html_e( "A 'Key 0 is not valid' error message means you're on a multisite, but have only entered the API key in the subsite settings. Set the API key in the network settings to fix that.", 'relevanssi' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Important!', 'relevanssi' ); ?></th>
|
||||
<td>
|
||||
<p><?php esc_html_e( "In order to read the contents of the files, the files are sent over to Relevanssiservices.com, a processing service hosted on a Digital Ocean Droplet. There are two servers: one in the US and another in the EU. The service creates a working copy of the files. The copy is removed after the file has been processed, but there are no guarantees that someone with an access to the server couldn't see the files. Do not read files with confidential information in them. In order to block individual files from reading, use the Relevanssi post controls on attachment edit page to exclude attachment posts from indexing.", 'relevanssi' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
@@ -1,168 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* /premium/tabs/import-export-tab.php
|
||||
*
|
||||
* Prints out the Premium import/export tab in Relevanssi settings.
|
||||
*
|
||||
* @package Relevanssi_Premium
|
||||
* @author Mikko Saari
|
||||
* @license https://wordpress.org/about/gpl/ GNU General Public License
|
||||
* @see https://www.relevanssi.com/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Prints out the Premium import/export tab in Relevanssi settings.
|
||||
*/
|
||||
function relevanssi_import_export_tab() {
|
||||
$serialized_options = relevanssi_serialize_options();
|
||||
?>
|
||||
<h2 id="options"><?php esc_html_e( 'Import or export options', 'relevanssi' ); ?></h2>
|
||||
|
||||
<p><?php esc_html_e( 'Here you find the current Relevanssi Premium options in a text format. Copy the contents of the text field to make a backup of your settings. You can also paste new settings here to change all settings at the same time. This is useful if you have default settings you want to use on every system.', 'relevanssi' ); ?></p>
|
||||
|
||||
<table class="form-table" role="presentation">
|
||||
<tr>
|
||||
<th scope="row"><label for="relevanssi_settings"><?php esc_html_e( 'Current Settings', 'relevanssi' ); ?></label></th>
|
||||
<td>
|
||||
<p>
|
||||
<textarea
|
||||
id='relevanssi_settings'
|
||||
name='relevanssi_settings'
|
||||
rows='4'
|
||||
cols='80'><?php echo esc_html( $serialized_options ); ?></textarea>
|
||||
</p>
|
||||
|
||||
<input
|
||||
type='submit'
|
||||
name='import_options'
|
||||
id='import_options'
|
||||
value='<?php esc_html_e( 'Import settings', 'relevanssi' ); ?>'
|
||||
class='button'
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p><?php esc_html_e( "Note! Make sure you've got correct settings from a right version of Relevanssi. Settings from a different version of Relevanssi may or may not work and may or may not mess your settings.", 'relevanssi' ); ?></p>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects all Relevanssi options to one array and JSON encodes it.
|
||||
*
|
||||
* @return string An array of Relevanssi options converted to JSON.
|
||||
*/
|
||||
function relevanssi_serialize_options() {
|
||||
$serialize_options = array();
|
||||
|
||||
$bg_col = get_option( 'relevanssi_bg_col' );
|
||||
$txt_col = get_option( 'relevanssi_txt_col' );
|
||||
$index_taxonomies_list = get_option( 'relevanssi_index_taxonomies_list' );
|
||||
$index_terms = get_option( 'relevanssi_index_terms' );
|
||||
|
||||
$txt_col = relevanssi_sanitize_hex_color( $txt_col );
|
||||
$bg_col = relevanssi_sanitize_hex_color( $bg_col );
|
||||
|
||||
if ( empty( $index_post_types ) ) {
|
||||
$index_post_types = array();
|
||||
}
|
||||
if ( empty( $index_taxonomies_list ) ) {
|
||||
$index_taxonomies_list = array();
|
||||
}
|
||||
if ( empty( $index_terms ) ) {
|
||||
$index_terms = array();
|
||||
}
|
||||
|
||||
$serialize_options['relevanssi_admin_search'] = get_option( 'relevanssi_admin_search' );
|
||||
$serialize_options['relevanssi_api_key'] = get_option( 'relevanssi_api_key' );
|
||||
$serialize_options['relevanssi_bg_col'] = $bg_col;
|
||||
$serialize_options['relevanssi_body_stopwords'] = get_option( 'relevanssi_body_stopwords' );
|
||||
$serialize_options['relevanssi_cat'] = get_option( 'relevanssi_cat' );
|
||||
$serialize_options['relevanssi_class'] = get_option( 'relevanssi_class' );
|
||||
$serialize_options['relevanssi_comment_boost'] = get_option( 'relevanssi_comment_boost' );
|
||||
$serialize_options['relevanssi_content_boost'] = get_option( 'relevanssi_content_boost' );
|
||||
$serialize_options['relevanssi_css'] = get_option( 'relevanssi_css' );
|
||||
$serialize_options['relevanssi_db_version'] = get_option( 'relevanssi_db_version' );
|
||||
$serialize_options['relevanssi_default_orderby'] = get_option( 'relevanssi_default_orderby' );
|
||||
$serialize_options['relevanssi_disable_or_fallback'] = get_option( 'relevanssi_disable_or_fallback' );
|
||||
$serialize_options['relevanssi_disable_shortcodes'] = get_option( 'relevanssi_disable_shortcodes' );
|
||||
$serialize_options['relevanssi_do_not_call_home'] = get_option( 'relevanssi_do_not_call_home' );
|
||||
$serialize_options['relevanssi_exact_match_bonus'] = get_option( 'relevanssi_exact_match_bonus' );
|
||||
$serialize_options['relevanssi_excat'] = get_option( 'relevanssi_excat' );
|
||||
$serialize_options['relevanssi_excerpt_allowable_tags'] = get_option( 'relevanssi_excerpt_allowable_tags' );
|
||||
$serialize_options['relevanssi_excerpt_custom_fields'] = get_option( 'relevanssi_excerpt_custom_fields' );
|
||||
$serialize_options['relevanssi_excerpt_length'] = get_option( 'relevanssi_excerpt_length' );
|
||||
$serialize_options['relevanssi_excerpt_specific_fields'] = get_option( 'relevanssi_excerpt_specific_fields' );
|
||||
$serialize_options['relevanssi_excerpt_type'] = get_option( 'relevanssi_excerpt_type' );
|
||||
$serialize_options['relevanssi_excerpts'] = get_option( 'relevanssi_excerpts' );
|
||||
$serialize_options['relevanssi_exclude_posts'] = get_option( 'relevanssi_exclude_posts' );
|
||||
$serialize_options['relevanssi_expand_highlights'] = get_option( 'relevanssi_expand_highlights' );
|
||||
$serialize_options['relevanssi_expand_shortcodes'] = get_option( 'relevanssi_expand_shortcodes' );
|
||||
$serialize_options['relevanssi_extag'] = get_option( 'relevanssi_extag' );
|
||||
$serialize_options['relevanssi_fuzzy'] = get_option( 'relevanssi_fuzzy' );
|
||||
$serialize_options['relevanssi_hide_branding'] = get_option( 'relevanssi_hide_branding' );
|
||||
$serialize_options['relevanssi_hide_post_controls'] = get_option( 'relevanssi_hide_post_controls' );
|
||||
$serialize_options['relevanssi_highlight'] = get_option( 'relevanssi_highlight' );
|
||||
$serialize_options['relevanssi_highlight_comments'] = get_option( 'relevanssi_highlight_comments' );
|
||||
$serialize_options['relevanssi_highlight_docs'] = get_option( 'relevanssi_highlight_docs' );
|
||||
$serialize_options['relevanssi_hilite_title'] = get_option( 'relevanssi_hilite_title' );
|
||||
$serialize_options['relevanssi_implicit_operator'] = get_option( 'relevanssi_implicit_operator' );
|
||||
$serialize_options['relevanssi_index_author'] = get_option( 'relevanssi_index_author' );
|
||||
$serialize_options['relevanssi_index_comments'] = get_option( 'relevanssi_index_comments' );
|
||||
$serialize_options['relevanssi_index_excerpt'] = get_option( 'relevanssi_index_excerpt' );
|
||||
$serialize_options['relevanssi_index_fields'] = get_option( 'relevanssi_index_fields' );
|
||||
$serialize_options['relevanssi_index_image_files'] = get_option( 'relevanssi_index_image_files' );
|
||||
$serialize_options['relevanssi_index_limit'] = get_option( 'relevanssi_index_limit' );
|
||||
$serialize_options['relevanssi_index_pdf_parent'] = get_option( 'relevanssi_index_pdf_parent' );
|
||||
$serialize_options['relevanssi_index_post_type_archives'] = get_option( 'relevanssi_index_post_type_archives' );
|
||||
$serialize_options['relevanssi_index_post_types'] = get_option( 'relevanssi_index_post_types', array() );
|
||||
$serialize_options['relevanssi_index_subscribers'] = get_option( 'relevanssi_index_subscribers' );
|
||||
$serialize_options['relevanssi_index_synonyms'] = get_option( 'relevanssi_index_synonyms' );
|
||||
$serialize_options['relevanssi_index_taxonomies'] = get_option( 'relevanssi_index_taxonomies' );
|
||||
$serialize_options['relevanssi_index_taxonomies_list'] = $index_taxonomies_list;
|
||||
$serialize_options['relevanssi_index_terms'] = $index_terms;
|
||||
$serialize_options['relevanssi_index_user_fields'] = get_option( 'relevanssi_index_user_fields' );
|
||||
$serialize_options['relevanssi_index_users'] = get_option( 'relevanssi_index_users' );
|
||||
$serialize_options['relevanssi_internal_links'] = get_option( 'relevanssi_internal_links' );
|
||||
$serialize_options['relevanssi_link_boost'] = get_option( 'relevanssi_link_boost' );
|
||||
$serialize_options['relevanssi_link_pdf_files'] = get_option( 'relevanssi_link_pdf_files' );
|
||||
$serialize_options['relevanssi_log_queries'] = get_option( 'relevanssi_log_queries' );
|
||||
$serialize_options['relevanssi_log_queries_with_ip'] = get_option( 'relevanssi_log_queries_with_ip' );
|
||||
$serialize_options['relevanssi_max_excerpts'] = get_option( 'relevanssi_max_excerpts' );
|
||||
$serialize_options['relevanssi_min_word_length'] = get_option( 'relevanssi_min_word_length' );
|
||||
$serialize_options['relevanssi_mysql_columns'] = get_option( 'relevanssi_mysql_columns' );
|
||||
$serialize_options['relevanssi_omit_from_logs'] = get_option( 'relevanssi_omit_from_logs' );
|
||||
$serialize_options['relevanssi_polylang_all_languages'] = get_option( 'relevanssi_polylang_all_languages' );
|
||||
$serialize_options['relevanssi_post_type_ids'] = get_option( 'relevanssi_post_type_ids' );
|
||||
$serialize_options['relevanssi_post_type_weights'] = get_option( 'relevanssi_post_type_weights' );
|
||||
$serialize_options['relevanssi_punctuation'] = get_option( 'relevanssi_punctuation' );
|
||||
$serialize_options['relevanssi_read_new_files'] = get_option( 'relevanssi_read_new_files' );
|
||||
$serialize_options['relevanssi_recency_bonus'] = get_option( 'relevanssi_recency_bonus' );
|
||||
$serialize_options['relevanssi_redirects'] = get_option( 'relevanssi_redirects' );
|
||||
$serialize_options['relevanssi_related_settings'] = get_option( 'relevanssi_related_settings' );
|
||||
$serialize_options['relevanssi_related_style'] = get_option( 'relevanssi_related_style' );
|
||||
$serialize_options['relevanssi_respect_exclude'] = get_option( 'relevanssi_respect_exclude' );
|
||||
$serialize_options['relevanssi_searchblogs'] = get_option( 'relevanssi_searchblogs' );
|
||||
$serialize_options['relevanssi_searchblogs_all'] = get_option( 'relevanssi_searchblogs_all' );
|
||||
$serialize_options['relevanssi_send_pdf_files'] = get_option( 'relevanssi_send_pdf_files' );
|
||||
$serialize_options['relevanssi_seo_noindex'] = get_option( 'relevanssi_seo_noindex' );
|
||||
$serialize_options['relevanssi_server_location'] = get_option( 'relevanssi_server_location' );
|
||||
$serialize_options['relevanssi_show_matches'] = get_option( 'relevanssi_show_matches' );
|
||||
$serialize_options['relevanssi_show_matches_text'] = get_option( 'relevanssi_show_matches_text' );
|
||||
$serialize_options['relevanssi_show_post_controls'] = get_option( 'relevanssi_show_post_controls' );
|
||||
$serialize_options['relevanssi_spamblock'] = get_option( 'relevanssi_spamblock' );
|
||||
$serialize_options['relevanssi_stopwords'] = get_option( 'relevanssi_stopwords' );
|
||||
$serialize_options['relevanssi_synonyms'] = get_option( 'relevanssi_synonyms' );
|
||||
$serialize_options['relevanssi_thousand_separator'] = get_option( 'relevanssi_thousand_separator' );
|
||||
$serialize_options['relevanssi_throttle'] = get_option( 'relevanssi_throttle' );
|
||||
$serialize_options['relevanssi_throttle_limit'] = get_option( 'relevanssi_throttle_limit' );
|
||||
$serialize_options['relevanssi_title_boost'] = get_option( 'relevanssi_title_boost' );
|
||||
$serialize_options['relevanssi_trim_logs'] = get_option( 'relevanssi_trim_logs' );
|
||||
$serialize_options['relevanssi_txt_col'] = $txt_col;
|
||||
$serialize_options['relevanssi_update_translations'] = get_option( 'relevanssi_update_translations' );
|
||||
$serialize_options['relevanssi_wpml_only_current'] = get_option( 'relevanssi_wpml_only_current' );
|
||||
|
||||
$serialized_options = wp_json_encode( $serialize_options );
|
||||
|
||||
return $serialized_options;
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* /premium/tabs/redirects-tab.php
|
||||
*
|
||||
* Prints out the Premium Redirects tab in Relevanssi settings.
|
||||
*
|
||||
* @package Relevanssi_Premium
|
||||
* @author Mikko Saari
|
||||
* @license https://wordpress.org/about/gpl/ GNU General Public License
|
||||
* @see https://www.relevanssi.com/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Prints out the Premium Redirects tab in Relevanssi settings.
|
||||
*/
|
||||
function relevanssi_redirects_tab() {
|
||||
$site_url = site_url();
|
||||
$redirects = get_option( 'relevanssi_redirects' );
|
||||
if ( ! isset( $redirects['empty'] ) ) {
|
||||
$redirects['empty'] = '';
|
||||
}
|
||||
if ( ! isset( $redirects['no_terms'] ) ) {
|
||||
$redirects['no_terms'] = '';
|
||||
}
|
||||
?>
|
||||
<h2 id="options"><?php esc_html_e( 'Redirects', 'relevanssi' ); ?></h2>
|
||||
|
||||
<p><?php esc_html_e( 'If you want a particular search to always lead to a specific page, you can use the redirects. Whenever the search query matches a redirect, the search is automatically bypassed and the user is redirected to the target page.', 'relevanssi' ); ?></p>
|
||||
|
||||
<p><?php esc_html_e( 'Enter the search term and the target URL, which may be relative to your site home page or an absolute URL. If "Partial match" is checked, the redirect happens if the query word appears anywhere in the search query, even inside a word, so use it with care. If the search query matches multiple redirections, the first one it matches will trigger.', 'relevanssi' ); ?></p>
|
||||
|
||||
<p><?php esc_html_e( 'The "Hits" column shows how many times each redirect has been used.', 'relevanssi' ); ?></p>
|
||||
|
||||
<table class="form-table" role="presentation">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row"><label for="redirect_empty_searches"><?php esc_html_e( 'Redirect empty searches', 'relevanssi' ); ?></label></th>
|
||||
<td><input type="text" id="redirect_empty_searches" name="redirect_empty_searches" size="60" value="<?php echo esc_attr( str_replace( $site_url, '', $redirects['empty'] ) ); ?>" />
|
||||
<p class="description"><?php esc_html_e( 'Enter an URL here to redirect all searches that find nothing to this URL.', 'relevanssi' ); ?></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="redirect_no_terms"><?php esc_html_e( 'Redirect searches without terms', 'relevanssi' ); ?></label></th>
|
||||
<td><input type="text" id="redirect_no_terms" name="redirect_no_terms" size="60" value="<?php echo esc_attr( str_replace( $site_url, '', $redirects['no_terms'] ) ); ?>" />
|
||||
<p class="description"><?php esc_html_e( 'Enter an URL here to redirect all searches without any search terms.', 'relevanssi' ); ?></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table class="form-table" id="redirect_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php esc_html_e( 'Query', 'relevanssi' ); ?></th>
|
||||
<th><?php esc_html_e( 'Partial match', 'relevanssi' ); ?></th>
|
||||
<th><?php esc_html_e( 'URL', 'relevanssi' ); ?></th>
|
||||
<th><?php esc_html_e( 'Hits', 'relevanssi' ); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
if ( ! isset( $redirects[0] ) ) {
|
||||
?>
|
||||
<tr class="redirect_table_row" id="row_0">
|
||||
<td><input type="text" name="query_0" size="60" />
|
||||
<div class="row-actions">
|
||||
<span class="copy"><a href="#" class="copy"><?php esc_html_e( 'Copy', 'relevanssi' ); ?></a> |</span>
|
||||
<span class="delete"><a href="#" class="remove"><?php esc_html_e( 'Remove', 'relevanssi' ); ?></a></span>
|
||||
</div>
|
||||
</td>
|
||||
<td><input type="checkbox" name="partial_0" /></td>
|
||||
<td><input type="text" name="url_0" size="60" /></td>
|
||||
<td><input type="hidden" name="hits_0" /><span>0</span></td>
|
||||
</tbody>
|
||||
</tr>
|
||||
<?php
|
||||
} else {
|
||||
$row = 0;
|
||||
foreach ( $redirects as $redirect ) {
|
||||
if ( ! isset( $redirect['query'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$row_id = esc_attr( $row );
|
||||
$query = esc_attr( $redirect['query'] );
|
||||
$partial = '';
|
||||
if ( $redirect['partial'] ) {
|
||||
$partial = 'checked="checked"';
|
||||
}
|
||||
$url = esc_attr( $redirect['url'] );
|
||||
$url = str_replace( $site_url, '', $url );
|
||||
|
||||
$hits = $redirect['hits'] ?? 0;
|
||||
// phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
<tr class="redirect_table_row" id="row_<?php echo $row_id; ?>">
|
||||
<td>
|
||||
<label
|
||||
class="screen-reader-text"
|
||||
for="query_<?php echo $row_id; ?>">
|
||||
<?php esc_html_e( 'Query string', 'relevanssi' ); ?>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="query_<?php echo $row_id; ?>"
|
||||
name="query_<?php echo $row_id; ?>"
|
||||
size="60"
|
||||
value="<?php echo $query; ?>" />
|
||||
<div class="row-actions">
|
||||
<span class="copy"><a href="#" class="copy"><?php esc_html_e( 'Copy', 'relevanssi' ); ?></a> |</span>
|
||||
<span class="delete"><a href="#" class="remove"><?php esc_html_e( 'Remove', 'relevanssi' ); ?></a></span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<label
|
||||
class="screen-reader-text"
|
||||
for="partial_<?php echo $row_id; ?>">
|
||||
<?php esc_html_e( 'Partial match', 'relevanssi' ); ?>
|
||||
</label>
|
||||
<input
|
||||
type="checkbox"
|
||||
id="partial_<?php echo $row_id; ?>"
|
||||
name="partial_<?php echo $row_id; ?>"
|
||||
<?php echo $partial; ?> />
|
||||
</td>
|
||||
<td>
|
||||
<label
|
||||
class="screen-reader-text"
|
||||
for="url_<?php echo $row_id; ?>">
|
||||
<?php esc_html_e( 'Target URL', 'relevanssi' ); ?>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="url_<?php echo $row_id; ?>"
|
||||
id="url_<?php echo $row_id; ?>"
|
||||
size="60"
|
||||
value="<?php echo $url; ?>" />
|
||||
</td>
|
||||
<td>
|
||||
<input
|
||||
type="hidden"
|
||||
name="hits_<?php echo $row_id; ?>"
|
||||
id="hits_<?php echo $row_id; ?>"
|
||||
value="<?php echo $hits; ?>" />
|
||||
<span><?php echo $hits; ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
++$row;
|
||||
}
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<button type="button" class="secondary" id="add_redirect"><?php esc_html_e( 'Add a redirect', 'relevanssi' ); ?></button>
|
||||
|
||||
<p><?php esc_html_e( "Once you're done, remember to click the save button below!", 'relevanssi' ); ?></p>
|
||||
<?php
|
||||
}
|
||||
@@ -1,516 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* /premium/tabs/related-tab.php
|
||||
*
|
||||
* Prints out the Premium Related tab in Relevanssi settings.
|
||||
*
|
||||
* @package Relevanssi_Premium
|
||||
* @author Mikko Saari
|
||||
* @license https://wordpress.org/about/gpl/ GNU General Public License
|
||||
* @see https://www.relevanssi.com/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Prints out the Premium Related posts tab in Relevanssi settings.
|
||||
*/
|
||||
function relevanssi_related_tab() {
|
||||
global $relevanssi_variables;
|
||||
|
||||
wp_enqueue_media();
|
||||
add_action( 'admin_footer', 'relevanssi_media_selector_print_scripts' );
|
||||
|
||||
$settings = get_option( 'relevanssi_related_settings', array() );
|
||||
if ( empty( $settings ) ) {
|
||||
$settings = relevanssi_related_default_settings();
|
||||
update_option( 'relevanssi_related_settings', $settings );
|
||||
}
|
||||
|
||||
$enabled = $settings['enabled'] ?? 'off';
|
||||
$append = $settings['append'] ?? '';
|
||||
$number = $settings['number'] ?? 6;
|
||||
$months = $settings['months'] ?? 0;
|
||||
$keyword = $settings['keyword'] ?? 'title';
|
||||
$restrict = $settings['restrict'] ?? '';
|
||||
$nothing = $settings['nothing'] ?? 'nothing';
|
||||
$notenough = $settings['notenough'] ?? 'random';
|
||||
$post_types = $settings['post_types'] ?? 'post';
|
||||
$cache_for_admins = $settings['cache_for_admins'] ?? 'off';
|
||||
|
||||
$keyword_sources = explode( ',', $keyword );
|
||||
$restrict_taxos = explode( ',', $restrict );
|
||||
|
||||
$nothing_selected = '';
|
||||
$random_selected = '';
|
||||
$random_cat_selected = '';
|
||||
|
||||
if ( 'nothing' === $nothing ) {
|
||||
$nothing_selected = 'selected="selected"';
|
||||
}
|
||||
if ( 'random' === $nothing ) {
|
||||
$random_selected = 'selected="selected"';
|
||||
}
|
||||
if ( 'random_cat' === $nothing ) {
|
||||
$random_cat_selected = 'selected="selected"';
|
||||
}
|
||||
|
||||
$dontfillup_selected = '';
|
||||
$randomfillup_selected = '';
|
||||
$randomcatfillup_selected = '';
|
||||
if ( 'nothing' === $notenough ) {
|
||||
$dontfillup_selected = 'selected="selected"';
|
||||
}
|
||||
if ( 'random' === $notenough ) {
|
||||
$randomfillup_selected = 'selected="selected"';
|
||||
}
|
||||
if ( 'random_cat' === $notenough ) {
|
||||
$randomcatfillup_selected = 'selected="selected"';
|
||||
}
|
||||
|
||||
$append_array = explode( ',', $append );
|
||||
$post_type_array = explode( ',', $post_types );
|
||||
|
||||
$matching_checked = '';
|
||||
if ( 'matching_post_type' === $post_types ) {
|
||||
$matching_checked = 'checked="checked"';
|
||||
}
|
||||
|
||||
$enabled = relevanssi_check( $enabled );
|
||||
$cache_for_admins = relevanssi_check( $cache_for_admins );
|
||||
|
||||
$disabled = '';
|
||||
if ( empty( $enabled ) ) {
|
||||
$disabled = 'disabled="disabled"';
|
||||
}
|
||||
|
||||
$style = get_option( 'relevanssi_related_style', array() );
|
||||
$style = array_merge( relevanssi_related_default_styles(), $style );
|
||||
$width = $style['width'];
|
||||
$titles = relevanssi_check( $style['titles'] );
|
||||
$excerpts = relevanssi_check( $style['excerpts'] );
|
||||
$thumbnails = relevanssi_check( $style['thumbnails'] );
|
||||
$thumbnail_id = $style['default_thumbnail'];
|
||||
|
||||
$display_default_thumbnail = '';
|
||||
if ( empty( $thumbnails ) ) {
|
||||
$display_default_thumbnail = 'class="screen-reader-text"';
|
||||
}
|
||||
|
||||
$display_thumbnail_preview = '';
|
||||
if ( ! $thumbnail_id ) {
|
||||
$display_thumbnail_preview = 'style="display: none"';
|
||||
}
|
||||
?>
|
||||
<h2 id="options"><?php esc_html_e( 'Related Posts', 'relevanssi' ); ?></h2>
|
||||
|
||||
<p><?php esc_html_e( "Relevanssi Related Posts feature shows related posts on posts pages, based on keywords like post title, tags and categories. This feature uses the Relevanssi index to find the best-matching related posts. All results are cached, so your site performance won't suffer.", 'relevanssi' ); ?></p>
|
||||
|
||||
<?php // Translators: %s is the WP CLI command. ?>
|
||||
<p><?php printf( esc_html__( 'A pro tip: you can regenerate related posts for all posts with the WP CLI command %s.', 'relevanssi' ), '<code>wp relevanssi regenerate_related</code>' ); ?></p>
|
||||
|
||||
<h3><?php esc_html_e( 'Displaying the related posts', 'relevanssi' ); ?></h3>
|
||||
|
||||
<table class="form-table" role="presentation">
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<?php esc_html_e( 'Enable related posts', 'relevanssi' ); ?>
|
||||
</th>
|
||||
<td>
|
||||
<label>
|
||||
<input type='checkbox' name='relevanssi_related_enabled' id='relevanssi_related_enabled' <?php echo esc_html( $enabled ); ?> />
|
||||
<?php esc_html_e( 'If this is unchecked, related posts will be completely disabled.', 'relevanssi' ); ?>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="tr_relevanssi_related_append">
|
||||
<th scope="row"><?php esc_html_e( 'Automatically add to these post types', 'relevanssi' ); ?></th>
|
||||
<td>
|
||||
<fieldset>
|
||||
<legend class="screen-reader-text"><?php esc_html_e( 'Automatically add to these post types', 'relevanssi' ); ?></legend>
|
||||
<?php
|
||||
$args = array(
|
||||
'public' => true,
|
||||
);
|
||||
$post_types = get_post_types( $args, 'objects' );
|
||||
foreach ( $post_types as $post_type ) {
|
||||
$checked = '';
|
||||
if ( in_array( $post_type->name, $append_array, true ) ) {
|
||||
$checked = 'checked="checked"';
|
||||
}
|
||||
if ( in_array( $post_type->name, relevanssi_get_forbidden_post_types(), true ) ) {
|
||||
continue;
|
||||
}
|
||||
printf(
|
||||
'<p><label><input type="checkbox" name="relevanssi_related_append[]" value="%1$s" %2$s %4$s>%3$s</label></p>',
|
||||
esc_attr( $post_type->name ),
|
||||
$checked, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
esc_html( $post_type->labels->singular_name ),
|
||||
$disabled // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
);
|
||||
}
|
||||
?>
|
||||
</fieldset>
|
||||
<?php // Translators: %1$s is the_content, %2$s is relevanssi_related_priority. ?>
|
||||
<p class="description"><?php printf( esc_html__( 'The related posts will be automatically displayed for these post types. The element is added using %1$s filter hook with priority 99 (you can adjust that with the %2$s filter hook).', 'relevanssi' ), '<code>the_content</code>', '<code>relevanssi_related_priority</code>' ); ?></p>
|
||||
<?php // Translators: %1$s is the template function name, %2$s is the shortcode name. ?>
|
||||
<p class="description"><?php printf( esc_html__( "If you don't choose to display the related posts automatically, you need to add them manually to your template. You can use the template function %1\$s or the shortcode %2\$s to display the related posts.", 'relevanssi' ), '<code>relevanssi_related_posts( $post_id )</code>', '<code>[relevanssi_related_posts]</code>' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3><?php esc_html_e( 'Choosing the related posts', 'relevanssi' ); ?></h3>
|
||||
|
||||
<table class="form-table" role="presentation">
|
||||
<tr id="tr_relevanssi_related_keyword">
|
||||
<th scope="row"><?php esc_html_e( 'Keyword sources', 'relevanssi' ); ?></th>
|
||||
<td>
|
||||
<fieldset>
|
||||
<legend class="screen-reader-text"><?php esc_html_e( 'Keyword sources', 'relevanssi' ); ?></legend>
|
||||
<table>
|
||||
<tbody>
|
||||
<?php
|
||||
$title_object = new stdClass();
|
||||
$title_object->name = 'title';
|
||||
$title_object->labels = new stdClass();
|
||||
$title_object->labels->name = __( 'Title', 'relevanssi' );
|
||||
|
||||
$taxos = get_taxonomies( '', 'objects' );
|
||||
array_unshift( $taxos, $title_object );
|
||||
|
||||
$taxonomies_list = array_flip( get_option( 'relevanssi_index_taxonomies_list' ) );
|
||||
$taxonomies_list['title'] = true;
|
||||
|
||||
$not_indexed = array();
|
||||
|
||||
foreach ( $taxos as $taxonomy ) {
|
||||
if ( in_array( $taxonomy->name, relevanssi_get_forbidden_taxonomies(), true ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( ! isset( $taxonomies_list[ $taxonomy->name ] ) ) {
|
||||
$not_indexed[] = $taxonomy->labels->name;
|
||||
continue;
|
||||
}
|
||||
$checked = '';
|
||||
if ( in_array( $taxonomy->name, $keyword_sources, true ) ) {
|
||||
$checked = 'checked="checked"';
|
||||
}
|
||||
$restrict_checked = '';
|
||||
if ( in_array( $taxonomy->name, $restrict_taxos, true ) ) {
|
||||
$restrict_checked = 'checked="checked"';
|
||||
}
|
||||
printf(
|
||||
'<tr><td style="padding-top: 5px; padding-bottom: 5px"><label><input type="checkbox" name="relevanssi_related_keyword[]" %1$s value="%2$s" %4$s/> %3$s</label><td style="padding-top: 5px; padding-bottom: 5px">',
|
||||
$checked, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
esc_attr( $taxonomy->name ),
|
||||
esc_html( $taxonomy->labels->name ),
|
||||
$disabled // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
);
|
||||
if ( 'title' !== $taxonomy->name ) {
|
||||
printf(
|
||||
'<label><input type="checkbox" name="relevanssi_related_restrict[]" %1$s value="%2$s" %3$s/> %4$s %5$s</label>',
|
||||
$restrict_checked, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
esc_attr( $taxonomy->name ),
|
||||
$disabled, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
esc_html__( 'Restrict to taxonomy ', 'relevanssi' ),
|
||||
esc_html( $taxonomy->labels->name )
|
||||
);
|
||||
}
|
||||
echo '</td></tr>';
|
||||
}
|
||||
|
||||
$not_indexed = implode( ', ', $not_indexed );
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</fieldset>
|
||||
<p class="description"><?php esc_html_e( "The sources Relevanssi uses for related post keywords. Keywords from these sources are then used to search the Relevanssi index to find related posts. Make sure you choose something, otherwise you won't see results or will see random results. In addition of these sources, you can also define your own keywords for each post from the post edit screen.", 'relevanssi' ); ?></p>
|
||||
<p class="description"><?php esc_html_e( 'If you choose to restrict to the taxonomy, those keywords will only match in the same category. For example restricted category search terms will only match to category, not to post content. This may lead to better precision, depending on how the taxonomy terms are used.', 'relevanssi' ); ?></p>
|
||||
<?php
|
||||
if ( ! empty( $not_indexed ) ) {
|
||||
?>
|
||||
<p class="description">
|
||||
<?php
|
||||
esc_html_e( "These taxonomies are missing here, because Relevanssi isn't set to index them:", 'relevanssi' );
|
||||
echo ' ' . esc_html( $not_indexed ) . '.';
|
||||
?>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="relevanssi_related_number"><?php esc_html_e( 'Number of posts', 'relevanssi' ); ?></label></th>
|
||||
<td>
|
||||
<input type='number' name='relevanssi_related_number' id='relevanssi_related_number' size='4' placeholder='6' value='<?php echo esc_attr( $number ); ?>' <?php echo $disabled; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>/>
|
||||
<p class="description"><?php esc_html_e( 'The number of related posts to show.', 'relevanssi' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope='row'><label for='relevanssi_related_months'><?php esc_html_e( 'Months to use', 'relevanssi' ); ?></label></th>
|
||||
<td>
|
||||
<input type='number' name='relevanssi_related_months' id='relevanssi_related_months' size='4' placeholder='12' value='<?php echo esc_attr( $months ); ?>' <?php echo $disabled; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>/>
|
||||
<p class="description"><?php esc_html_e( 'Use only posts published within this many months. (For more fine-grained date controls, use filters.)', 'relevanssi' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="tr_relevanssi_related_post_types">
|
||||
<th scope="row"><?php esc_html_e( 'Post types to use', 'relevanssi' ); ?></th>
|
||||
<td>
|
||||
<fieldset>
|
||||
<legend class="screen-reader-text"><?php esc_html_e( 'Post types to use', 'relevanssi' ); ?></legend>
|
||||
<p>
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
class="matching"
|
||||
name="relevanssi_related_post_types[]"
|
||||
value="matching_post_type"
|
||||
<?php echo $matching_checked; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
<?php echo $disabled; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
/>
|
||||
<?php esc_html_e( 'Matching post type', 'relevanssi' ); ?>
|
||||
<span class="screen-reader-text"><?php esc_html_e( 'Uncheck this option to choose other post types.', 'relevanssi' ); ?></span>
|
||||
</label>
|
||||
</p>
|
||||
<?php
|
||||
$post_types = get_post_types();
|
||||
foreach ( $post_types as $type ) {
|
||||
$post_type = get_post_type_object( $type );
|
||||
|
||||
$checked = '';
|
||||
if ( in_array( $type, $post_type_array, true ) ) {
|
||||
$checked = 'checked="checked"';
|
||||
}
|
||||
$row_disabled = '';
|
||||
if ( $matching_checked ) {
|
||||
$row_disabled = 'disabled="disabled"';
|
||||
}
|
||||
if ( $disabled ) {
|
||||
$row_disabled = $disabled;
|
||||
}
|
||||
if ( in_array( $type, relevanssi_get_forbidden_post_types(), true ) ) {
|
||||
continue;
|
||||
}
|
||||
printf(
|
||||
'<p><label><input type="checkbox" class="nonmatching" name="relevanssi_related_post_types[]" value="%1$s" %2$s %3$s>%4$s</label></p>',
|
||||
esc_attr( $type ),
|
||||
$checked, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
$row_disabled, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
esc_html( $post_type->labels->singular_name )
|
||||
);
|
||||
}
|
||||
?>
|
||||
</fieldset>
|
||||
<p class="description"><?php esc_html_e( 'The post types to use for related posts. Matching post type means that for each post type, only posts from the same post type are used for related posts.', 'relevanssi' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="relevanssi_related_nothing"><?php esc_html_e( 'No related posts found', 'relevanssi' ); ?></label></th>
|
||||
<td>
|
||||
<select name="relevanssi_related_nothing" id="relevanssi_related_nothing" <?php echo $disabled; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
|
||||
<option value="nothing" <?php echo esc_html( $nothing_selected ); ?>><?php esc_html_e( 'Show nothing', 'relevanssi' ); ?></option>
|
||||
<option value="random" <?php echo esc_html( $random_selected ); ?>><?php esc_html_e( 'Random posts', 'relevanssi' ); ?></option>
|
||||
<option value="random_cat" <?php echo esc_html( $random_cat_selected ); ?>><?php esc_html_e( 'Random posts from same category', 'relevanssi' ); ?></option>
|
||||
</select>
|
||||
<p class="description"><?php esc_html_e( 'What to do when no related posts are found? The options are to show nothing and just disable the whole element, or to show random posts (either fully random, or from the same category). Do note that the related posts are cached, so the random posts do not change on every page load.', 'relevanssi' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="relevanssi_related_notenough"><?php esc_html_e( 'Not enough related posts found', 'relevanssi' ); ?></label></th>
|
||||
<td>
|
||||
<select name="relevanssi_related_notenough" id="relevanssi_related_notenough" <?php echo $disabled; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
|
||||
<option value="nothing" <?php echo esc_html( $dontfillup_selected ); ?>><?php esc_html_e( 'Show the found posts', 'relevanssi' ); ?></option>
|
||||
<option value="random" <?php echo esc_html( $randomfillup_selected ); ?>><?php esc_html_e( 'Fill with random posts', 'relevanssi' ); ?></option>
|
||||
<option value="random_cat" <?php echo esc_html( $randomcatfillup_selected ); ?>><?php esc_html_e( 'Fill with random posts from same category', 'relevanssi' ); ?></option>
|
||||
</select>
|
||||
<p class="description"><?php esc_html_e( 'What to do when not enough related posts are found? The options are to show what was found, or to fill up the display with random posts. Do note that the related posts are cached, so the random posts do not change on every page load.', 'relevanssi' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3><?php esc_html_e( 'Style options', 'relevanssi' ); ?></h3>
|
||||
|
||||
<p><?php esc_html_e( 'When you add the related posts to your site, Relevanssi will use a template to print out the results. These settings control how that template displays the posts. If you need to modify the related posts in a way these settings do not allow, you can always create your own template.', 'relevanssi' ); ?></p>
|
||||
|
||||
<p>
|
||||
<?php
|
||||
// Translators: %1$s is the default template filename, %2$s is the theme template directory.
|
||||
printf( esc_html__( "To create your own template, it's best if you begin with the default Relevanssi template, which can be found in the file %1\$s. Copy the template in the %2\$s folder in your theme and make the necessary changes. Relevanssi will then use your template file to display the related posts.", 'relevanssi' ), '<code>' . esc_html( $relevanssi_variables['plugin_dir'] ) . 'premium/templates/relevanssi-related.php</code>', '<code>' . esc_html( get_stylesheet_directory() ) . '/templates/</code>' );
|
||||
?>
|
||||
</p>
|
||||
|
||||
<table class="form-table" role="presentation">
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<?php esc_html_e( 'Display titles', 'relevanssi' ); ?>
|
||||
</th>
|
||||
<td>
|
||||
<label>
|
||||
<input type='checkbox' name='relevanssi_related_titles' id='relevanssi_related_titles' <?php echo esc_html( $titles ); ?> <?php echo $disabled; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>/>
|
||||
<?php esc_html_e( 'Display titles for related posts.', 'relevanssi' ); ?>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<?php esc_html_e( 'Display thumbnails', 'relevanssi' ); ?>
|
||||
</th>
|
||||
<td>
|
||||
<label>
|
||||
<input type='checkbox' name='relevanssi_related_thumbnails' id='relevanssi_related_thumbnails' <?php echo esc_html( $thumbnails ); ?> <?php echo $disabled; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>/>
|
||||
<?php esc_html_e( 'Display thumbnails for related posts.', 'relevanssi' ); ?>
|
||||
</label>
|
||||
<p class="description"><?php esc_html_e( 'If enabled, this will show the featured image for the post if the post has one.', 'relevanssi' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr id="defaultthumbnail" <?php echo $display_default_thumbnail; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
|
||||
<th scope="row">
|
||||
<?php esc_html_e( 'Default thumbnail', 'relevanssi' ); ?>
|
||||
</th>
|
||||
<td>
|
||||
<div class='image-preview-wrapper' <?php echo $display_thumbnail_preview; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
|
||||
<img id='image-preview' alt="Thumbnail image preview" src='<?php echo esc_attr( wp_get_attachment_url( $thumbnail_id ) ); ?>' width='100' height='100' style='max-height: 100px; width: 100px;'>
|
||||
</div>
|
||||
<input id="upload_image_button" type="button" class="button" value="<?php echo esc_attr( __( 'Select image', 'relevanssi' ) ); ?>" <?php echo $disabled; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>/>
|
||||
<input type='hidden' name='relevanssi_default_thumbnail' id='relevanssi_default_thumbnail' value='<?php echo esc_attr( $thumbnail_id ); ?>'>
|
||||
<p class="description"><?php esc_html_e( "If a post doesn't have a featured image, this image will be used instead.", 'relevanssi' ); ?></p>
|
||||
|
||||
<label>
|
||||
<input type='checkbox' name='relevanssi_remove_default_thumbnail' <?php echo $disabled; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>/>
|
||||
<?php esc_html_e( 'Check this post to remove the default thumbnail.', 'relevanssi' ); ?>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<?php esc_html_e( 'Display excerpts', 'relevanssi' ); ?>
|
||||
</th>
|
||||
<td>
|
||||
<label >
|
||||
<input type='checkbox' name='relevanssi_related_excerpts' id='relevanssi_related_excerpts' <?php echo esc_html( $excerpts ); ?> <?php echo $disabled; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>/>
|
||||
<?php esc_html_e( 'Display excerpts for related posts.', 'relevanssi' ); ?>
|
||||
</label>
|
||||
<?php // Translators: name of the filter hook. ?>
|
||||
<p class="description"><?php printf( esc_html__( 'This uses the manually created post excerpt if one exists, otherwise the beginning of the post is used. Default length is 50 characters, use the %s filter hook to adjust that.', 'relevanssi' ), '<code>relevanssi_related_excerpt_length</code>' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="relevanssi_related_width"><?php esc_html_e( 'Minimum width', 'relevanssi' ); ?>
|
||||
<span class="screen-reader-text"><?php esc_html_e( 'in pixels', 'relevanssi' ); ?></span>
|
||||
</label>
|
||||
</th>
|
||||
<td>
|
||||
<input type='text' name='relevanssi_related_width' id='relevanssi_related_width' size='4' value='<?php echo esc_attr( $width ); ?>' <?php echo $disabled; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>/> px
|
||||
<p class="description"><?php esc_html_e( 'The minimum width of the related post element.', 'relevanssi' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3><?php esc_html_e( 'Caching', 'relevanssi' ); ?></h3>
|
||||
|
||||
<p><?php esc_html_e( 'The related posts are cached using WordPress transients. The related posts for each post are stored in a transient that is stored for two weeks. The cache for each post is flushed whenever the post is saved. When a post is made non-public (returned to draft, trashed), Relevanssi automatically flushes all related post caches where that post appears.', 'relevanssi' ); ?></p>
|
||||
|
||||
<table class="form-table" role="presentation">
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<?php esc_html_e( 'Use cache for admins', 'relevanssi' ); ?>
|
||||
</th>
|
||||
<td>
|
||||
<label >
|
||||
<input type='checkbox' name='relevanssi_related_cache_for_admins' id='relevanssi_related_cache_for_admins' <?php echo esc_html( $cache_for_admins ); ?> <?php echo $disabled; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>/>
|
||||
<?php esc_html_e( 'Use the cache for admin users.', 'relevanssi' ); ?>
|
||||
</label>
|
||||
<p class="description"><?php esc_html_e( 'Disable this option when adjusting the settings to see changes on the site.', 'relevanssi' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<?php esc_html_e( 'Flush cache', 'relevanssi' ); ?>
|
||||
</th>
|
||||
<td>
|
||||
<label >
|
||||
<input type='checkbox' name='relevanssi_flush_related_cache' id='relevanssi_flush_related_cache' <?php echo $disabled; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>/>
|
||||
<?php esc_html_e( 'Flush the caches.', 'relevanssi' ); ?>
|
||||
</label>
|
||||
<p class="description"><?php esc_html_e( 'Check this box to flush all related posts caches.', 'relevanssi' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the media selector scripts for the related posts tab.
|
||||
*
|
||||
* From: https://jeroensormani.com/how-to-include-the-wordpress-media-selector-in-your-plugin/
|
||||
* and https://mikejolley.com/2012/12/21/using-the-new-wordpress-3-5-media-uploader-in-plugins/
|
||||
*
|
||||
* @author Jeroen Sormani
|
||||
* @author Mike Jolly
|
||||
*/
|
||||
function relevanssi_media_selector_print_scripts() {
|
||||
$style = get_option( 'relevanssi_related_style', array() );
|
||||
$style = array_merge( relevanssi_related_default_styles(), $style );
|
||||
|
||||
$thumbnail_id = $style['default_thumbnail'];
|
||||
if ( empty( $thumbnail_id ) ) {
|
||||
$thumbnail_id = 0;
|
||||
}
|
||||
|
||||
?>
|
||||
<script type='text/javascript'>
|
||||
jQuery( document ).ready( function( $ ) {
|
||||
// Uploading files
|
||||
var file_frame;
|
||||
var wp_media_post_id = wp.media.model.settings.post.id; // Store the old id
|
||||
var set_to_post_id = <?php echo $thumbnail_id; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>;
|
||||
console.log(set_to_post_id);
|
||||
jQuery('#upload_image_button').on('click', function( event ){
|
||||
event.preventDefault();
|
||||
// If the media frame already exists, reopen it.
|
||||
if ( file_frame ) {
|
||||
// Set the post ID to what we want
|
||||
file_frame.uploader.uploader.param( 'post_id', set_to_post_id );
|
||||
// Open frame
|
||||
file_frame.open();
|
||||
return;
|
||||
} else {
|
||||
// Set the wp.media post id so the uploader grabs the ID we want when initialised
|
||||
wp.media.model.settings.post.id = set_to_post_id;
|
||||
}
|
||||
// Create the media frame.
|
||||
file_frame = wp.media.frames.file_frame = wp.media({
|
||||
title: 'Select a image to upload',
|
||||
button: {
|
||||
text: 'Use this image',
|
||||
},
|
||||
multiple: false // Set to true to allow multiple files to be selected
|
||||
});
|
||||
// When an image is selected, run a callback.
|
||||
file_frame.on( 'select', function() {
|
||||
// We set multiple to false so only get one image from the uploader
|
||||
attachment = file_frame.state().get('selection').first().toJSON();
|
||||
// Do something with attachment.id and/or attachment.url here
|
||||
$( '#image-preview' ).attr( 'src', attachment.url ).css( 'width', 'auto' );
|
||||
$( '#relevanssi_default_thumbnail' ).val( attachment.id );
|
||||
// Restore the main post ID
|
||||
wp.media.model.settings.post.id = wp_media_post_id;
|
||||
$( '.image-preview-wrapper' ).show();
|
||||
});
|
||||
// Finally, open the modal
|
||||
file_frame.open();
|
||||
});
|
||||
// Restore the main ID when the add media button is pressed
|
||||
jQuery( 'a.add_media' ).on( 'click', function() {
|
||||
wp.media.model.settings.post.id = wp_media_post_id;
|
||||
$(".image-preview-wrapper").show();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* /premium/tabs/spamblock-tab.php
|
||||
*
|
||||
* Prints out the Premium Spam Block tab in Relevanssi settings.
|
||||
*
|
||||
* @package Relevanssi_Premium
|
||||
* @author Mikko Saari
|
||||
* @license https://wordpress.org/about/gpl/ GNU General Public License
|
||||
* @see https://www.relevanssi.com/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Prints out the Premium Spam Block tab in Relevanssi settings.
|
||||
*/
|
||||
function relevanssi_spamblock_tab() {
|
||||
$spamblock = get_option( 'relevanssi_spamblock' );
|
||||
if ( ! isset( $spamblock['keywords'] ) ) {
|
||||
$spamblock['keywords'] = '';
|
||||
}
|
||||
if ( ! isset( $spamblock['regex'] ) ) {
|
||||
$spamblock['regex'] = '';
|
||||
}
|
||||
if ( ! isset( $spamblock['chinese'] ) ) {
|
||||
$spamblock['chinese'] = '';
|
||||
}
|
||||
if ( ! isset( $spamblock['cyrillic'] ) ) {
|
||||
$spamblock['cyrillic'] = '';
|
||||
}
|
||||
if ( ! isset( $spamblock['emoji'] ) ) {
|
||||
$spamblock['emoji'] = '';
|
||||
}
|
||||
if ( ! isset( $spamblock['bots'] ) ) {
|
||||
$spamblock['bots'] = '';
|
||||
}
|
||||
$chinese = relevanssi_check( $spamblock['chinese'] );
|
||||
$cyrillic = relevanssi_check( $spamblock['cyrillic'] );
|
||||
$emoji = relevanssi_check( $spamblock['emoji'] );
|
||||
$bots = relevanssi_check( $spamblock['bots'] );
|
||||
|
||||
?>
|
||||
<h2 id="options"><?php esc_html_e( 'Spam Blocking', 'relevanssi' ); ?></h2>
|
||||
|
||||
<p><?php esc_html_e( "These tools can be used to block spam searches on your site. It's best if the spam searches can be blocked earlier on server level before WordPress starts at all, but if that's not possible, this is a fine option.", 'relevanssi' ); ?></p>
|
||||
|
||||
<p>
|
||||
<?php
|
||||
printf(
|
||||
// Translators: %1$s is '?s=', %2$s is '/search/', %3$ is the filter hook name and %4$ is 'highlight'.
|
||||
esc_html__( 'These filters are applied to all searches done using the %1$s parameter, the %2$s pretty URLs (if your pretty URLs are using a different prefix, you can use the %3$s filter hook to adjust the spam block) and also on page views with the %4$s parameter.', 'relevanssi' ),
|
||||
'<code>?s=</code>',
|
||||
'<code>/search/</code>',
|
||||
'<code>relevanssi_search_url_prefix</code>',
|
||||
'<code>highlight</code>'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
|
||||
<p><?php esc_html_e( "You can figure out the suitable keywords from your User searches page. Look for common terms. Often spam queries contain URLs, and the top level domain names are good keywords, things like '.shop', '.online', '.com' – those appear rarely in legitimate searches.", 'relevanssi' ); ?></p>
|
||||
|
||||
<table class="form-table" role="presentation">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row"><label for="relevanssi_spamblock_keywords"><?php esc_html_e( 'Keyword spam blocking', 'relevanssi' ); ?></label></th>
|
||||
<td><textarea name="relevanssi_spamblock_keywords" id="relevanssi_spamblock_keywords" rows="9" cols="60"><?php echo esc_textarea( $spamblock['keywords'] ); ?></textarea>
|
||||
<p class="description"><?php esc_html_e( 'Enter keywords, one per line. If these keywords appear anywhere in the search string, the search will be stopped. Use as short keywords as possible, but be careful to avoid blocking legitimate searches. The keywords are case insensitive.', 'relevanssi' ); ?></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="relevanssi_spamblock_regex"><?php esc_html_e( 'Regex keywords', 'relevanssi' ); ?></label></th>
|
||||
<td><textarea name="relevanssi_spamblock_regex" id="relevanssi_spamblock_regex" rows="9" cols="60"><?php echo esc_textarea( $spamblock['regex'] ); ?></textarea>
|
||||
<?php // Translators: %1$s is <code>/.../iu</code>. ?>
|
||||
<p class="description"><?php printf( esc_html__( 'These keywords support the use of regular expressions with preg_match(). The keywords will be wrapped with %1$s.', 'relevanssi' ), '<code>/.../iu</code>' ); ?></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="relevanssi_spamblock_chinese"><?php esc_html_e( 'Block Chinese queries', 'relevanssi' ); ?></label></th>
|
||||
<td><input type='checkbox' name='relevanssi_spamblock_chinese' id='relevanssi_spamblock_chinese' <?php echo esc_attr( $chinese ); ?> />
|
||||
<?php esc_html_e( 'Block queries that contain Chinese characters.', 'relevanssi' ); ?>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="relevanssi_spamblock_cyrillic"><?php esc_html_e( 'Block Cyrillic queries', 'relevanssi' ); ?></label></th>
|
||||
<td><input type='checkbox' name='relevanssi_spamblock_cyrillic' id='relevanssi_spamblock_cyrillic' <?php echo esc_attr( $cyrillic ); ?> />
|
||||
<?php esc_html_e( 'Block queries that contain Cyrillic characters.', 'relevanssi' ); ?>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="relevanssi_spamblock_emoji"><?php esc_html_e( 'Block emoji queries', 'relevanssi' ); ?></label></th>
|
||||
<td><input type='checkbox' name='relevanssi_spamblock_emoji' id='relevanssi_spamblock_emoji' <?php echo esc_attr( $emoji ); ?> />
|
||||
<?php esc_html_e( 'Block queries that contain emoji characters.', 'relevanssi' ); ?>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="relevanssi_spamblock_bots"><?php esc_html_e( 'Block bot queries', 'relevanssi' ); ?></label></th>
|
||||
<td><input type='checkbox' name='relevanssi_spamblock_bots' id='relevanssi_spamblock_bots' <?php echo esc_attr( $bots ); ?> />
|
||||
<?php esc_html_e( 'Block queries from bots. Only applied to searches, not to page views with highlights.', 'relevanssi' ); ?>
|
||||
<p class="description">
|
||||
<?php
|
||||
esc_html_e( 'Current list of bots: ', 'relevanssi' );
|
||||
/**
|
||||
* Filter documented in /premium/spamblock.php.
|
||||
*/
|
||||
echo esc_html( implode( ', ', array_keys( apply_filters( 'relevanssi_bots_to_block', relevanssi_bot_block_list() ) ) ) . '. ' );
|
||||
// Translators: %1$s is the name of the filter hook.
|
||||
printf( esc_html__( 'You can add new bots to the list with the filter hook %1$s.', 'relevanssi' ), '<code>relevanssi_bots_to_block</code>' );
|
||||
?>
|
||||
</p>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h3><?php esc_html_e( 'Blocking bots', 'relevanssi' ); ?></h3>
|
||||
|
||||
<p><?php esc_html_e( "You can use the Relevanssi spam block to also block requests from bots. In general there's very little reason to allow bots to crawl search results pages. They can create lots of really quite pointless traffic. On one of my sites, out of 20.000 search queries, 16.000 were useless queries by the Bing bot. Nice bots will obey the robots.txt instructions. This code snippet adds robots.txt rules that block rule-obeying bots from accessing search results pages:", 'relevanssi' ); ?></p>
|
||||
|
||||
<p><pre>
|
||||
add_action( 'do_robots', 'rlv_block_bots_robots_txt' );
|
||||
function rlv_block_bots_robots_txt() {
|
||||
?>
|
||||
User-agent: *
|
||||
Disallow: /search/
|
||||
Disallow: /?s=
|
||||
<?php
|
||||
}
|
||||
</pre></p>
|
||||
|
||||
<h3><?php esc_html_e( 'Blocking at the server level', 'relevanssi' ); ?></h3>
|
||||
|
||||
<p><?php esc_html_e( "It's best if the blocking is done before WordPress starts up in the first place: that will increase security and will save server resources. These tools can be used to block bot traffic on your site, but using them requires expertise on server settings. Use them only if you know what you're doing, or have a professional help you.", 'relevanssi' ); ?></p>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker">NGINX Ultimate Bad Bot & Referrer Blocker</a></li>
|
||||
<li><a href="https://github.com/mitchellkrogza/apache-ultimate-bad-bot-blocker">Apache Ultimate Bad Bot & Referrer Blocker</a></li>
|
||||
</ul>
|
||||
<?php
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* /premium/tabs/support-tab.php
|
||||
*
|
||||
* Prints out the Premium Support tab in Relevanssi settings.
|
||||
*
|
||||
* @package Relevanssi_Premium
|
||||
* @author Mikko Saari
|
||||
* @license https://wordpress.org/about/gpl/ GNU General Public License
|
||||
* @see https://www.relevanssi.com/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Prints out the Premium Support tab in Relevanssi settings.
|
||||
*/
|
||||
function relevanssi_support_tab() {
|
||||
global $relevanssi_variables;
|
||||
|
||||
if ( isset( $_REQUEST['relevanssi_support_form'] ) ) {
|
||||
check_admin_referer( 'relevanssi_support_form', 'relevanssi_support_form' );
|
||||
relevanssi_support_send_email( $_REQUEST );
|
||||
}
|
||||
$support_email = $relevanssi_variables['autoupdate']->get_remote_license();
|
||||
|
||||
?>
|
||||
<h2 id="options"><?php esc_html_e( 'Support', 'relevanssi' ); ?></h2>
|
||||
<?php
|
||||
if ( ! $support_email ) {
|
||||
?>
|
||||
<p><?php echo relevanssi_get_api_key_notification(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></p>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<p>
|
||||
<?php
|
||||
printf(
|
||||
// Translators: %1$s opens the link to the support form, %2$s closes the link, %3$s is the support email address.
|
||||
esc_html__( 'This form sends out an email to the Relevanssi support. If you have a question, please fill in the form below and we will get back to you as soon as possible. If you don\'t hear from us in a day or two, it\'s possible your email has gone astray. In that case, please contact us again and use %1$sthe support form at Relevanssi.com%2$s. You can also email us directly at %3$s. Expect slower response times during June and July.', 'relevanssi' ),
|
||||
'<a href="https://www.relevanssi.com/support/">',
|
||||
'</a>',
|
||||
'<em>' . esc_html( $support_email ) . '</em>'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<?php
|
||||
// Translators: %1$s opens the link to the knowledge base, %2$s closes the link.
|
||||
printf( esc_html__( 'We have a large knowledge base. %1$sTake a look there%2$s, perhaps your question is already answered there.', 'relevanssi' ), '<a href="https://www.relevanssi.com/category/knowledge-base/">', '</a>' );
|
||||
?>
|
||||
</p>
|
||||
|
||||
<p><?php esc_html_e( 'Instead of telling us "X doesn\'t work", please try be as specific as possible. Please tell us what you expect to happen and what actually happens.', 'relevanssi' ); ?></p>
|
||||
|
||||
<p><?php esc_html_e( 'Feel free to ask questions in English or Finnish. Please do not send us video questions.', 'relevanssi' ); ?></p>
|
||||
|
||||
<form method="post">
|
||||
<?php wp_nonce_field( 'relevanssi_support_form', 'relevanssi_support_form' ); ?>
|
||||
<input type="hidden" name="relevanssi_support_to_email" value="<?php echo esc_attr( $support_email ); ?>" />
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row"><label for="relevanssi_support_email"><?php esc_html_e( 'Your email address', 'relevanssi' ); ?></label></th>
|
||||
<td><input type="text" name="relevanssi_support_email" id="relevanssi_support_email" value="" size="40" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="relevanssi_support_subject"><?php esc_html_e( 'Subject', 'relevanssi' ); ?></label></th>
|
||||
<td><input type="text" name="relevanssi_support_subject" id="relevanssi_support_subject" value="" size="40" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="relevanssi_support_message"><?php esc_html_e( 'Message', 'relevanssi' ); ?></label></th>
|
||||
<td><textarea name="relevanssi_support_message" id="relevanssi_support_message" rows="10" cols="50"></textarea></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"></th>
|
||||
<td><input type="submit" name="relevanssi_support_submit" id="relevanssi_support_submit" value="<?php esc_attr_e( 'Send', 'relevanssi' ); ?>" class="button button-primary" /></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends out an email to Relevanssi support.
|
||||
*
|
||||
* @param array $request The request array.
|
||||
*/
|
||||
function relevanssi_support_send_email( $request ) {
|
||||
global $wp_version, $relevanssi_variables;
|
||||
|
||||
$message = $request['relevanssi_support_message'];
|
||||
$from = 'From: ' . $request['relevanssi_support_email'];
|
||||
$to = $request['relevanssi_support_to_email'];
|
||||
$subject = $request['relevanssi_support_subject'];
|
||||
|
||||
$message_intro = 'WP version: ' . $wp_version . "\n";
|
||||
$message_intro .= 'PHP version: ' . phpversion() . "\n";
|
||||
$message_intro .= 'Relevanssi version: ' . $relevanssi_variables['plugin_version'] . "\n";
|
||||
$message_intro .= "\n";
|
||||
|
||||
$message = $message_intro . stripslashes( $message );
|
||||
|
||||
$success = wp_mail( $to, $subject, $message, array( $from ) );
|
||||
|
||||
if ( $success ) {
|
||||
?>
|
||||
<div id="message" class="updated fade">
|
||||
<p><?php esc_html_e( 'Email sent!', 'relevanssi' ); ?></p>
|
||||
</div>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<div id="message" class="error">
|
||||
<p><?php esc_html_e( 'Email failed!', 'relevanssi' ); ?></p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* /premium/templates/relevanssi-related.php
|
||||
*
|
||||
* Template for printing out the related posts.
|
||||
*
|
||||
* Make sure this template does not overwrite $post_id. Also note that the
|
||||
* template will be cached, so for example don't do separate code for mobile
|
||||
* and desktop users, because the caching won't care about whether the user
|
||||
* is a mobile or a desktop user and will randomly provide the wrong version to
|
||||
* users.
|
||||
*
|
||||
* @package Relevanssi_Premium
|
||||
* @author Mikko Saari
|
||||
* @license https://wordpress.org/about/gpl/ GNU General Public License
|
||||
* @see https://www.relevanssi.com/
|
||||
*/
|
||||
|
||||
$style = get_option( 'relevanssi_related_style' );
|
||||
|
||||
if ( ! empty( $related_posts ) ) :
|
||||
?>
|
||||
<div id="relevanssi_related">
|
||||
<div class="relevanssi_related_grid_header">
|
||||
<h3><?php esc_html_e( 'Related Posts', 'relevanssi' ); ?></h3>
|
||||
</div>
|
||||
<div id="relevanssi_related_grid">
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Allows adjusting the image size.
|
||||
*
|
||||
* The default value for the image size is "post-thumbnail", but if you for
|
||||
* example want a non-square image size, you can use this filter to set the
|
||||
* image size to "medium".
|
||||
*
|
||||
* @param string The image size.
|
||||
*/
|
||||
$image_size = apply_filters( 'relevanssi_related_image_size', 'post-thumbnail' );
|
||||
|
||||
/**
|
||||
* The related posts are stored in the $related_posts WP_Query object. Each
|
||||
* post is just the post ID number, so if you want to access the whole post
|
||||
* object, use get_post() to fetch it.
|
||||
*/
|
||||
foreach ( $related_posts as $related_post_id ) {
|
||||
$the_post = get_post( $related_post_id );
|
||||
$related_link = get_permalink( $related_post_id );
|
||||
|
||||
$class = '';
|
||||
$thumb = '';
|
||||
if ( isset( $style['thumbnails'] ) && 'off' !== $style['thumbnails'] ) {
|
||||
if ( has_post_thumbnail( $related_post_id ) ) {
|
||||
$thumb = get_the_post_thumbnail( $related_post_id, $image_size );
|
||||
}
|
||||
if ( ! $thumb && isset( $style['default_thumbnail'] ) ) {
|
||||
$thumb = wp_get_attachment_image( $style['default_thumbnail'], $image_size, false, array( 'class' => 'wp-post-image' ) );
|
||||
}
|
||||
}
|
||||
|
||||
$excerpt = '';
|
||||
if ( isset( $style['excerpts'] ) && 'off' !== $style['excerpts'] ) {
|
||||
if ( empty( $the_post->post_excerpt ) ) {
|
||||
$the_post->post_excerpt = mb_substr( wp_strip_all_tags( $the_post->post_content ), 0, apply_filters( 'relevanssi_related_excerpt_length', 50 ) ) . '...';
|
||||
}
|
||||
$excerpt = '<p>' . $the_post->post_excerpt . '</p>';
|
||||
if ( mb_strlen( $excerpt ) > apply_filters( 'relevanssi_related_wide_limit', 100 ) ) {
|
||||
$class .= ' wide';
|
||||
}
|
||||
}
|
||||
|
||||
$related_title = '';
|
||||
if ( isset( $style['titles'] ) && 'off' !== $style['titles'] ) {
|
||||
$related_title = $the_post->post_title;
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="relevanssi_related_post<?php echo esc_attr( $class ); ?>">
|
||||
<a href="<?php echo $related_link; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>">
|
||||
<?php echo $thumb; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
<h4><?php echo $related_title; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></h4>
|
||||
</a>
|
||||
<?php echo $excerpt; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Prints out the default CSS styles. If you include the style for the related posts
|
||||
* to the main CSS file, you can remove this part from your template.
|
||||
*/
|
||||
$width = 200;
|
||||
if ( isset( $style['width'] ) && intval( $style['width'] ) > 0 ) {
|
||||
$width = $style['width'];
|
||||
}
|
||||
|
||||
?>
|
||||
<style>
|
||||
#relevanssi_related_grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(<?php echo $width; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>px, 1fr));
|
||||
grid-column-gap: 10px;
|
||||
}
|
||||
.relevanssi_related_post h4 {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.relevanssi_related_grid_header {
|
||||
grid-area: header;
|
||||
}
|
||||
.relevanssi_related_post.wide {
|
||||
grid-column-end: span 2;
|
||||
}
|
||||
</style>
|
||||
<?php
|
||||
endif; // This if clause checks for empty( $related_posts->posts ).
|
||||
@@ -1,159 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* /premium/uninstall.php
|
||||
*
|
||||
* @package Relevanssi Premium
|
||||
* @author Mikko Saari
|
||||
* @license https://wordpress.org/about/gpl/ GNU General Public License
|
||||
* @see https://www.relevanssi.com/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Uninstalls Relevanssi Premium.
|
||||
*
|
||||
* Deletes all options and removes database tables.
|
||||
*
|
||||
* @global object $wpdb The WordPress database interface.
|
||||
*/
|
||||
function relevanssi_uninstall() {
|
||||
delete_option( 'relevanssi_admin_search' );
|
||||
delete_option( 'relevanssi_api_key' );
|
||||
delete_option( 'relevanssi_bg_col' );
|
||||
delete_option( 'relevanssi_body_stopwords' );
|
||||
delete_option( 'relevanssi_cat' );
|
||||
delete_option( 'relevanssi_class' );
|
||||
delete_option( 'relevanssi_click_tracking' );
|
||||
delete_option( 'relevanssi_comment_boost' );
|
||||
delete_option( 'relevanssi_content_boost' );
|
||||
delete_option( 'relevanssi_css' );
|
||||
delete_option( 'relevanssi_db_version' );
|
||||
delete_option( 'relevanssi_default_orderby' );
|
||||
delete_option( 'relevanssi_disable_or_fallback' );
|
||||
delete_option( 'relevanssi_disable_shortcodes' );
|
||||
delete_option( 'relevanssi_do_not_call_home' );
|
||||
delete_option( 'relevanssi_doc_count' );
|
||||
delete_option( 'relevanssi_exact_match_bonus' );
|
||||
delete_option( 'relevanssi_excat' );
|
||||
delete_option( 'relevanssi_excerpt_allowable_tags' );
|
||||
delete_option( 'relevanssi_excerpt_custom_fields' );
|
||||
delete_option( 'relevanssi_excerpt_length' );
|
||||
delete_option( 'relevanssi_excerpt_specific_fields' );
|
||||
delete_option( 'relevanssi_excerpt_type' );
|
||||
delete_option( 'relevanssi_excerpts' );
|
||||
delete_option( 'relevanssi_exclude_posts' );
|
||||
delete_option( 'relevanssi_expand_highlights' );
|
||||
delete_option( 'relevanssi_expand_shortcodes' );
|
||||
delete_option( 'relevanssi_extag' );
|
||||
delete_option( 'relevanssi_fuzzy' );
|
||||
delete_option( 'relevanssi_hide_branding' );
|
||||
delete_option( 'relevanssi_hide_post_controls' );
|
||||
delete_option( 'relevanssi_highlight' );
|
||||
delete_option( 'relevanssi_highlight_comments' );
|
||||
delete_option( 'relevanssi_highlight_docs' );
|
||||
delete_option( 'relevanssi_hilite_title' );
|
||||
delete_option( 'relevanssi_implicit_operator' );
|
||||
delete_option( 'relevanssi_index' );
|
||||
delete_option( 'relevanssi_index_author' );
|
||||
delete_option( 'relevanssi_index_comments' );
|
||||
delete_option( 'relevanssi_index_excerpt' );
|
||||
delete_option( 'relevanssi_index_fields' );
|
||||
delete_option( 'relevanssi_index_limit' );
|
||||
delete_option( 'relevanssi_index_pdf_parent' );
|
||||
delete_option( 'relevanssi_index_post_type_archives' );
|
||||
delete_option( 'relevanssi_index_post_types' );
|
||||
delete_option( 'relevanssi_index_subscribers' );
|
||||
delete_option( 'relevanssi_index_synonyms' );
|
||||
delete_option( 'relevanssi_index_taxonomies' );
|
||||
delete_option( 'relevanssi_index_taxonomies_list' );
|
||||
delete_option( 'relevanssi_index_terms' );
|
||||
delete_option( 'relevanssi_index_user_fields' );
|
||||
delete_option( 'relevanssi_index_user_meta' );
|
||||
delete_option( 'relevanssi_index_users' );
|
||||
delete_option( 'relevanssi_indexed' );
|
||||
delete_option( 'relevanssi_internal_links' );
|
||||
delete_option( 'relevanssi_link_boost' );
|
||||
delete_option( 'relevanssi_link_pdf_files' );
|
||||
delete_option( 'relevanssi_log_queries' );
|
||||
delete_option( 'relevanssi_log_queries_with_ip' );
|
||||
delete_option( 'relevanssi_max_excerpts' );
|
||||
delete_option( 'relevanssi_min_word_length' );
|
||||
delete_option( 'relevanssi_mysql_columns' );
|
||||
delete_option( 'relevanssi_omit_from_logs' );
|
||||
delete_option( 'relevanssi_polylang_all_languages' );
|
||||
delete_option( 'relevanssi_post_type_ids' );
|
||||
delete_option( 'relevanssi_post_type_weights' );
|
||||
delete_option( 'relevanssi_punctuation' );
|
||||
delete_option( 'relevanssi_read_new_files' );
|
||||
delete_option( 'relevanssi_recency_bonus' );
|
||||
delete_option( 'relevanssi_redirects' );
|
||||
delete_option( 'relevanssi_related_settings' );
|
||||
delete_option( 'relevanssi_related_style' );
|
||||
delete_option( 'relevanssi_respect_exclude' );
|
||||
delete_option( 'relevanssi_searchblogs' );
|
||||
delete_option( 'relevanssi_searchblogs_all' );
|
||||
delete_option( 'relevanssi_send_pdf_files' );
|
||||
delete_option( 'relevanssi_server_location' );
|
||||
delete_option( 'relevanssi_show_matches' );
|
||||
delete_option( 'relevanssi_show_matches_text' );
|
||||
delete_option( 'relevanssi_show_post_controls' );
|
||||
delete_option( 'relevanssi_spamblock' );
|
||||
delete_option( 'relevanssi_synonyms' );
|
||||
delete_option( 'relevanssi_taxterm_count' );
|
||||
delete_option( 'relevanssi_terms_count' );
|
||||
delete_option( 'relevanssi_thousand_separator' );
|
||||
delete_option( 'relevanssi_throttle' );
|
||||
delete_option( 'relevanssi_throttle_limit' );
|
||||
delete_option( 'relevanssi_title_boost' );
|
||||
delete_option( 'relevanssi_trim_click_logs' );
|
||||
delete_option( 'relevanssi_trim_logs' );
|
||||
delete_option( 'relevanssi_txt_col' );
|
||||
delete_option( 'relevanssi_update_translations' );
|
||||
delete_option( 'relevanssi_user_count' );
|
||||
delete_option( 'relevanssi_words' );
|
||||
delete_option( 'relevanssi_wpml_only_current' );
|
||||
|
||||
global $wpdb;
|
||||
$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_hide_post'" );
|
||||
$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_hide_content'" );
|
||||
$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_pin_for_all'" );
|
||||
$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_pin'" );
|
||||
$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_pin_weights'" );
|
||||
$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_unpin'" );
|
||||
$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_pdf_content'" );
|
||||
$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_pdf_error'" );
|
||||
$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_pdf_modified'" );
|
||||
$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_related_keywords'" );
|
||||
$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_related_posts'" );
|
||||
$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_related_include_ids'" );
|
||||
$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_related_exclude_ids'" );
|
||||
$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_related_no_append'" );
|
||||
$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_related_not_related'" );
|
||||
$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_noindex_reason'" );
|
||||
|
||||
// Unused options, removed in case they are still left.
|
||||
delete_option( 'relevanssi_cache_seconds' );
|
||||
delete_option( 'relevanssi_custom_types' );
|
||||
delete_option( 'relevanssi_enable_cache' );
|
||||
delete_option( 'relevanssi_hidesponsor' );
|
||||
delete_option( 'relevanssi_index_attachments' );
|
||||
delete_option( 'relevanssi_index_drafts' );
|
||||
delete_option( 'relevanssi_index_limit' );
|
||||
delete_option( 'relevanssi_index_type' );
|
||||
delete_option( 'relevanssi_show_matches_txt' );
|
||||
delete_option( 'relevanssi_tag_boost' );
|
||||
delete_option( 'relevanssi_include_cats' );
|
||||
delete_option( 'relevanssi_include_tags' );
|
||||
delete_option( 'relevanssi_custom_taxonomies' );
|
||||
delete_option( 'relevanssi_taxonomies_to_index' );
|
||||
delete_option( 'relevanssi_highlight_docs_external' );
|
||||
delete_option( 'relevanssi_word_boundaries' );
|
||||
|
||||
if ( ! defined( 'UNINSTALLING_RELEVANSSI_PREMIUM' ) ) {
|
||||
// The if clause is required to avoid nagging from testing.
|
||||
define( 'UNINSTALLING_RELEVANSSI_PREMIUM', true );
|
||||
}
|
||||
|
||||
wp_clear_scheduled_hook( 'relevanssi_update_counts' );
|
||||
|
||||
relevanssi_drop_database_tables();
|
||||
}
|
||||
Reference in New Issue
Block a user