Upgrade Search & Filter Pro

Signed-off-by: Chris Abraham <cjyabraham@gmail.com>
This commit is contained in:
Chris Abraham 2025-04-03 20:34:39 +07:00
parent 611f741217
commit cc2f980e94
No known key found for this signature in database
GPG Key ID: 60A2BD1DA7D4B0F0
9 changed files with 801 additions and 22 deletions

View File

@ -3,8 +3,8 @@ Contributors: DesignsAndCode, CodeAmp
Donate link:
Tags: posts, custom posts, products, category, filter, taxonomy, post meta, custom fields, search, wordpress, post type, post date, author
Requires at least: 5.1
Tested up to: 6.6
Stable tag: 2.5.19
Tested up to: 6.7
Stable tag: 2.5.21
Search and Filtering for posts, products and custom posts. Allow your users to Search & Filter by taxonomies, custom fields and more.
@ -57,6 +57,18 @@ Great for searching in your online shop, tested with: WooCommerce and WP eCommer
== Changelog ==
= 2.5.21 =
* Compatibility + tested upto WP 6.7
* Fix - a E_PARSE PHP error in the admin screen.
= 2.5.20 =
* Important - security fix - prevent subscribers from accessing post meta data (thanks to Tom Broucke for the discovery and Wordfence for disclosure).
* Important - this update changes the URLs used to receive plugin updates - it is advised to update as soon as possible.
* Update WooCommerce and WordPress core supported versions.
* Fix - PHP notice when using meta_date_value_current_date.
* Fix - change URL for the update server + show an error message if it's not possible to connect.
* Fix - license status was not reflecting renewals in the dashboard.
= 2.5.19 =
* Update WooCommerce and WordPress core supported versions.

View File

