Files
2026-04-28 15:13:50 +02:00

264 lines
7.7 KiB
PHP

<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'WPChill_Notifications' ) ) {
//phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound
class WPChill_Notifications {
public static $instance;
public static $notification_prefix = 'wpchill_notification_';
public static $blocked_notifications = 'wpchill_blocked_notifications';
private $hook_name = 'wpchill_notifications_remote';
public function __construct() {
if ( ! wp_next_scheduled( $this->hook_name ) ) {
wp_schedule_event( time(), 'daily', $this->hook_name );
}
add_action( $this->hook_name, array( $this, 'get_remote_notices' ) );
if ( ! class_exists( 'WPChill_Rest_Api' ) ) {
require_once plugin_dir_path( __FILE__ ) . 'class-wpchill-rest-api.php';
}
add_action( 'admin_enqueue_scripts', array( $this, 'notification_system_scripts' ) );
new WPChill_Rest_Api();
}
public static function get_instance() {
if ( ! isset( self::$instance ) && ! ( self::$instance instanceof WPChill_Notifications ) ) {
self::$instance = new WPChill_Notifications();
}
return self::$instance;
}
public static function add_notification( $key, $notification ) {
$blocked = get_option( self::$blocked_notifications, array() );
if ( in_array( $key, $blocked, true ) ) {
return;
}
// Set the timestamp but only if not previously set.
if ( ! isset( $notification['timestamp'] ) ) {
$notification['timestamp'] = strtotime( current_time( 'mysql' ) );
}
update_option( self::$notification_prefix . $key, $notification );
}
public static function remove_notification( $key ) {
delete_option( self::$notification_prefix . $key );
}
public function get_notifications() {
$notifications = array(
'error' => array(),
'warning' => array(),
'success' => array(),
'info' => array(),
);
$options = $this->_get_options_wildcard( self::$notification_prefix . '%' );
if ( ! function_exists( 'is_plugin_active' ) ) {
include_once ABSPATH . 'wp-admin/includes/plugin.php';
}
$plugin_map = array(
'modula' => 'modula-best-grid-gallery/Modula.php',
'download-monitor' => 'download-monitor/download-monitor.php',
'strong-testimonials' => 'strong-testimonials/strong-testimonials.php',
);
foreach ( $options as $option ) {
$id = explode( '_', $option['option_name'] );
$id = end( $id );
if ( ! isset( $option['option_value'] ) ) {
continue;
}
$current_notifications = maybe_unserialize( $option['option_value'] );
if ( empty( $current_notifications ) || empty( $current_notifications['message'] ) ) {
continue;
}
$status = isset( $current_notifications['status'] ) ? $current_notifications['status'] : 'info';
if ( isset( $current_notifications['source']['slug'] ) ) {
$slug = sanitize_text_field( $current_notifications['source']['slug'] );
if ( isset( $plugin_map[ $slug ] ) ) {
$plugin_file = $plugin_map[ $slug ];
} else {
$plugin_file = $slug . '/' . $slug . '.php';
}
if ( ! is_plugin_active( $plugin_file ) ) {
continue;
}
$current_notifications['source']['icon'] = apply_filters(
'wpchill_notification_icon',
plugin_dir_url( __FILE__ ) . 'icons/' . $slug . '.svg',
$current_notifications
);
}
$time_ago = $current_notifications['timestamp']
? human_time_diff( $current_notifications['timestamp'], strtotime( current_time( 'mysql' ) ) )
: false;
$notifications[ $status ][] = array(
'id' => $id,
'title' => isset( $current_notifications['title'] ) ? $current_notifications['title'] : 'Notification',
'message' => $current_notifications['message'],
'dismissible' => isset( $current_notifications['dismissible'] ) ? $current_notifications['dismissible'] : true,
'actions' => isset( $current_notifications['actions'] ) ? $current_notifications['actions'] : array(),
'timed' => isset( $current_notifications['timed'] ) ? $current_notifications['timed'] : false,
'source' => isset( $current_notifications['source'] ) ? $current_notifications['source'] : array(),
// Translators: %s represents the time elapsed (e.g., "5 minutes", "2 hours", "1 day").
'time_ago' => $time_ago ? sprintf( esc_html__( '%s ago', 'download-monitor' ), $time_ago ) : false,
);
}
//phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
$notifications = apply_filters( 'wpchill_notifications', $notifications );
return $notifications;
}
private function _get_options_wildcard( $option_pattern ) {
global $wpdb;
$options = $wpdb->get_results(
$wpdb->prepare(
"SELECT option_name, option_value FROM $wpdb->options WHERE option_name LIKE %s",
$option_pattern
),
ARRAY_A
);
return $options;
}
public function clear_notification( $key, $permanent = false ) {
if ( $permanent ) {
$blocked = get_option( self::$blocked_notifications, array() );
$blocked[] = $key;
update_option( self::$blocked_notifications, $blocked );
}
delete_option( self::$notification_prefix . $key );
}
public function clear_notifications( $prefix = false ) {
$slug = $prefix ? $prefix : self::$notification_prefix;
$options = $this->_get_options_wildcard( $slug . '%' );
foreach ( $options as $option ) {
if ( isset( $option['option_name'] ) ) {
delete_option( $option['option_name'] );
}
}
}
public function get_remote_notices() {
$response = wp_remote_get(
'https://wp-modula.com/wp-json/notification/v1/get',
array(
'sslverify' => false,
'timeout' => 15,
)
);
if ( is_wp_error( $response ) ) {
return;
}
$status_code = wp_remote_retrieve_response_code( $response );
if ( 200 !== $status_code ) {
return;
}
$body = wp_remote_retrieve_body( $response );
$notifications = json_decode( $body, true );
if ( json_last_error() !== JSON_ERROR_NONE ) {
return;
}
foreach ( $notifications as $key => $notification ) {
$this->add_notification( $key, $notification );
}
}
public function notification_system_scripts() {
if ( ! $this->is_wpchill_admin_page() || ! current_user_can( 'manage_options' ) ) {
return;
}
$wpchill_path = plugin_dir_path( __FILE__ );
$wpchill_url = plugin_dir_url( __FILE__ );
$asset_file = require $wpchill_path . 'scripts/notification-system/notification-system.asset.php';
$enqueue = array(
'handle' => 'wpchill-notification-system',
'dependencies' => $asset_file['dependencies'],
'version' => $asset_file['version'],
'script' => $wpchill_url . 'scripts/notification-system/notification-system.js',
'style' => $wpchill_url . 'scripts/notification-system/notification-system.css',
);
wp_enqueue_script(
$enqueue['handle'],
$enqueue['script'],
$enqueue['dependencies'],
$enqueue['version'],
true
);
wp_enqueue_style(
$enqueue['handle'],
$enqueue['style'],
array( 'wp-components' ),
$enqueue['version']
);
}
/**
* Check if we are on a wpchill plugin admin page
*
* @return bool
*
*/
private function is_wpchill_admin_page() {
$screen = get_current_screen();
//phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
$allowed_screens = apply_filters( 'wpchill_notifications_allowed_screens', array( 'modula-gallery', 'modula-albums', 'dlm_download', 'wpm-testimonial' ) );
foreach ( $allowed_screens as $allowed_screen ) {
if ( false !== strpos( $screen->id, $allowed_screen ) ) {
return true;
}
}
return false;
}
}
WPChill_Notifications::get_instance();
}