%PDF- %PDF-
Direktori : /home/opti/public_html/stlc/wp-content/plugins/duplicator/src/Core/Notifications/ |
Current File : /home/opti/public_html/stlc/wp-content/plugins/duplicator/src/Core/Notifications/Notifications.php |
<?php namespace Duplicator\Core\Notifications; use DUP_LITE_Plugin_Upgrade; use DUP_Settings; use Duplicator\Ajax\ServicesNotifications; use Duplicator\Core\Views\TplMng; /** * Notifications. */ class Notifications { /** * Source of notifications content. * * @var string */ const SOURCE_URL = 'https://notifications.duplicator.com/dp-notifications.json'; /** * WordPress option key containing notification data * * @var string */ const DUPLICATOR_NOTIFICATIONS_OPT_KEY = 'duplicator_notifications'; /** * WordPress option key containing notification data * * @var string */ const DUPLICATOR_BEFORE_PACKAGES_HOOK = 'duplicator_before_packages_table_action'; /** * Duplicator notifications dismiss nonce key * * @var string */ const DUPLICATOR_NOTIFICATION_NONCE_KEY = 'duplicator-notification-dismiss'; /** * Option value. * * @var bool|array */ public static $option = false; /** * Initialize class. * * @return void */ public static function init() { // Delete data even if notifications are disabled. add_action('deactivate_plugin', array(__CLASS__, 'delete'), 10, 2); if (!DUP_Settings::Get('amNotices')) { return; } // Add notification count to menu label. add_filter('duplicator_menu_label_duplicator', function ($label) { if (self::getCount() === 0) { return $label; } return $label . '<span class="awaiting-mod">' . self::getCount() . '</span>'; }); self::update(); add_action(self::DUPLICATOR_BEFORE_PACKAGES_HOOK, array(__CLASS__, 'output')); $notificationsService = new ServicesNotifications(); $notificationsService->init(); } /** * Check if user has access and is enabled. * * @return bool */ public static function hasAccess() { return current_user_can('manage_options'); } /** * Get option value. * * @param bool $cache Reference property cache if available. * * @return array */ public static function getOption($cache = true) { if (self::$option && $cache) { return self::$option; } $option = get_option(self::DUPLICATOR_NOTIFICATIONS_OPT_KEY, array()); self::$option = array( 'update' => !empty($option['update']) ? (int)$option['update'] : 0, 'feed' => !empty($option['feed']) ? (array)$option['feed'] : array(), 'events' => !empty($option['events']) ? (array)$option['events'] : array(), 'dismissed' => !empty($option['dismissed']) ? (array)$option['dismissed'] : array() ); return self::$option; } /** * Fetch notifications from feed. * * @return array */ public static function fetchFeed() { $response = wp_remote_get( self::SOURCE_URL, array( 'timeout' => 10, 'user-agent' => self::getUserAgent(), ) ); if (is_wp_error($response)) { return array(); } $body = wp_remote_retrieve_body($response); if (empty($body)) { return array(); } return self::verify(json_decode($body, true)); } /** * Verify notification data before it is saved. * * @param array $notifications Array of notifications items to verify. * * @return array */ public static function verify($notifications) { $data = array(); if (!is_array($notifications) || empty($notifications)) { return $data; } foreach ($notifications as $notification) { // Ignore if one of the conditional checks is true: // // 1. notification message is empty. // 2. license type does not match. // 3. notification is expired. // 4. notification has already been dismissed. // 5. notification existed before installing Duplicator. // (Prevents bombarding the user with notifications after activation). if ( empty($notification['content']) || !self::isLicenseTypeMatch($notification) || self::isExpired($notification) || self::isDismissed($notification) || self::isExisted($notification) ) { continue; } $data[] = $notification; } return $data; } /** * Verify saved notification data for active notifications. * * @param array $notifications Array of notifications items to verify. * * @return array */ public static function verifyActive($notifications) { if (!is_array($notifications) || empty($notifications)) { return array(); } $current_timestamp = time(); // Remove notifications that are not active. foreach ($notifications as $key => $notification) { if ( (!empty($notification['start']) && $current_timestamp < strtotime($notification['start'])) || (!empty($notification['end']) && $current_timestamp > strtotime($notification['end'])) ) { unset($notifications[$key]); } } return $notifications; } /** * Get notification data. * * @return array */ public static function get() { if (!self::hasAccess()) { return array(); } $option = self::getOption(); $feed = !empty($option['feed']) ? self::verifyActive($option['feed']) : array(); $events = !empty($option['events']) ? self::verifyActive($option['events']) : array(); return array_merge($feed, $events); } /** * Get notification count. * * @return int */ public static function getCount() { return count(self::get()); } /** * Add a new Event Driven notification. * * @param array $notification Notification data. * * @return void */ public static function add($notification) { if (!self::isValid($notification)) { return; } $option = self::getOption(); // Notification ID already exists. if (!empty($option['events'][$notification['id']])) { return; } $notification = self::verify(array($notification)); update_option( self::DUPLICATOR_NOTIFICATIONS_OPT_KEY, array( 'update' => $option['update'], 'feed' => $option['feed'], 'events' => array_merge($notification, $option['events']), 'dismissed' => $option['dismissed'], ) ); } /** * Determine if notification data is valid. * * @param array $notification Notification data. * * @return bool */ public static function isValid($notification) { if (empty($notification['id'])) { return false; } return count(self::verify(array($notification))) > 0; } /** * Determine if notification has already been dismissed. * * @param array $notification Notification data. * * @return bool */ private static function isDismissed($notification) { $option = self::getOption(); return !empty($option['dismissed']) && in_array($notification['id'], $option['dismissed']); } /** * Determine if license type is match. * * @param array $notification Notification data. * * @return bool */ private static function isLicenseTypeMatch($notification) { // A specific license type is not required. $notification['type'] = (array)$notification['type']; if (empty($notification['type'])) { return false; } if (in_array('any', $notification['type'])) { return true; } return in_array(self::getLicenseType(), (array)$notification['type'], true); } /** * Determine if notification is expired. * * @param array $notification Notification data. * * @return bool */ private static function isExpired($notification) { return !empty($notification['end']) && time() > strtotime($notification['end']); } /** * Determine if notification existed before installing Duplicator. * * @param array $notification Notification data. * * @return bool */ private static function isExisted($notification) { $installInfo = DUP_LITE_Plugin_Upgrade::getInstallInfo(); return (!empty($notification['start']) && $installInfo['time'] > strtotime($notification['start'])); } /** * Update notification data from feed. * * @return void */ public static function update() { $option = self::getOption(); //Only update twice daily if ($option['update'] !== 0 && time() < $option['update'] + DAY_IN_SECONDS / 2) { return; } $data = array( 'update' => time(), 'feed' => self::fetchFeed(), 'events' => $option['events'], 'dismissed' => $option['dismissed'], ); /** * Allow changing notification data before it will be updated in database. * * @param array $data New notification data. */ $data = (array)apply_filters('duplicator_admin_notifications_update_data', $data); update_option(self::DUPLICATOR_NOTIFICATIONS_OPT_KEY, $data); } /** * Remove notification data from database before a plugin is deactivated. * * @param string $plugin Path to the plugin file relative to the plugins directory. * * @return void */ public static function delete($plugin) { $duplicator_plugins = array( 'duplicator-lite/duplicator.php', 'duplicator/duplicator.php', ); if (!in_array($plugin, $duplicator_plugins, true)) { return; } delete_option(self::DUPLICATOR_NOTIFICATIONS_OPT_KEY); } /** * Enqueue assets on Form Overview admin page. * * @return void */ public static function enqueues() { if (!self::getCount()) { return; } wp_enqueue_style( 'dup-admin-notifications', DUPLICATOR_PLUGIN_URL . "assets/css/admin-notifications.css", array('dup-lity'), DUPLICATOR_VERSION ); wp_enqueue_script( 'dup-admin-notifications', DUPLICATOR_PLUGIN_URL . "assets/js/notifications/admin-notifications.js", array('jquery', 'dup-lity'), DUPLICATOR_VERSION, true ); wp_localize_script( 'dup-admin-notifications', 'dup_admin_notifications', array( 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce(self::DUPLICATOR_NOTIFICATION_NONCE_KEY), ) ); // Lity. wp_enqueue_style( 'dup-lity', DUPLICATOR_PLUGIN_URL . 'assets/lib/lity/lity.min.css', array(), DUPLICATOR_VERSION ); wp_enqueue_script( 'dup-lity', DUPLICATOR_PLUGIN_URL . 'assets/lib/lity/lity.min.js', array('jquery'), DUPLICATOR_VERSION, true ); } /** * Output notifications on Form Overview admin area. * * @return void */ public static function output() { $notificationsData = self::get(); if (empty($notificationsData)) { return; } $content_allowed_tags = array( 'br' => array(), 'em' => array(), 'strong' => array(), 'span' => array( 'style' => array() ), 'p' => array( 'id' => array(), 'class' => array() ), 'a' => array( 'href' => array(), 'target' => array(), 'rel' => array() ) ); $notifications = array(); foreach ($notificationsData as $notificationData) { // Prepare required arguments. $notificationData = wp_parse_args( $notificationData, array( 'id' => 0, 'title' => '', 'content' => '', 'video' => '' ) ); $title = self::getComponentData($notificationData['title']); $content = self::getComponentData($notificationData['content']); if (!$title && !$content) { continue; } $notifications[] = array( 'id' => $notificationData['id'], 'title' => $title, 'btns' => self::getButtonsData($notificationData), 'content' => wp_kses(wpautop($content), $content_allowed_tags), 'video_url' => wp_http_validate_url(self::getComponentData($notificationData['video'])), ); } self::enqueues(); TplMng::getInstance()->render( 'parts/Notifications/main', array( 'notifications' => $notifications ) ); } /** * Retrieve notification's buttons. * * @param array $notification Notification data. * * @return array */ private static function getButtonsData($notification) { if (empty($notification['btn']) || !is_array($notification['btn'])) { return array(); } $buttons = array(); if (!empty($notification['btn']['main_text']) && !empty($notification['btn']['main_url'])) { $buttons[] = array( 'type' => 'primary', 'text' => $notification['btn']['main_text'], 'url' => self::prepareBtnUrl($notification['btn']['main_url']), 'target' => '_blank' ); } if (!empty($notification['btn']['alt_text']) && !empty($notification['btn']['alt_url'])) { $buttons[] = array( 'type' => 'secondary', 'text' => $notification['btn']['alt_text'], 'url' => self::prepareBtnUrl($notification['btn']['alt_url']), 'target' => '_blank' ); } return $buttons; } /** * Retrieve notification's component data by a license type. * * @param mixed $data Component data. * * @return false|mixed */ private static function getComponentData($data) { if (empty($data['license'])) { return $data; } $license_type = self::getLicenseType(); return !empty($data['license'][$license_type]) ? $data['license'][$license_type] : false; } /** * Retrieve the current installation license type (always lowercase). * * @return string */ private static function getLicenseType() { return 'lite'; } /** * Prepare button URL. * * @param string $btnUrl Button url. * * @return string */ private static function prepareBtnUrl($btnUrl) { if (empty($btnUrl)) { return ''; } $replace_tags = array( '{admin_url}' => admin_url() ); return wp_http_validate_url(str_replace(array_keys($replace_tags), array_values($replace_tags), $btnUrl)); } /** * User agent that will be used for the request * * @return string */ private static function getUserAgent() { return 'WordPress/' . get_bloginfo('version') . '; ' . get_bloginfo('url') . '; Duplicator/Lite-' . DUPLICATOR_VERSION; } }