@ -36,7 +36,7 @@ function search_filter_plugin_updater() {
// setup the updater
$edd_updater = new SF_EDD_SL_Plugin_Updater(
SEARCH_FILTER_STORE_URL,
Search_Filter_Admin_License_Server::get_endpoint(),
SEARCH_FILTER_PRO_BASE_PATH,
array(
'version' => SEARCH_FILTER_VERSION, // current version number
@ -80,7 +80,8 @@ class Search_Filter_Admin {
*/
protected $widget_screen_admin = null;
protected $plugin_slug = null;
protected $license_server = null;
private $cache_table_name = '';
private $term_results_table_name = '';
@ -129,6 +130,7 @@ class Search_Filter_Admin {
add_action( 'admin_notices', array( $this, 'action_display_welcome_header' ) );
$this->admin_notices = new Search_Filter_Admin_Notices( $this->plugin_slug );
add_action( 'admin_head', array( $this, 'action_setup_screens' ) );
@ -488,6 +490,17 @@ class Search_Filter_Admin {
}
public function display_plugin_license_settings_admin_page() {
// Run the license server test and redirect back to the license page.
if ( isset( $_GET['action'] ) ) {
if ( $_GET['action'] == 'test-connection' ) {
$is_healthy = Search_Filter_Admin_License_Server::check_server_health();
$status = $is_healthy ? 'success' : 'error';
wp_redirect( admin_url( 'edit.php?post_type=search-filter-widget&page=search-filter-licence-settings&status=' . $status ) );
exit;
}
}
$license = get_option( 'search_filter_license_key' );
$status = get_option( 'search_filter_license_status' );
$expires = get_option( 'search_filter_license_expires' );
@ -565,8 +578,9 @@ class Search_Filter_Admin {
$api_params = array(
'edd_action' => 'activate_license',
'license' => $license,
'item_name' => urlencode( SEARCH_FILTER_ITEM_NAME ), // the name of our product in EDD
'item_id' => 615,
'url' => home_url(),
'info' => Search_Filter_Admin_License_Server::get_site_info(),
);
// Call the custom API.
@ -585,7 +599,7 @@ class Search_Filter_Admin {
// decode the license data
$license_data = json_decode( wp_remote_retrieve_body( $response ) );
// $license_data->license will be either "valid" or "invalid"
$license_status = 'invalid';
if ( property_exists( $license_data, 'license' ) ) {
@ -633,8 +647,9 @@ class Search_Filter_Admin {
$api_params = array(
'edd_action' => 'deactivate_license',
'license' => $license,
'item_name' => urlencode( SEARCH_FILTER_ITEM_NAME ), // the name of our product in EDD
'item_id' => 615,
'url' => home_url(),
'info' => Search_Filter_Admin_License_Server::get_site_info(),
);
// Call the custom API.
@ -646,6 +661,7 @@ class Search_Filter_Admin {
)
);
// make sure the response came back okay
if ( is_wp_error( $response ) ) {
return false;
@ -658,8 +674,9 @@ class Search_Filter_Admin {
if ( $license_data->license == 'deactivated' ) {
delete_option( 'search_filter_license_status' );
}
delete_option( 'search_filter_license_error' );
delete_option( 'search_filter_license_expires' );
delete_option( 'search_filter_license_error' );
delete_option( 'search_filter_license_expires' );
}
}
@ -691,6 +708,9 @@ class Search_Filter_Admin {
exit;
}
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( __( 'You do not have sufficient permissions to access this page.', 'search-filter-pro' ) );
}
$run_method = esc_attr( $_GET['method'] );
$cache_options = get_option( 'search-filter-cache' );
@ -766,11 +786,17 @@ class Search_Filter_Admin {
}
function get_meta_values() {
// global $woocommerce;
global $current_user;
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( __( 'You do not have sufficient permissions to access this page.', 'search-filter-pro' ) );
}
$meta_key = sanitize_text_field( $_POST['meta_key'] );
// $meta_key = sanitize_text_field($_GET['meta_key']);
$meta_key = '';
if ( isset( $_POST['meta_key'] ) ) {
$meta_key = sanitize_text_field( $_POST['meta_key'] );
} else {
wp_die( __( 'No meta key provided.', 'search-filter-pro' ) );
}
global $wpdb;
$data = array();
@ -831,10 +857,11 @@ class Search_Filter_Admin {
}
function get_taxonomy_terms() {
// global $woocommerce;
global $current_user;
// $meta_key = sanitize_key($_GET['meta_key']);
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( __( 'You do not have sufficient permissions to access this page.', 'search-filter-pro' ) );
}
$tax_name = sanitize_key( $_GET['taxonomy_name'] );
$tax_ids = esc_attr( $_GET['taxonomy_ids'] );

View File

@ -0,0 +1,372 @@
<?php
/**
* Handles license server endpoint selection and health checks.
*
* @link https://searchandfilter.com
* @since 3.0.0
*
* @package Search_Filter_Pro
* @subpackage Search_Filter_Pro/Core
*/
// If this file is called directly, abort.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Handles license server availability checks and endpoint selection.
*/
class Search_Filter_Admin_License_Server {
/**
* License server endpoints
*/
const SERVER_ENDPOINTS = array(
'license' => 'https://license.searchandfilter.com',
'main' => 'https://searchandfilter.com',
);
/**
* The cron hook name.
*/
const CRON_HOOK = 'search-filter-pro/core/license-server/health-check';
/**
* The cron interval name.
*/
const CRON_INTERVAL_NAME = 'search_filter_4days';
/**
* The cron interval.
*/
const CRON_INTERVAL = DAY_IN_SECONDS * 4;
/**
* The option name for storing the server test results.
*/
const OPTION_TEST_RESULTS = 'search_filter_license_server_test';
/**
* Initialize the license server checks.
*/
public static function init() {
// Setup CRON job for checking for expired items.
add_action( 'init', array( __CLASS__, 'validate_cron_schedule' ) );
// Create the schedule
add_filter( 'cron_schedules', array( __CLASS__, 'schedules' ) );
// Add the cron job action
add_action( self::CRON_HOOK, array( __CLASS__, 'schedule_check_server_health' ) );
// Add notices when there are errors with connecting to the servers.
add_action( 'init', array( __CLASS__, 'add_notices' ) );
}
/**
* Get the preferred server endpoint.
*
* @return string The server endpoint URL
*/
public static function get_endpoint( $preferred_server = 'license' ) {
return self::SERVER_ENDPOINTS[ $preferred_server ];
}
/**
* Setup the interval for the cron job.
*
* @param array $schedules The existing cron schedules.
* @return array Modified cron schedules.
*/
public static function schedules( $schedules ) {
if ( ! isset( $schedules[ self::CRON_INTERVAL_NAME ] ) ) {
$schedules[ self::CRON_INTERVAL_NAME ] = array(
'interval' => self::CRON_INTERVAL,
'display' => __( 'Once every 4 days', 'search-filter-pro' ),
);
}
return $schedules;
}
/**
* Activate the cron job.
*/
public static function activate() {
if ( ! wp_next_scheduled( self::CRON_HOOK ) ) {
wp_schedule_event( time(), self::CRON_INTERVAL_NAME, self::CRON_HOOK );
}
}
/**
* Deactivate the cron job.
*/
public static function deactivate() {
wp_clear_scheduled_hook( self::CRON_HOOK );
}
/**
* Hook the task into shutdown so we don't affect the request.
*/
public static function schedule_check_server_health() {
// Hook the task into shutdown so we don't affect the request.
add_action( 'shutdown', array( __CLASS__, 'check_server_health' ) );
}
/**
* Check the health of both servers and update the preferred endpoint.
*/
public static function check_server_health() {
$license_server_healthy = self::refresh_health();
$result = array(
'license' => $license_server_healthy,
);
// Store the results in the options table.
update_option( self::OPTION_TEST_RESULTS, $result );
return $license_server_healthy;
}
private static function get_php_version() {
if ( function_exists( 'phpversion' ) ) {
return phpversion();
} else if ( defined( 'PHP_VERSION' ) ) {
return PHP_VERSION;
}
return '';
}
public static function get_site_info() {
$site_meta_data = array(
'integrations' => self::get_enabled_integrations(),
'version' => SEARCH_FILTER_VERSION,
'php_version' => self::get_php_version(),
'wp_version' => get_bloginfo( 'version' ),
'site_language' => get_bloginfo( 'language' ),
'is_multisite' => is_multisite(),
);
return $site_meta_data;
}
/**
* Refresh health.
*
* @param string $endpoint The endpoint URL to test.
*/
public static function refresh_health( $preferred_server = 'license' ) {
$api_params = array(
'edd_action' => 'check_license',
'item_id' => 615,
'url' => home_url(),
'license' => '',
'info' => self::get_site_info(),
);
$license_data = self::get_license_data();
if ( ! empty( $license_data['license'] ) ) {
$api_params['license'] = $license_data['license'];
}
$endpoint = self::get_endpoint( $preferred_server );
// Call the custom API.
$response = wp_remote_post(
$endpoint,
array(
'timeout' => 15,
'sslverify' => false,
'body' => $api_params,
)
);
$is_healthy = ! is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) === 200;
if ( is_wp_error( $response ) ) {
return $is_healthy;
}
$body = wp_remote_retrieve_body( $response );
$request_response = json_decode( $body, true );
if ( ! $request_response ) {
return $is_healthy;
}
if ( ! isset( $request_response['success'] ) ) {
return $is_healthy;
}
if ( ! isset( $request_response['license'] ) ) {
return $is_healthy;
}
$expires = $request_response['expires'];
self::update_license_data(
array(
'expires' => $expires,
'status' => $request_response['license'],
'error' => isset( $request_response['error'] ) ? $request_response['error'] : '',
)
);
return $is_healthy;
}
/**
* Get the license data from the options table.
*
* @since 3.0.0
*
* @return array The license data.
*/
public static function get_license_data() {
$default_license_data = array(
'status' => '',
'expires' => '',
'license' => '',
'error' => '',
'errorMessage' => '',
);
$license_data = array(
'status' => get_option( 'search_filter_license_status' ),
'expires' => get_option( 'search_filter_license_expires' ),
'license' => get_option( 'search_filter_license_key' ),
);
if ( $license_data ) {
$license_data = wp_parse_args( $license_data, $default_license_data );
} else {
$license_data = $default_license_data;
}
return $license_data;
}
public static function update_license_data( $new_license_data ) {
$existing_data = self::get_license_data();
$updated_license_data = wp_parse_args( $new_license_data, $existing_data );
update_option( 'search_filter_license_status', $updated_license_data['status'] );
update_option( 'search_filter_license_expires', $updated_license_data['expires'] );
update_option( 'search_filter_license_error', $updated_license_data['error'] );
}
/**
* Validate the cron job.
*
* @since 3.0.0
*/
public static function validate_cron_schedule() {
$next_event = wp_get_scheduled_event( self::CRON_HOOK );
if ( ! $next_event ) {
wp_schedule_event( time(), self::CRON_INTERVAL_NAME, self::CRON_HOOK );
return;
}
$time_diff = $next_event->timestamp - time();
$time_5_minutes = 5 * MINUTE_IN_SECONDS;
if ( $time_diff < 0 && -$time_diff > $time_5_minutes ) {
// This means our scheduled event has been missed by more then 5 minutes.
// So lets run manually and reschedule.
self::schedule_check_server_health();
wp_clear_scheduled_hook( self::CRON_HOOK );
wp_schedule_event( time(), self::CRON_INTERVAL_NAME, self::CRON_HOOK );
}
}
/**
* Add error notices if the license server cannot be reached.
*/
public static function add_notices() {
// Show a notice to the user if there are errors with both servers.
$test_result = get_option( self::OPTION_TEST_RESULTS, array(
'license' => false,
) );
// If the options are empty, then we don't have any test results yet.
if ( empty( $test_result ) ) {
return;
}
// If the license server is healthy, then we don't need to show a notice.
if ( $test_result['license'] === false ) {
// Add WP notice, not S&F notice:
add_action( 'admin_notices', array( __CLASS__, 'display_wp_admin_connection_error_notice' ) );
}
}
public static function display_wp_admin_connection_error_notice() {
if ( isset( $_GET['activate'] ) ) {
unset( $_GET['activate'] );
}
$notice_string = sprintf(
// translators: %s: Support URL.
__( 'Unable to connect to Search & Filter update servers. Please check your internet connection or firewall settings. <a href="%s">Test your connection settings</a> or <a href="%s" target="_blank">contact support for help</a>.', 'search-filter-pro' ),
admin_url( 'edit.php?post_type=search-filter-widget&page=search-filter-licence-settings&action=test-connection' ),
'https://searchandfilter.com/account/support/'
);
printf( '<div class="notice notice-error"><p>%1$s</p></div>', wp_kses_post( $notice_string ) );
}
public static function get_enabled_integrations() {
$integrations = array();
// Relevanssi
global $relevanssi_variables;
if ( ! empty( $relevanssi_variables ) ) {
$integrations[] = 'relevanssi';
}
// WooCommerce
if ( class_exists( 'WooCommerce' ) ) {
$integrations[] = 'woocommerce';
}
// Elementor
if ( did_action( 'elementor/loaded' ) ) {
$integrations[] = 'elementor';
}
// Dynamic Content for Elementor
if ( class_exists( 'DynamicContentForElementor\Plugin' ) ) {
$integrations[] = 'dynamiccontent';
}
// Polylang
if ( defined( 'POLYLANG_VERSION' ) ) {
$integrations[] = 'polylang';
}
// WPML
if ( has_filter( 'wpml_object_id' ) || function_exists( 'icl_object_id' ) ) {
$integrations[] = 'wpml';
}
// ACF
if ( class_exists( 'ACF' ) ) {
$integrations[] = 'acf';
}
// Beaver Builder
if ( defined( 'FL_BUILDER_VERSION' ) ) {
$integrations[] = 'beaverbuilder';
}
// Easy Digital Downloads
if ( function_exists( '\EDD' ) ) {
$integrations[] = 'edd';
}
// Divi
if ( defined( 'ET_BUILDER_VERSION' ) ) {
$integrations[] = 'divi';
}
// WP Bakery Page Builder
if ( defined( 'WPB_VC_VERSION' ) ) {
$integrations[] = 'wpbpb';
}
return $integrations;
}
}

View File

@ -0,0 +1,342 @@
<?php
/**
* Handles license server endpoint selection and health checks.
*
* @link https://searchandfilter.com
* @since 3.0.0
*
* @package Search_Filter_Pro
* @subpackage Search_Filter_Pro/Core
*/
// If this file is called directly, abort.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Handles license server availability checks and endpoint selection.
*/
class Search_Filter_Remote_Notices {
/**
* The cron hook name.
*/
const CRON_HOOK = 'search-filter-pro/core/notices/fetch';
/**
* The cron interval name.
*/
const CRON_INTERVAL_NAME = 'search_filter_3days';
/**
* The cron interval.
*/
const CRON_INTERVAL = DAY_IN_SECONDS * 7;
/**
* The option name for storing the server test results.
*/
const OPTION_NOTICES = 'search_filter_remote_notices';
const OPTION_NOTICES_DISMISSED = 'search_filter_notices_dismissed';
/**
* Initialize the remote notices.
*/
public static function init() {
// Setup CRON job for checking for expired items.
add_action( 'init', array( __CLASS__, 'validate_cron_schedule' ) );
// Create the schedule
add_filter( 'cron_schedules', array( __CLASS__, 'schedules' ) );
// Add the cron job action
add_action( self::CRON_HOOK, array( __CLASS__, 'schedule_fetch' ) );
// Add notices.
add_action( 'admin_notices', array( __CLASS__, 'display_wp_admin_remote_notice' ) );
add_action( 'admin_footer', array( __CLASS__, 'handle_dismiss_notice_js' ) );
// Handle the ajax action.
add_action( 'wp_ajax_search_filter_dismiss_notice', array( __CLASS__, 'handle_dismiss_notice' ) );
add_action( 'wp_ajax_nopriv_search_filter_dismiss_notice', array( __CLASS__, 'handle_dismiss_notice' ) );
}
/**
* Setup the interval for the cron job.
*
* @param array $schedules The existing cron schedules.
* @return array Modified cron schedules.
*/
public static function schedules( $schedules ) {
if ( ! isset( $schedules[ self::CRON_INTERVAL_NAME ] ) ) {
$schedules[ self::CRON_INTERVAL_NAME ] = array(
'interval' => self::CRON_INTERVAL,
'display' => __( 'Once every 3 days', 'search-filter-pro' ),
);
}
return $schedules;
}
/**
* Activate the cron job.
*/
public static function activate() {
if ( ! wp_next_scheduled( self::CRON_HOOK ) ) {
wp_schedule_event( time(), self::CRON_INTERVAL_NAME, self::CRON_HOOK );
}
}
/**
* Deactivate the cron job.
*/
public static function deactivate() {
wp_clear_scheduled_hook( self::CRON_HOOK );
}
/**
* Hook the task into shutdown so we don't affect the request.
*/
public static function schedule_fetch() {
// Hook the task into shutdown so we don't affect the request.
add_action( 'shutdown', array( __CLASS__, 'fetch' ) );
}
/**
* Refresh health.
*
* @param string $endpoint The endpoint URL to test.
*/
public static function fetch() {
$api_params = array(
'edd_action' => 'get_notices',
'item_id' => 526297,
'url' => home_url(),
'license' => '',
);
$license_data = Search_Filter_Admin_License_Server::get_license_data();
if ( ! empty( $license_data['license'] ) ) {
$api_params['license'] = $license_data['license'];
}
$endpoint = Search_Filter_Admin_License_Server::get_endpoint();
// Call the custom API.
$response = wp_remote_post(
$endpoint,
array(
'timeout' => 15,
'sslverify' => false,
'body' => $api_params,
)
);
if ( is_wp_error( $response ) ) {
return;
}
$body = wp_remote_retrieve_body( $response );
$code = wp_remote_retrieve_response_code( $response );
if ( $code < 200 || $code >= 300 ) {
return;
}
$notice_response = json_decode( $body, true );
// No message broadcasted.
if ( empty( $notice_response ) ) {
update_option( self::OPTION_NOTICES, array() );
return;
}
// Validate notice before saving.
if ( ! self::validate_notice( $notice_response ) ) {
return;
}
// Sanitize each $key and $value in the $notice_response array.
foreach( $notice_response as $key => $value ) {
if ( is_bool( $value ) ) {
$notice_response[ sanitize_text_field( $key ) ] = (bool) $value;
} else {
$notice_response[ sanitize_text_field( $key ) ] = sanitize_text_field( $value );
}
}
update_option( self::OPTION_NOTICES, $notice_response );
return;
}
private static function validate_notice( $notice ) {
if ( ! is_array( $notice ) ) {
return false;
}
$allowed_keys = array( 'id', 'message', 'type', 'actionText', 'actionLink', 'dismissible' );
$received_keys = array_keys( $notice );
// Don't allow extra keys.
foreach( $received_keys as $key ) {
if ( ! in_array( $key, $allowed_keys ) ) {
return false;
}
}
// Ensure at least id, message and type are set.
if ( ! isset( $notice['id'] ) ) {
return false;
}
if ( ! isset( $notice['message'] ) ) {
return false;
}
if ( ! isset( $notice['type'] ) ) {
return false;
}
return $notice;
}
/**
* Validate the cron job.
*
* @since 3.0.0
*/
public static function validate_cron_schedule() {
$next_event = wp_get_scheduled_event( self::CRON_HOOK );
if ( ! $next_event ) {
wp_schedule_event( time(), self::CRON_INTERVAL_NAME, self::CRON_HOOK );
return;
}
$time_diff = $next_event->timestamp - time();
$time_5_minutes = 5 * MINUTE_IN_SECONDS;
if ( $time_diff < 0 && -$time_diff > $time_5_minutes ) {
// This means our scheduled event has been missed by more then 5 minutes.
// So lets run manually and reschedule.
self::schedule_fetch();
wp_clear_scheduled_hook( self::CRON_HOOK );
wp_schedule_event( time(), self::CRON_INTERVAL_NAME, self::CRON_HOOK );
}
}
/**
* Add error notices if the license server cannot be reached.
*/
public static function display_wp_admin_remote_notice() {
$remote_notices = get_option( self::OPTION_NOTICES );
if ( empty( $remote_notices ) ) {
return;
}
if ( ! self::validate_notice( $remote_notices ) ) {
return;
}
$dismissed_notices = self::get_dismissed_notices();
$notice_id = 'search-filter-remote-notice-' . sanitize_key( $remote_notices['id'] );
if ( in_array( $notice_id, $dismissed_notices, true ) ) {
return;
}
$notice_string = wp_kses_post( $remote_notices['message'] );
$dismissible = isset( $remote_notices['dismissible'] ) ? $remote_notices['dismissible'] : true;
$notice_action = '';
if ( isset( $remote_notices['actionText'], $remote_notices['actionLink'] ) ) {
$notice_action = sprintf(
' <a href="%s" class="button button-secondary">%s</a>',
esc_url( $remote_notices['actionLink'] ),
esc_html( $remote_notices['actionText'], 'search-filter-pro' )
);
}
$type = isset( $remote_notices['type'] ) ? $remote_notices['type'] : 'info';
// Add notices when there are errors with connecting to the servers.
if ( isset( $_GET['activate'] ) ) {
unset( $_GET['activate'] );
}
$notice_string = $notice_string . $notice_action;
$notice_class = sanitize_html_class( 'notice-' . $type );
if ( $dismissible ) {
$notice_class = $notice_class . ' is-dismissible';
}
wp_admin_notice(
wp_kses_post( $notice_string ),
array(
'type' => $type,
'dismissible' => $dismissible,
'additional_classes' => array( 'search-filter-pro-notice' ),
'attributes' => array( 'data-notice-id' => $notice_id )
)
);
}
public static function get_dismissed_notices() {
$dismissed_notices = get_option( self::OPTION_NOTICES_DISMISSED );
if ( ! is_array( $dismissed_notices ) ) {
$dismissed_notices = array();
}
return $dismissed_notices;
}
public static function handle_dismiss_notice() {
if ( ! isset( $_GET['action'] ) ) {
return;
}
if ( $_GET['action'] !== 'search_filter_dismiss_notice' ) {
return;
}
if ( ! isset( $_GET['notice_id'] ) ) {
wp_send_json( array( 'success' => false ) );
}
if ( ! wp_verify_nonce( $_GET['nonce'], 'search_filter_dismiss_notice' ) ) {
wp_send_json( array( 'success' => false ) );
}
$notice_name = sanitize_key( $_GET['notice_id'] );
$dismissed_notices = get_option( self::OPTION_NOTICES_DISMISSED );
if ( ! is_array( $dismissed_notices ) ) {
$dismissed_notices = array();
}
if ( ! in_array( $notice_name, $dismissed_notices, true ) ) {
$dismissed_notices[] = $notice_name;
update_option( self::OPTION_NOTICES_DISMISSED, $dismissed_notices );
}
wp_send_json( array( 'success' => true ) );
}
public static function handle_dismiss_notice_js() {
$query_args = array(
'action' => 'search_filter_dismiss_notice',
'nonce' => wp_create_nonce( 'search_filter_dismiss_notice' ),
);
$ajax_url = add_query_arg( $query_args, admin_url( 'admin-ajax.php' ) );
?>
<script type="text/javascript">
jQuery( document ).ready( function( $ ) {
$( '.search-filter-pro-notice' ).on( 'click', '.notice-dismiss', function() {
var notice_id = $( this ).closest( '.search-filter-pro-notice' ).data( 'notice-id' );
// Send via ajax.
var url = '<?php echo $ajax_url; ?>' + '&notice_id=' + notice_id;
$.ajax( {
url: url,
type: 'GET',
success: function( response ) {
console.log( response );
}
} );
} );
} );
</script>
<?php
}
}

View File

@ -114,6 +114,17 @@ if ( ! defined( 'ABSPATH' ) ) {
</td>
</tr>
<?php } ?>
<tr valign="top">
<th scope="row" valign="top">
<?php _e('Test connection'); ?>
</th>
<td>
<?php wp_nonce_field( 'search_filter_nonce', 'search_filter_nonce' ); ?>
<a href="<?php echo esc_url( admin_url( 'edit.php?post_type=search-filter-widget&page=search-filter-licence-settings&action=test-connection' ) ); ?>" class="button-tertiary">
<?php _e('Test connection'); ?>
</a>
</td>
</tr>
</tbody>
</table>

View File

@ -40,7 +40,8 @@ class Search_Filter_Activator {
public function activate( $network_wide ) {
global $wpdb;
Search_Filter_Admin_License_Server::activate();
Search_Filter_Remote_Notices::activate();
if ( is_multisite() && $network_wide ) {
// store the current blog id
$current_blog = $wpdb->blogid;

View File

@ -25,7 +25,8 @@ class Search_Filter_Deactivator {
* @since 1.0.0
*/
public static function deactivate() {
Search_Filter_Admin_License_Server::deactivate();
Search_Filter_Remote_Notices::deactivate();
}
}

View File

@ -1403,7 +1403,7 @@ class Search_Filter_Query {
}
if ( $post_meta['meta_type'] == 'DATE' ) {
if ( $post_meta['meta_date_value_current_date'] == 1 ) {
if ( isset( $post_meta['meta_date_value_current_date'] ) && $post_meta['meta_date_value_current_date'] == 1 ) {
$meta_query = array(
'key' => $post_meta['meta_key'],
@ -1421,7 +1421,7 @@ class Search_Filter_Query {
);
}
} elseif ( $post_meta['meta_type'] == 'TIMESTAMP' ) {
if ( $post_meta['meta_date_value_current_timestamp'] == 1 ) {
if ( isset( $post_meta['meta_date_value_current_timestamp'] ) && $post_meta['meta_date_value_current_timestamp'] == 1 ) {
$meta_query = array(
'key' => $post_meta['meta_key'],

View File

@ -11,7 +11,7 @@
* Plugin Name: Search & Filter Pro
* Plugin URI: https://searchandfilter.com
* Description: Search & Filtering for posts, products and custom posts. Allow your users to Search & Filter by categories, tags, taxonomies, custom fields, post meta, post dates, post types and authors.
* Version: 2.5.19
* Version: 2.5.21
* Author: Code Amp
* Author URI: http://www.codeamp.com
* Developer: Code Amp
@ -19,10 +19,11 @@
* Text Domain: search-filter
* License: GPL-2.0+
* License URI: http://www.gnu.org/licenses/gpl-2.0.html
* Update URI: https://searchandfilter.com
* Domain Path: /languages
*
* WC requires at least: 8.1
* WC tested up to: 9.1
* WC tested up to: 9.7
*/
// If this file is called directly, abort.
@ -38,13 +39,25 @@ if ( ! defined( 'SEARCH_FILTER_QUERY_DEBUG' ) ) {
}
if ( ! defined( 'SEARCH_FILTER_VERSION' ) ) {
define( 'SEARCH_FILTER_VERSION', '2.5.19' );
define( 'SEARCH_FILTER_VERSION', '2.5.21' );
}
if ( ! defined( 'SEARCH_FILTER_PRO_BASE_PATH' ) ) {
define( 'SEARCH_FILTER_PRO_BASE_PATH', __FILE__ );
}
if ( ! class_exists( 'Search_Filter_Admin_License_Server' ) ) {
require_once plugin_dir_path( __FILE__ ) . 'admin/includes/class-search-filter-admin-license-server.php';
}
// Check to make sure we can connect to the S&F update servers.
Search_Filter_Admin_License_Server::init();
if ( ! class_exists( 'Search_Filter_Remote_Notices' ) ) {
require_once plugin_dir_path( __FILE__ ) . 'admin/includes/class-search-filter-remote-notices.php';
}
Search_Filter_Remote_Notices::init();
/*
----------------------------------------------------------------------------*
* Public-Facing Functionality