mirror of https://github.com/cncf/cncf.io.git
Upgrade Search & Filter Pro
Signed-off-by: Chris Abraham <cjyabraham@gmail.com>
This commit is contained in:
parent
611f741217
commit
cc2f980e94
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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'] );
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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; ?>' + '¬ice_id=' + notice_id;
|
||||
$.ajax( {
|
||||
url: url,
|
||||
type: 'GET',
|
||||
success: function( response ) {
|
||||
console.log( response );
|
||||
}
|
||||
} );
|
||||
} );
|
||||
} );
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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'],
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue