Commit realizado el 12:13:52 08-04-2024

This commit is contained in:
Pagina Web Monito
2024-04-08 12:13:55 -04:00
commit 0c33094de9
7815 changed files with 1365694 additions and 0 deletions

View File

@@ -0,0 +1,357 @@
<?php
/**
* The Notification center handles notifications storage and display.
*
* @since 1.0.0
* @package RankMath
* @subpackage RankMath
* @author RankMath <support@rankmath.com>
*/
namespace RankMath\Admin\Notifications;
/**
* Notification_Center class.
*/
class Notification_Center {
/**
* Option name to store notifications in.
*
* @var string
*/
private $storage_key = '';
/**
* Notifications.
*
* @var array
*/
private $notifications = [];
/**
* Stores whether we need to clear storage or not.
*
* @var array
*/
private $should_clear_storage = true;
/**
* Stores already displayed notice texts to avoid duplication.
*
* @var array
*/
private $displayed_notifications = [];
/**
* Internal flag for whether notifications have been retrieved from storage.
*
* @var bool
*/
private $retrieved = false;
/**
* Construct
*
* @param string $storage_key Option name to store notification in.
*/
public function __construct( $storage_key = 'mythemeshop_notifications' ) {
$this->storage_key = $storage_key;
add_action( 'plugins_loaded', [ $this, 'get_from_storage' ], 5 );
add_action( 'all_admin_notices', [ $this, 'display' ] );
add_action( 'shutdown', [ $this, 'update_storage' ] );
add_action( 'admin_footer', [ $this, 'print_javascript' ] );
add_action( 'wp_ajax_wp_helpers_notice_dismissible', [ $this, 'notice_dismissible' ] );
}
/**
* Retrieve the notifications from storage
*
* @codeCoverageIgnore
*
* @return array Notification[] Notifications
*/
public function get_from_storage() {
if ( $this->retrieved ) {
return;
}
$this->retrieved = true;
$notifications = get_option( $this->storage_key );
// Check if notifications are stored.
if ( empty( $notifications ) ) {
$this->should_clear_storage = false;
return;
}
if ( is_array( $notifications ) ) {
foreach ( $notifications as $notification ) {
$this->notifications[] = new Notification(
$notification['message'],
$notification['options']
);
}
}
}
/**
* Display the notifications.
*
* @codeCoverageIgnore
*/
public function display() {
// Never display notifications for network admin.
if ( $this->is_network_admin() ) {
return;
}
$notifications = $this->get_sorted_notifications();
if ( empty( $notifications ) ) {
return;
}
foreach ( $notifications as $notification ) {
if ( $notification->can_display() && ! in_array( (string) $notification, $this->displayed_notifications, true ) ) {
echo $notification;
$this->displayed_notifications[] = (string) $notification;
}
}
}
/**
* Print JS for dismissile.
*
* @codeCoverageIgnore
*/
public function print_javascript() {
?>
<script>
;(function($) {
$( '.wp-helpers-notice.is-dismissible' ).on( 'click', '.notice-dismiss', function() {
var notice = $( this ).parent()
$.ajax({
url: ajaxurl,
type: 'POST',
dataType: 'json',
data: {
action: 'wp_helpers_notice_dismissible',
security: notice.data( 'security' ),
notificationId: notice.attr( 'id' )
}
});
});
})(jQuery);
</script>
<?php
}
/**
* Save persistent or transactional notifications to storage.
*
* We need to be able to retrieve these so they can be dismissed at any time during the execution.
*
* @codeCoverageIgnore
*/
public function update_storage() {
$notifications = $this->get_notifications();
$notifications = array_filter( $notifications, [ $this, 'remove_notification' ] );
/**
* Filter: 'wp_helpers_notifications_before_storage' - Allows developer to filter notifications before saving them.
*
* @param Notification[] $notifications
*/
$notifications = apply_filters( 'wp_helpers_notifications_before_storage', $notifications );
// No notifications to store, clear storage.
if ( empty( $notifications ) && $this->should_clear_storage ) {
delete_option( $this->storage_key );
return;
}
$notifications = array_map( [ $this, 'notification_to_array' ], $notifications );
// Save the notifications to the storage.
update_option( $this->storage_key, $notifications );
}
/**
* Dismiss persistent notice.
*
* @codeCoverageIgnore
*/
public function notice_dismissible() {
$notification_id = filter_input( INPUT_POST, 'notificationId' );
check_ajax_referer( $notification_id, 'security' );
$notification = $this->remove_by_id( $notification_id );
/**
* Filter: 'wp_helpers_notification_dismissed' - Allows developer to perform action after dismissed.
*
* @param Notification[] $notifications
*/
do_action( 'wp_helpers_notification_dismissed', $notification_id, $notification );
}
/**
* Add notification
*
* @param string $message Message string.
* @param array $options Set of options.
*/
public function add( $message, $options = [] ) {
if ( isset( $options['id'] ) && ! is_null( $this->get_notification_by_id( $options['id'] ) ) ) {
return;
}
$this->notifications[] = new Notification(
$message,
$options
);
}
/**
* Provide a way to verify present notifications
*
* @return array|Notification[] Registered notifications.
*/
public function get_notifications() {
return $this->notifications;
}
/**
* Get the notification by ID
*
* @param string $notification_id The ID of the notification to search for.
* @return null|Notification
*/
public function get_notification_by_id( $notification_id ) {
foreach ( $this->notifications as $notification ) {
if ( $notification_id === $notification->args( 'id' ) ) {
return $notification;
}
}
return null;
}
/**
* Remove the notification by ID
*
* @codeCoverageIgnore
*
* @param string $notification_id The ID of the notification to search for.
* @return Notification Instance of delete notification.
*/
public function remove_by_id( $notification_id ) {
$notification = $this->get_notification_by_id( $notification_id );
if ( ! is_null( $notification ) ) {
$notification->dismiss();
}
return $notification;
}
/**
* Remove notification after it has been displayed.
*
* @codeCoverageIgnore
*
* @param Notification $notification Notification to remove.
*/
public function remove_notification( Notification $notification ) {
if ( ! $notification->is_displayed() ) {
return true;
}
if ( $notification->is_persistent() ) {
return true;
}
return false;
}
/**
* Return the notifications sorted on type and priority
*
* @codeCoverageIgnore
*
* @return array|Notification[] Sorted Notifications
*/
private function get_sorted_notifications() {
$notifications = $this->get_notifications();
if ( empty( $notifications ) ) {
return [];
}
// Sort by severity, error first.
usort( $notifications, [ $this, 'sort_notifications' ] );
return $notifications;
}
/**
* Sort on type then priority
*
* @codeCoverageIgnore
*
* @param Notification $first Compare with B.
* @param Notification $second Compare with A.
* @return int 1, 0 or -1 for sorting offset.
*/
private function sort_notifications( Notification $first, Notification $second ) {
if ( 'error' === $first->args( 'type' ) ) {
return -1;
}
if ( 'error' === $second->args( 'type' ) ) {
return 1;
}
return 0;
}
/**
* Convert Notification to array representation
*
* @codeCoverageIgnore
*
* @param Notification $notification Notification to convert.
* @return array
*/
private function notification_to_array( Notification $notification ) {
return $notification->to_array();
}
/**
* Check if is network admin.
*
* @codeCoverageIgnore
*
* @return bool
*/
private function is_network_admin() {
return function_exists( 'is_network_admin' ) && is_network_admin();
}
/**
* Check if a notification with the given ID exists.
*
* @param string $id Notification ID.
* @return boolean
*/
public function has_notification( $id ) {
$notifications = $this->get_notifications();
foreach ( $notifications as $notification ) {
if ( isset( $notification->options['id'] ) && $notification->options['id'] === $id ) {
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,244 @@
<?php
/**
* The Notification
*
* @since 1.0.0
* @package RankMath
* @subpackage RankMath
* @author RankMath <support@rankmath.com>
*/
namespace RankMath\Admin\Notifications;
use RankMath\Helpers\Str;
use RankMath\Helpers\HTML;
/**
* Notification class.
*/
class Notification {
/**
* Notification type.
*
* @var string
*/
const ERROR = 'error';
/**
* Notification type.
*
* @var string
*/
const SUCCESS = 'success';
/**
* Notification type.
*
* @var string
*/
const INFO = 'info';
/**
* Notification type.
*
* @var string
*/
const WARNING = 'warning';
/**
* Screen check.
*
* @var string
*/
const SCREEN_ANY = 'any';
/**
* User capability check.
*
* @var string
*/
const CAPABILITY_ANY = '';
/**
* The notification message.
*
* @var string
*/
public $message = '';
/**
* Contains optional arguments:
*
* - type: The notification type, i.e. 'updated' or 'error'
* - id: The ID of the notification
* - dismissal_key: Option name to save dismissal information in, ID will be used if not supplied.
* - screen: Only display on plugin page or on every page.
*
* @var array Options of this Notification.
*/
public $options = [];
/**
* Internal flag for whether notifications has been displayed.
*
* @var bool
*/
private $displayed = false;
/**
* Notification class constructor.
*
* @param string $message Message string.
* @param array $options Set of options.
*/
public function __construct( $message, $options = [] ) {
$this->message = $message;
$this->options = wp_parse_args(
$options,
[
'id' => '',
'classes' => '',
'type' => self::SUCCESS,
'screen' => self::SCREEN_ANY,
'capability' => self::CAPABILITY_ANY,
]
);
}
/**
* Adds string (view) behaviour to the Notification.
*
* @codeCoverageIgnore
*
* @return string
*/
public function __toString() {
return $this->render();
}
/**
* Return data from options.
*
* @param string $id Data to get.
* @return mixed
*/
public function args( $id ) {
return $this->options[ $id ];
}
/**
* Is this Notification persistent.
*
* @codeCoverageIgnore
*
* @return bool True if persistent, False if fire and forget.
*/
public function is_persistent() {
return ! empty( $this->args( 'id' ) );
}
/**
* Is this notification displayed.
*
* @codeCoverageIgnore
*
* @return bool
*/
public function is_displayed() {
return $this->displayed;
}
/**
* Can display on current screen.
*
* @codeCoverageIgnore
*
* @return bool
*/
public function can_display() {
// Removed.
if ( $this->displayed ) {
return false;
}
$screen = get_current_screen();
if ( self::SCREEN_ANY === $this->args( 'screen' ) || Str::contains( $this->args( 'screen' ), $screen->id ) ) {
$this->displayed = true;
}
if ( self::CAPABILITY_ANY !== $this->args( 'capability' ) && ! current_user_can( $this->args( 'capability' ) ) ) {
$this->displayed = false;
}
return $this->displayed;
}
/**
* Dismiss persisten notification.
*
* @codeCoverageIgnore
*/
public function dismiss() {
$this->displayed = true;
$this->options['id'] = '';
}
/**
* Return the object properties as an array.
*
* @codeCoverageIgnore
*
* @return array
*/
public function to_array() {
return [
'message' => $this->message,
'options' => $this->options,
];
}
/**
* Renders the notification as a string.
*
* @codeCoverageIgnore
*
* @return string The rendered notification.
*/
public function render() {
$attributes = [];
// Default notification classes.
$classes = [
'notice',
'notice-' . $this->args( 'type' ),
$this->args( 'classes' ),
];
// Maintain WordPress visualisation of alerts when they are not persistent.
if ( $this->is_persistent() ) {
$classes[] = 'is-dismissible';
$classes[] = 'wp-helpers-notice';
$attributes['id'] = $this->args( 'id' );
$attributes['data-security'] = wp_create_nonce( $this->args( 'id' ) );
}
if ( ! empty( $classes ) ) {
$attributes['class'] = implode( ' ', array_filter( $classes ) );
}
// Build the output DIV.
$output = '<div' . HTML::attributes_to_string( $attributes ) . '>' . wpautop( $this->message ) . '</div>' . PHP_EOL;
/**
* Filter: 'wp_helpers_notifications_render' - Allows developer to filter notifications before the output is finalized.
*
* @param string $output HTML output.
* @param array $message Notice message.
* @param array $options Notice args.
*/
$output = apply_filters( 'wp_helpers_notifications_render', $output, $this->message, $this->options );
return $output;
}
}