File "class-itsec-lib-remote-messages.php"
Full Path: /home/siazco/grocery.siazco.se/wp-content/plugins/better-wp-security/core/lib/class-itsec-lib-remote-messages.php
File size: 5.73 KB
MIME-type: text/x-php
Charset: utf-8
<?php
class ITSEC_Lib_Remote_Messages {
const URL = 'https://assets.solidwp.com/public/itsec-service-status.json';
const OPTION = 'itsec_remote_messages';
const EVENT = 'remote-messages';
/** @var array */
private static $_response;
/**
* Initialize the Remote Messages library.
*/
public static function init() {
if ( ITSEC_Core::is_pro() ) {
add_action( 'itsec_scheduled_' . self::EVENT, array( __CLASS__, 'run_event' ) );
}
}
public static function get_actions() {
$response = self::get_response();
return isset( $response['actions'] ) ? $response['actions'] : array();
}
public static function has_action( $action ) {
return in_array( $action, self::get_actions(), true );
}
public static function get_feature( $flag ) {
$response = self::get_response();
return isset( $response['features'][ $flag ] ) ? $response['features'][ $flag ] : null;
}
public static function get_raw_messages() {
$response = self::get_response();
return isset( $response['messages'] ) ? $response['messages'] : array();
}
public static function get_messages_for_placement( $placement ) {
$matched = array();
foreach ( self::get_raw_messages() as $message ) {
if ( in_array( $placement, $message['placement'], true ) ) {
$matched[] = array(
'message' => $message['message'],
'type' => $message['type'],
);
}
}
return $matched;
}
/**
* Run the event to fetch the data.
*
* @param ITSEC_Job $job
*/
public static function run_event( $job ) {
$fetched = self::fetch();
if ( is_wp_error( $fetched ) ) {
$job->reschedule_in( 5 * MINUTE_IN_SECONDS );
return;
}
}
/**
* Fetches and stores the remote messages response.
*
* @return null|WP_Error
*/
public static function fetch() {
$response = wp_remote_get( self::URL, array(
'user-agent' => 'WordPress',
) );
if ( is_wp_error( $response ) ) {
return $response;
}
$data = wp_remote_retrieve_body( $response );
if ( ! $data ) {
return new WP_Error( 'empty_body', __( 'Empty response body.', 'better-wp-security' ) );
}
$json = json_decode( $data, true );
if ( ! $json ) {
return new WP_Error( 'invalid_json', __( 'Invalid json response.', 'better-wp-security' ) );
}
$sanitized = self::sanitize_response( $json );
update_site_option( self::OPTION, array(
'response' => $sanitized,
'ttl' => $sanitized['ttl'],
'requested' => ITSEC_Core::get_current_time_gmt(),
) );
return null;
}
/**
* Sanitizes the JSON response.
*
* @param array $json
*
* @return array
*/
public static function sanitize_response( $json ) {
$json = wp_parse_args( $json, array(
'ttl' => HOUR_IN_SECONDS,
'messages' => array(),
'actions' => array(),
'features' => array(),
) );
$sanitized = array(
'ttl' => absint( $json['ttl'] ),
'messages' => array(),
'features' => array(),
'actions' => wp_parse_slug_list( $json['actions'] ),
);
foreach ( $json['messages'] as $message ) {
$sanitized['messages'][] = array(
'message' => self::sanitize_message( $message['message'] ),
'type' => self::sanitize_type( $message['type'] ),
'placement' => $message['placement'],
);
}
foreach ( $json['features'] as $feature => $f_config ) {
$sanitized['features'][ $feature ] = [
'rate' => isset( $f_config['rate'] ) ? (int) $f_config['rate'] : false,
'disabled' => ! empty( $f_config['disabled'] ),
'requirements' => isset( $f_config['requirements'] ) && is_array( $f_config['requirements'] ) ? $f_config['requirements'] : [],
];
}
return $sanitized;
}
private static function sanitize_message( $message ) {
return wp_kses( $message, array( 'a' => array( 'href' => true ) ) );
}
private static function sanitize_type( $type ) {
if ( in_array( $type, array( 'success', 'info', 'warning', 'error' ), true ) ) {
return $type;
}
return 'info';
}
private static function get_response() {
if ( ! ITSEC_Core::is_pro() ) {
return array();
}
if ( ! isset( self::$_response ) ) {
self::$_response = self::load_response();
}
return apply_filters( 'itsec_remote_messages', self::$_response );
}
/**
* Loads the response from the local cache or the server.
*
* @return array|mixed
*/
private static function load_response() {
$data = self::get_stored_response();
if ( ! $data['response'] ) {
self::schedule_check();
return array();
}
if ( $data['requested'] + $data['ttl'] < ITSEC_Core::get_current_time_gmt() ) {
self::schedule_check();
$events = ITSEC_Core::get_scheduler()->get_single_events();
foreach ( $events as $event ) {
// If we are less than an hour late for processing the refresh, return the stale data.
if ( self::EVENT === $event['id'] ) {
if ( $event['fire_at'] + HOUR_IN_SECONDS > ITSEC_Core::get_current_time_gmt() ) {
return $data['response'];
}
// If its been more than a day, call the API right now.
if ( $event['fire_at'] + DAY_IN_SECONDS > ITSEC_Core::get_current_time_gmt() ) {
ITSEC_Core::get_scheduler()->run_single_event( self::EVENT );
$data = self::get_stored_response();
if ( $data['requested'] === ITSEC_Core::get_current_time_gmt() ) {
return $data['response'];
}
}
}
}
return array();
}
return $data['response'];
}
private static function get_stored_response() {
$data = get_site_option( self::OPTION, array() );
$data = wp_parse_args( $data, array(
'response' => array(),
'requested' => 0,
'ttl' => 0,
) );
return $data;
}
private static function schedule_check() {
$s = ITSEC_Core::get_scheduler();
if ( ! $s->is_single_scheduled( self::EVENT, null ) ) {
$s->schedule_once( ITSEC_Core::get_current_time_gmt() + 60, self::EVENT );
}
}
}