<?php namespace Resmush\Notices; use Resmush\ShortPixelLogger\ShortPixelLogger as Log; class NoticeController //extends ShortPixelController { protected static $notices = array(); protected static $instance = null; protected static $cssHookLoaded = false; // prevent css output more than once. protected $notice_displayed = array(); public $notice_count = 0; protected $has_stored = false; protected $notice_option = ''; // The wp_options name for notices here. /** For backward compat. Never call constructor directly. */ public function __construct() { $ns = __NAMESPACE__; $ns = substr($ns, 0, strpos($ns, '\\')); // try to get first part of namespace $this->notice_option = $ns . '-notices'; add_action('wp_ajax_' . $this->notice_option, array($this, 'ajax_action')); $this->loadNotices(); //$this->loadConfig(); } public static function getInstance() { if ( self::$instance === null) { self::$instance = new NoticeController(); } return self::$instance; } /** Reset all notices, before loading them, to ensure on updates / activations one starts fresh */ public static function resetNotices() { $ns = __NAMESPACE__; $ns = substr($ns, 0, strpos($ns, '\\')); // try to get first part of namespace $result = delete_option($ns . '-notices'); } /** Load Notices Config File, if any * * [ Future Use ] */ public function loadConfig() { return; if (file_exists('../notice_config.json')) { $config = file_get_contents('../notice_config.json'); $json_config = json_decode($config); } } public function loadIcons($icons) { foreach($icons as $name => $icon) NoticeModel::setIcon($name, $icon); } protected function loadNotices() { $notices = get_option($this->notice_option, false); $cnotice = (is_array($notices)) ? count($notices) : 0; if ($notices !== false && is_array($notices)) { $checked = array(); foreach($notices as $noticeObj) { if (is_object($noticeObj) && $noticeObj instanceOf NoticeModel) { $checked[] = $noticeObj; } } self::$notices = $checked; $this->has_stored = true; } else { self::$notices = array(); $this->has_stored = false; } $this->countNotices(); } protected function addNotice($message, $code, $unique) { $notice = new NoticeModel($message, $code); if ($unique) { foreach(self::$notices as $nitem) { if ($nitem->message == $notice->message && $nitem->code == $notice->code) // same message. return $nitem; // return the notice with the same message. } } self::$notices[] = $notice; $this->countNotices(); $this->update(); return $notice; } /** Update the notices to store, check what to remove, returns count. */ public function update() { if (! is_array(self::$notices) || count(self::$notices) == 0) { if ($this->has_stored) delete_option($this->notice_option); return 0; } $new_notices = array(); foreach(self::$notices as $item) { if (! $item->isDone() ) { $new_notices[] = $item; } } update_option($this->notice_option, $new_notices); self::$notices = $new_notices; return $this->countNotices(); } public function countNotices() { $this->notice_count = count(self::$notices); return $this->notice_count; } public function getNotices() { return self::$notices; } public function getNoticesForDisplay() { $newNotices = array(); foreach(self::$notices as $notice) { if ($notice->isDismissed()) // dismissed never displays. continue; if ($notice->isPersistent()) { $id = $notice->getID(); if (! is_null($id) && ! in_array($id, $this->notice_displayed)) { $notice->notice_action = $this->notice_option; $newNotices[] = $notice; $this->notice_displayed[] = $id; } } else $newNotices[] = $notice; } return $newNotices; } public function getNoticeByID($id) { foreach(self::$notices as $notice) { if ($notice->getID() == $id) return $notice; } return false; } public static function removeNoticeByID($id) { $noticeController = self::getInstance(); for($i = 0; $i < count(self::$notices); $i++) { $item = self::$notices[$i]; if (is_object($item) && $item->getID() == $id) { Log::addDebug('Removing notice with ID ' . $id); unset(self::$notices[$i]); } //if ($notice_item ) } $noticeController->update(); } public function ajax_action() { $response = array('result' => false, 'reason' => ''); if (isset($_POST['nonce']) && wp_verify_nonce( sanitize_key($_POST['nonce']), 'dismiss') ) { if (isset($_POST['plugin_action']) && 'dismiss' == $_POST['plugin_action'] ) { $id = (isset($_POST['id'])) ? sanitize_text_field( wp_unslash($_POST['id'])) : null; if (! is_null($id)) { $notice = $this->getNoticeByID($id); } else { $notice = false; } if(false !== $notice) { $notice->dismiss(); $this->update(); $response['result'] = true; } else { Log::addError('Notice not found when dismissing -> ' . $id, self::$notices); $response['result'] = false; $response['reason'] = ' Notice ' . $id . ' not found. '; } } } else { Log::addError('Wrong Nonce when dismissed notice. '); $response['reason'] = 'wrong nonce'; } wp_send_json($response); } /** Adds a notice, quick and fast method * @param String $message The Message you want to notify * @param Boolean $unique If unique, check to not repeat notice exact same text in notices. Discard if so * @param int $code A value of messageType as defined in model * @returm Object Instance of noticeModel */ public static function addNormal($message, $unique = false) { $noticeController = self::getInstance(); $notice = $noticeController->addNotice($message, NoticeModel::NOTICE_NORMAL, $unique); return $notice; } public static function addError($message, $unique = false) { $noticeController = self::getInstance(); $notice = $noticeController->addNotice($message, NoticeModel::NOTICE_ERROR, $unique); return $notice; } public static function addWarning($message, $unique = false) { $noticeController = self::getInstance(); $notice = $noticeController->addNotice($message, NoticeModel::NOTICE_WARNING, $unique); return $notice; } public static function addSuccess($message, $unique = false) { $noticeController = self::getInstance(); $notice = $noticeController->addNotice($message, NoticeModel::NOTICE_SUCCESS, $unique); return $notice; } public static function addDetail($notice, $detail) { $noticeController = self::getInstance(); $notice->addDetail($detail); // $notice_id = spl_object_id($notice); $noticeController->update(); } /** Make a regular notice persistent across multiple page loads * @param $notice NoticeModel The Notice to make Persistent * @param $key String Identifier of the persistent notice. * @param $suppress Int When dismissed, time to stay dismissed * @param $callback Function Callable function */ public static function makePersistent($notice, $key, $suppress = -1, $callback = null) { $noticeController = self::getInstance(); $existing = $noticeController->getNoticeByID($key); // if this key already exists, don't allow the new notice to be entered into the array. Remove it since it's already created. if ($existing) { for($i = 0; $i < count(self::$notices); $i++) { $item = self::$notices[$i]; if ($item->message == $notice->message && $item->getID() == null) { if ($item->message != $existing->message) // allow the persistent message to be updated, if something else is served on this ID { $existing->message = $item->message; } unset(self::$notices[$i]); } //if ($notice_item ) } } else { $notice->setPersistent($key, $suppress, $callback); // set this notice persistent. } $noticeController->update(); } public function admin_notices() { if ($this->countNotices() > 0) { if (! self::$cssHookLoaded) { add_action('admin_print_footer_scripts', array($this, 'printNoticeStyle')); self::$cssHookLoaded = true; } foreach($this->getNoticesForDisplay() as $notice) { echo $notice->getForDisplay(); } } $this->update(); // puts views, and updates } public function printNoticeStyle() { if (file_exists(__DIR__ . '/css/notices.css')) { echo '<style>' . esc_html(file_get_contents(__DIR__ . '/css/notices.css')) . '</style>'; } else { Log::addDebug('Notices : css/notices.css could not be loaded'); } } }