OwlCyberSecurity - MANAGER
Edit File: class-vc-notice-controller.php
<?php /** * Autoload notice controller. * * @note we require our autoload files everytime and everywhere after plugin load. * @since 7.0 */ if ( ! defined( 'ABSPATH' ) ) { die( '-1' ); } /** * Controller for plugin notice system. * * @description: We use it to notify users about, * emergency updates, new features and some promotions stuff etc. * * @since 7.0 */ class Vc_Notice_Controller { /** * Notification API URL. * * @version 7.0 * @var string */ protected $notification_api_url = 'https://support.wpbakery.com/api/external/notifications'; /** * The slug of transient that stores notice list that we show to user. * * @var string */ public $transient_notice_list = 'wpb_notice_list'; /** * The slug of user meta that stores notice list that user close. * * @var string */ public $user_notice_close_list = 'wpb_notice_close_list'; /** * Vc_Notice_Controller constructor. * * @since 7.0 */ public function __construct() { add_action( 'admin_init', [ $this, 'init', ] ); add_action( 'wp_ajax_wpb_add_notice_to_close_list', [ $this, 'add_notice_to_close_list' ] ); } /** * Init notice system. * * @since 7.0 */ public function init() { $notice_list = $this->get_notice_list(); $this->show_notices( $notice_list ); } /** * Show notices to user. * * @since 7.0 * @param mixed $notice_list */ public function show_notices( $notice_list ) { if ( empty( $notice_list ) || ! is_array( $notice_list ) ) { return; } // last api request was empty or failed. if ( $this->is_api_response_empty( $notice_list ) ) { return; } $is_show_at_least_one_notice = false; foreach ( $notice_list as $notice ) { if ( ! $this->is_notice_valid( $notice ) ) { continue; } if ( ! $this->is_show_notice( $notice['id'] ) ) { continue; } $this->output_notice( $notice ); $is_show_at_least_one_notice = true; } if ( $is_show_at_least_one_notice ) { add_action( 'admin_notices', function () { vc_include_template( 'params/notice/notice-assets.php' ); } ); } } /** * Check if notice is valid. * * @since 7.0 * @param mixed $notice * @return bool */ public function is_notice_valid( $notice ) { if ( empty( $notice ) || ! is_array( $notice ) ) { return false; } if ( ! $this->is_notice_version_valid( $notice ) ) { return false; } // phpcs:ignore if ( ! $this->is_notice_date_valid( $notice, current_time( 'timestamp' ) ) ) { return false; } if ( ! $this->is_notice_content_valid( $notice ) ) { return false; } return true; } /** * Check if we should show notice. * * @note we don't show notice if user already closed it. * * @since 7.0 * @param int $notice_id * @return bool */ public function is_show_notice( $notice_id ) { $notice_close_list = get_user_meta( get_current_user_id(), $this->user_notice_close_list, true ); if ( empty( $notice_close_list ) ) { return true; } $notice_close_list = is_string( $notice_close_list ) ? json_decode( $notice_close_list ) : []; return ! ( is_array( $notice_close_list ) && in_array( $notice_id, $notice_close_list ) ); } /** * Check if notice can be displayed in current plugin version. * * @since 7.0 * @param array $notice * @param string | false $current_version * @return bool */ public function is_notice_version_valid( $notice, $current_version = false ) { $result = false; if ( empty( $notice['version_from'] ) || empty( $notice['version_to'] ) ) { return $result; } $is_versions_value_valid = version_compare( $notice['version_from'], '0.0.1', '>=' ) && version_compare( $notice['version_to'], '0.0.1', '>=' ); if ( ! $is_versions_value_valid ) { return $result; } if ( ! $current_version ) { if ( ! function_exists( 'get_plugin_data' ) ) { return $result; } $plugin_data = get_plugin_data( WPB_PLUGIN_FILE ); $current_version = $plugin_data['Version']; } $is_version_inside_diapason = version_compare( $notice['version_from'], $current_version, '<=' ) && version_compare( $current_version, $notice['version_to'], '<=' ); if ( $is_version_inside_diapason ) { $result = true; } return $result; } /** * Check if notice can be displayed in current time. * * @since 7.0 * @param array $notice * @param int $current_time * @return bool */ public function is_notice_date_valid( $notice, $current_time ) { $result = false; if ( empty( $notice['date_from'] ) || empty( $notice['date_to'] ) ) { return $result; } $is_date_inside_diapason = ( $current_time >= strtotime( $notice['date_from'] ) ) && ( $current_time <= strtotime( $notice['date_to'] ) ); if ( $is_date_inside_diapason ) { $result = true; } return $result; } /** * Check if notice has content that we can show to user. * * @since 7.0 * @param array $notice * @return bool */ public function is_notice_content_valid( $notice ) { // notice always should have id. if ( empty( $notice['id'] ) ) { return false; } // notice should have at least one element to show. $is_notice_content_empty = empty( $notice['title'] ) && empty( $notice['description'] ) && empty( $notice['image'] ) && empty( $notice['button_text'] ); return $is_notice_content_empty ? false : true; } /** * Output notice to user. * * @since 7.0 * @param array $notice */ public function output_notice( $notice ) { add_action( 'admin_notices', function () use ( $notice ) { vc_include_template( 'params/notice/notice.php', [ 'notice' => $notice ] ); } ); } /** * Get notices that should be displayed. * * @since 7.0 * @return array */ public function get_notice_list() { $notice_list = get_transient( $this->transient_notice_list ); if ( $this->is_api_response_empty( $notice_list ) ) { return []; } if ( ! $this->is_notice_list_valid( $notice_list ) ) { $notice_list = $this->get_notice_list_from_api_request(); $this->save_notice_list_to_transient( $notice_list ); } return json_decode( $notice_list, true ); } /** * Check if api response is empty. * * @param mixed $notice_list */ public function is_api_response_empty( $notice_list ) { return is_array( $notice_list ) && isset( $notice_list['empty_api_response'] ); } /** * Save notice list to transient. * * @since 7.0 * @param string $notice_list */ public function save_notice_list_to_transient( $notice_list ) { if ( ! $this->is_notice_list_valid( $notice_list ) ) { // in case if we have invalid notice list we save false value. // to transient to prevent requests to our API more than 12 hours. $empty = [ 'empty_api_response' => true ]; set_transient( $this->transient_notice_list, $empty, 12 * HOUR_IN_SECONDS ); return; } set_transient( $this->transient_notice_list, $notice_list, 12 * HOUR_IN_SECONDS ); } /** * Check if notice list is valid. * * @since 7.0 * @param mixed $notice_list * @return bool */ public function is_notice_list_valid( $notice_list ) { if ( empty( $notice_list ) ) { return false; } if ( ! is_string( $notice_list ) ) { return false; } json_decode( $notice_list ); return json_last_error() === JSON_ERROR_NONE; } /** * Get notices from notice API. * * @note we fire up request to our API once per 12 hours. * * @since 7.0 * @return string */ public function get_notice_list_from_api_request() { $empty_notice_list = ''; $response = wp_remote_get( $this->build_request_url(), [ 'timeout' => 30 ] ); if ( is_wp_error( $response ) ) { return $empty_notice_list; } if ( wp_remote_retrieve_response_code( $response ) !== 200 ) { return $empty_notice_list; } $response_body = wp_remote_retrieve_body( $response ); if ( $this->is_notice_list_valid( $response_body ) ) { $notice_list = $response_body; } else { $notice_list = $empty_notice_list; } return $notice_list; } /** * Add license key and theme license parameters if it is activated * * @return string */ public function build_request_url() { if ( vc_license()->isActivated() ) { return add_query_arg( 'license_key', vc_license()->getLicenseKey(), $this->notification_api_url ); } if ( vc_is_as_theme() ) { return add_query_arg( 'theme_activated', '1', $this->notification_api_url ); } return $this->notification_api_url; } /** * Add notice to close list. */ public function add_notice_to_close_list() { vc_user_access()->checkAdminNonce()->validateDie(); $notice_id = vc_request_param( 'notice_id' ); if ( empty( $notice_id ) ) { wp_send_json_error( false ); } $is_set = $this->save_notice_to_close_list( $notice_id ); if ( $is_set ) { wp_send_json_success( true ); } else { wp_send_json_error( false ); } } /** * Save notice to close list. * * @param int $notice_id * @return int|bool */ public function save_notice_to_close_list( $notice_id ) { $user_id = get_current_user_id(); $notice_list = json_decode( get_user_meta( $user_id, $this->user_notice_close_list, true ) ); if ( ! is_array( $notice_list ) ) { $notice_list = []; } $notice_id = (int) $notice_id; if ( ! in_array( $notice_id, $notice_list ) ) { $notice_list[] = $notice_id; } return update_user_meta( $user_id, $this->user_notice_close_list, wp_json_encode( $notice_list ) ); } } new Vc_Notice_Controller();