diff --git a/web/wp-content/plugins/search-filter-pro/README.txt b/web/wp-content/plugins/search-filter-pro/README.txt index 2d3ae7c1..81b673d6 100644 --- a/web/wp-content/plugins/search-filter-pro/README.txt +++ b/web/wp-content/plugins/search-filter-pro/README.txt @@ -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. diff --git a/web/wp-content/plugins/search-filter-pro/admin/class-search-filter-admin.php b/web/wp-content/plugins/search-filter-pro/admin/class-search-filter-admin.php index ba7daa1e..4590c70d 100644 --- a/web/wp-content/plugins/search-filter-pro/admin/class-search-filter-admin.php +++ b/web/wp-content/plugins/search-filter-pro/admin/class-search-filter-admin.php @@ -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'] ); diff --git a/web/wp-content/plugins/search-filter-pro/admin/includes/class-search-filter-admin-license-server.php b/web/wp-content/plugins/search-filter-pro/admin/includes/class-search-filter-admin-license-server.php new file mode 100644 index 00000000..2ab8cf6d --- /dev/null +++ b/web/wp-content/plugins/search-filter-pro/admin/includes/class-search-filter-admin-license-server.php @@ -0,0 +1,372 @@ + '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. Test your connection settings or contact support for help.', '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( '
%1$s