File: /var/www/html/wp-content/plugins/wp-stateless/lib/classes/class-errors.php
<?php
/**
* Admin Notices Handler
*
* @namespace wpCloud\StatelessMedia
*
* This file can be used to bootstrap any of the UD plugins, it essentially requires that you have
* a core file which will be called after 'plugins_loaded'. In addition, if the core class has
* 'activate' and 'deactivate' functions, then those will be called automatically by this class.
*/
namespace wpCloud\StatelessMedia {
if( !class_exists( 'wpCloud\StatelessMedia\Errors' ) ) {
/**
*
* @author: peshkov@UD
*/
class Errors extends \UsabilityDynamics\WP\Scaffold {
/**
* Errors
*
* @used admin_notices
* @public
* @property $errors
* @type array
*/
private $errors = array();
/**
* Messages
*
* @used admin_notices
* @public
* @property $messages
* @type array
*/
private $messages = array();
/**
* Warnings
*
* @used admin_notices
* @public
* @property $messages
* @type array
*/
private $warnings = array();
/**
* Notices
*
* @used admin_notices
* @public
* @property $messages
* @type array
*/
private $notices = array();
/**
* Action Links in Footer
*
* @used admin_notices
* @public
* @property $messages
* @type array
*/
private $action_links = array(
'errors' => null,
'notices' => null,
);
/**
* Dismiss action link is available or not.
*
* @var bool
*/
private $dismiss = true;
/**
*
*/
public function __construct( $args ) {
parent::__construct( $args );
add_action( 'admin_notices', array( $this, 'admin_notices' ) );
add_action( 'wp_ajax_stateless_notice_dismiss', array( $this, 'dismiss_notices' ) );
add_action( 'wp_ajax_stateless_enable_notice_button_action', array( $this, 'stateless_enable_notice_button_action' ) );
}
/**
* Prevents adding duplicating messages
* Some triggers may happen few times during site load (like 'switch_blog' hook)
* adding the same message several times is not necessary
*
* @param string $collection
* @param string $message
*/
private function add_message( &$collection, $message ) {
$exiting_keys = array_column($collection, 'key');
if ( in_array( $message['key'], $exiting_keys ) ) {
return;
}
$collection[] = $message;
}
/**
* Add new message for admin notices
*
* @param string $message
* @param string $type Values: 'error', 'message', 'warning'
* @param string $translate Values: true, false
* @author peshkov@UD
*/
public function add( $message, $type = 'error', $translate = true ) {
switch( $type ) {
case 'error':
$this->add_message($this->errors, $message);
break;
case 'message':
case 'warning':
case 'notice':
if(!is_array($message)){
$title = $translate
? sprintf( __( '%s has the following notice:', $this->domain ), esc_html($this->name) )
: sprintf( '%s has the following notice:', esc_html($this->name) );
$message = array(
'title' => $title,
'message' => $message,
'button' => null,
);
}
if(empty($message['key'])){
$message['key'] = md5( $message['title'] );
}
$this->add_message($this->notices, $message);
break;
}
}
/**
* Add footer link to specific ( errors|messages|wanrnings ) block
*
* @author peshkov@UD
*/
public function add_action_link( $link, $type = 'error' ) {
switch( $type ) {
case 'error':
$this->action_links[ 'errors' ][] = $link;
break;
case 'message':
case 'warning':
case 'notice':
$this->action_links[ 'notices' ][] = $link;
break;
}
}
/**
* Determine if errors exist
*
* @author peshkov@UD
*/
public function has_errors() {
return !empty( $this->errors ) ? true : false;
}
/**
* Renders admin notes in case there are errors or notices on bootstrap init
*
* @author peshkov@UD
*/
public function admin_notices() {
global $wp_version;
wp_enqueue_style("stateless-error-style", ud_get_stateless_media()->path('static/styles/error-notice.css'));
//enqueue dismiss js for ajax requests
$script_path = \UsabilityDynamics\WP\Utility::path( 'static/scripts/ud-dismiss.js', 'url' );
wp_enqueue_script( "sateless-error-notice-js", ud_get_stateless_media()->path( 'static/scripts/error-notice.js', 'url' ), array( 'jquery' ) );
wp_enqueue_script( "ud-dismiss", $script_path, array( 'jquery' ) );
wp_localize_script( "ud-dismiss", "_ud_vars", array(
"ajaxurl" => admin_url( 'admin-ajax.php' ),
));
wp_localize_script( "sateless-error-notice-js", "stateless_error_notice_vars", array(
"dismiss_nonce" => wp_create_nonce( 'stateless_notice_dismiss' ),
"enable_action_nonce" => wp_create_nonce( 'stateless_enable_notice_button_action' ),
));
//** Don't show the message if the user has no enough permissions. */
if ( ! function_exists( 'wp_get_current_user' ) ) {
require_once( ABSPATH . 'wp-includes/pluggable.php' );
}
$default_show = true;
if (
empty( $this->args['type'] ) ||
( $this->args['type'] == 'plugin' && !current_user_can( 'activate_plugins' ) ) ||
( $this->args['type'] == 'theme' && !current_user_can( 'switch_themes' ) )
) {
$default_show = false;
}
//** Don't show the message if on a multisite and the user isn't a super user. */
if ( is_multisite() && ! is_super_admin() ) {
$default_show = false;
}
$errors = apply_filters( 'ud:errors:admin_notices', $this->errors, $this->args );
$notices = apply_filters( 'stateless:notices:admin_notices', $this->notices, $this->args );
//** Errors Block */
if( $default_show && !empty( $errors ) && is_array( $errors ) ) {
$message = '<ul style="none;"><li>' . implode( '</li><li>', $errors ) . '</li></ul>';
$data = array(
'title' => sprintf( __( '%s is not active due to following errors:', $this->domain ), esc_html($this->name) ),
'class' => 'error',
'message' => $message,
'action_links' => !empty($this->action_links[ 'errors' ])?$this->action_links[ 'errors' ]:null,
);
include ud_get_stateless_media()->path( '/static/views/error-notice.php', 'dir' );
}
$has_notice = false;
//** Determine if warning has been dismissed */
if ( ! empty( $notices ) && is_array( $notices ) ) {
//** Warnings Block */
foreach ($notices as $notice ) {
if ( get_option( 'dismissed_notice_' . $notice['key'] )){
continue;
}
// Check additional capabilities
$capability = isset( $notice['capability'] ) && !empty( $notice['capability'] ) ? $notice['capability'] : null;
if ( ( !$default_show && empty($capability) ) || ( !empty($capability) && !current_user_can($capability) ) ) {
continue;
}
// Additional HTML classes
$classes = [];
if ( isset($notice['classes']) ) {
$classes = $notice['classes'];
if ( !is_array($classes) ) {
$classes = [$classes];
}
}
$classes[] = 'notice';
$data = wp_parse_args($notice, array(
'title' => '',
'class' => implode(' ', $classes),
'message' => '',
'button' => '',
'button_link' => '#',
'key' => '',
'action_links' => $this->action_links[ 'notices' ],
'dismiss' => true,
));
$button_capability = isset( $notice['button_capability'] ) && !empty( $notice['button_capability'] ) ? $notice['button_capability'] : null;
if ( !empty($button_capability) && !current_user_can($button_capability) ) {
$data['button'] = '';
}
include ud_get_stateless_media()->path( '/static/views/error-notice.php', 'dir' );
$has_notice = true;
}
}
}
/**
* dismiss the notice ajax callback
* @throws \Exception
*/
public function dismiss_notices() {
check_ajax_referer('stateless_notice_dismiss');
if ( !is_user_logged_in() ) {
wp_send_json_error( array( 'error' => __( 'You are not allowed to do this action.', $this->domain ) ) );
}
$response = array(
'success' => '0',
'error' => __( 'There was an error in request.', $this->domain ),
);
$error = false;
$option_key = isset($_POST['key']) ? sanitize_key($_POST['key']) : '';
if ( strpos($option_key, 'dismissed_') !== 0 ) {
$response['error'] = __( 'Invalid key', $this->domain );
$error = true;
}
if ( !$error && update_option( $option_key, time() ) ) {
do_action('wp_stateless_notice_dismissed', $option_key);
$response['success'] = '1';
$response['error'] = null;
}
wp_send_json( $response );
}
/**
* Action for the stateless_enable_notice_button_action ajax callback
* @throws \Exception
*/
public function stateless_enable_notice_button_action(){
check_ajax_referer('stateless_enable_notice_button_action');
if ( !is_user_logged_in() ) {
wp_send_json_error( array( 'error' => __( 'You are not allowed to do this action.', $this->domain ) ) );
}
$response = array(
'success' => '1',
);
$error = false;
if( empty($_POST['key']) ) {
$response['success'] = '0';
$response['error'] = __( 'Invalid key', $this->domain );
}
else{
$option_key = sanitize_key($_POST['key']);
$compatibility = Module::get_module($option_key);
if(!empty($compatibility['self']) && is_callable(array($compatibility['self'], 'enable_compatibility'))){
$response['success'] = $compatibility['self']->enable_compatibility();
}
}
wp_send_json( $response );
}
/**
* Check dismiss notice timestamp if greater than 24 hrs
*
* @param string $time
*
* @return bool
*/
public function check_dismiss_time( $time = '' ) {
if( empty( $time ) ) {
return true;
}
$current_time = time();
$diff = $current_time - 86400;
if ( $diff > (int)$time ) {
return true;
}
return false;
}
}
}
}