first
This commit is contained in:
@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "shortpixel/notices",
|
||||
"description": "ShortPixel WordPress Notice System",
|
||||
"version": "1.5",
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Bas",
|
||||
"email": "bas@weblogmechanic.com"
|
||||
}
|
||||
],
|
||||
"minimum-stability": "dev",
|
||||
"require": {
|
||||
"shortpixel/log" : "1.1.*"
|
||||
},
|
||||
"repositories": [
|
||||
{
|
||||
"packagist.org": false,
|
||||
"type": "path",
|
||||
"url": "../modules/",
|
||||
"options": {
|
||||
"symlink": true
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"autoload": {
|
||||
"psr-4": { "ShortPixel\\Notices\\" : "src" }
|
||||
}
|
||||
}
|
@ -0,0 +1,372 @@
|
||||
<?php
|
||||
namespace ShortPixel\Notices;
|
||||
use ShortPixel\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');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,366 @@
|
||||
<?php
|
||||
namespace ShortPixel\Notices;
|
||||
|
||||
class NoticeModel //extends ShortPixelModel
|
||||
{
|
||||
public $message; // The message we want to convey.
|
||||
public $details = array(); // extra details, like the files involved. Something could be hideable in the future.
|
||||
public $code;
|
||||
|
||||
private $id = null; // used for persistent messages.
|
||||
protected $viewed = false; // was this notice viewed?
|
||||
protected $is_persistent = false; // This is a fatal issue, display until something was fixed.
|
||||
protected $is_dismissed = false; // for persistent notices,
|
||||
protected $suppress_until = null;
|
||||
protected $suppress_period = -1;
|
||||
protected $include_screens = array();
|
||||
protected $exclude_screens = array();
|
||||
public $is_removable = true; // if removable, display a notice dialog with red X or so.
|
||||
public $messageType = self::NOTICE_NORMAL;
|
||||
|
||||
public $notice_action; // empty unless for display. Ajax action to talk back to controller.
|
||||
protected $callback; // empty unless callback is needed
|
||||
|
||||
public static $icons = array();
|
||||
|
||||
private static $jsDismissLoaded;
|
||||
|
||||
const NOTICE_NORMAL = 1;
|
||||
const NOTICE_ERROR = 2;
|
||||
const NOTICE_SUCCESS = 3;
|
||||
const NOTICE_WARNING = 4;
|
||||
|
||||
/** Use this model in conjunction with NoticeController, do not call directly */
|
||||
public function __construct($message, $messageType = self::NOTICE_NORMAL)
|
||||
{
|
||||
$this->message = $message;
|
||||
$this->messageType = $messageType;
|
||||
}
|
||||
|
||||
public function isDone()
|
||||
{
|
||||
// check suppressed
|
||||
if ($this->is_dismissed && ! is_null($this->suppress_until))
|
||||
{
|
||||
if (time() >= $this->suppress_until)
|
||||
{
|
||||
$this->is_persistent = false; // unpersist, so it will be cleaned and dropped.
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->viewed && ! $this->is_persistent)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getID()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function isPersistent()
|
||||
{
|
||||
return $this->is_persistent;
|
||||
}
|
||||
|
||||
public function isDismissed()
|
||||
{
|
||||
return $this->is_dismissed;
|
||||
}
|
||||
|
||||
public function dismiss()
|
||||
{
|
||||
$this->is_dismissed = true;
|
||||
$this->suppress_until = time() + $this->suppress_period;
|
||||
}
|
||||
|
||||
public function unDismiss()
|
||||
{
|
||||
$this->is_dismissed = false;
|
||||
}
|
||||
|
||||
public function setDismissedUntil($timestamp)
|
||||
{
|
||||
$this->suppress_until = $timestamp;
|
||||
}
|
||||
|
||||
/** Support for extra information beyond the message.
|
||||
* Can help to not overwhelm users w/ the same message but different file /circumstances.
|
||||
*/
|
||||
public function addDetail($detail, $clean = false)
|
||||
{
|
||||
if ($clean)
|
||||
$this->details = array();
|
||||
|
||||
if (! in_array($detail, $this->details) )
|
||||
$this->details[] = $detail;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $method String Include or Exclude
|
||||
* @param $includes String|Array Screen Names to Include / Exclude either string, or array
|
||||
*/
|
||||
public function limitScreens($method, $screens)
|
||||
{
|
||||
if ($method == 'exclude')
|
||||
{
|
||||
$var = 'exclude_screens';
|
||||
}
|
||||
else {
|
||||
$var = 'include_screens';
|
||||
}
|
||||
|
||||
if (is_array($screens))
|
||||
{
|
||||
$this->$var = array_merge($this->$var, $screens);
|
||||
}
|
||||
else {
|
||||
$this->{$var}[] = $screens; // strange syntax is PHP 5.6 compat.
|
||||
}
|
||||
}
|
||||
|
||||
/* Checks if Notice is allowed on this screen
|
||||
* @param @screen_id String The screen Id to check ( most likely current one, via EnvironmentModel)
|
||||
*/
|
||||
public function checkScreen($screen_id)
|
||||
{
|
||||
if (in_array($screen_id, $this->exclude_screens))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (in_array($screen_id, $this->include_screens))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// if include is set, don't show if not screen included.
|
||||
if (count($this->include_screens) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Set a notice persistent. Meaning it shows every page load until dismissed.
|
||||
* @param $key Unique Key of this message. Required
|
||||
* @param $suppress When dismissed do not show this message again for X amount of time. When -1 it will just be dropped from the Notices and not suppressed
|
||||
*/
|
||||
public function setPersistent($key, $suppress = -1, $callback = null)
|
||||
{
|
||||
$this->id = $key;
|
||||
$this->is_persistent = true;
|
||||
$this->suppress_period = $suppress;
|
||||
if ( ! is_null($callback) && is_callable($callback))
|
||||
{
|
||||
$this->callback = $callback;
|
||||
}
|
||||
}
|
||||
|
||||
public static function setIcon($notice_type, $icon)
|
||||
{
|
||||
switch($notice_type)
|
||||
{
|
||||
case 'error':
|
||||
$type = self::NOTICE_ERROR;
|
||||
break;
|
||||
case 'success':
|
||||
$type = self::NOTICE_SUCCESS;
|
||||
break;
|
||||
case 'warning':
|
||||
$type = self::NOTICE_WARNING;
|
||||
break;
|
||||
case 'normal':
|
||||
default:
|
||||
$type = self::NOTICE_NORMAL;
|
||||
break;
|
||||
}
|
||||
self::$icons[$type] = $icon;
|
||||
}
|
||||
|
||||
public function _debug_getvar($var)
|
||||
{
|
||||
if (property_exists($this, $var))
|
||||
{
|
||||
return $this->$var;
|
||||
}
|
||||
}
|
||||
|
||||
private function checkIncomplete($var)
|
||||
{
|
||||
return ($var instanceof \__PHP_Incomplete_Class);
|
||||
}
|
||||
|
||||
public function getForDisplay()
|
||||
{
|
||||
$this->viewed = true;
|
||||
$class = 'shortpixel shortpixel-notice ';
|
||||
|
||||
$icon = '';
|
||||
|
||||
if ($this->callback)
|
||||
{
|
||||
if (is_array($this->callback))
|
||||
{
|
||||
foreach($this->callback as $part)
|
||||
{
|
||||
if ($this->checkIncomplete($part) === true)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} elseif (is_object($this->callback))
|
||||
{
|
||||
if ($this->checkIncomplete($part) === true)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! is_callable($this->callback))
|
||||
{
|
||||
return;
|
||||
}
|
||||
else {
|
||||
$return = call_user_func($this->callback, $this);
|
||||
if ($return === false) // don't display is callback returns false explicitly.
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
switch($this->messageType)
|
||||
{
|
||||
case self::NOTICE_ERROR:
|
||||
$class .= 'notice-error ';
|
||||
$icon = isset(self::$icons[self::NOTICE_ERROR]) ? self::$icons[self::NOTICE_ERROR] : '';
|
||||
//$icon = 'scared';
|
||||
break;
|
||||
case self::NOTICE_SUCCESS:
|
||||
$class .= 'notice-success ';
|
||||
$icon = isset(self::$icons[self::NOTICE_SUCCESS]) ? self::$icons[self::NOTICE_SUCCESS] : '';
|
||||
break;
|
||||
case self::NOTICE_WARNING:
|
||||
$class .= 'notice-warning ';
|
||||
$icon = isset(self::$icons[self::NOTICE_WARNING]) ? self::$icons[self::NOTICE_WARNING] : '';
|
||||
break;
|
||||
case self::NOTICE_NORMAL:
|
||||
$class .= 'notice-info ';
|
||||
$icon = isset(self::$icons[self::NOTICE_NORMAL]) ? self::$icons[self::NOTICE_NORMAL] : '';
|
||||
break;
|
||||
default:
|
||||
$class .= 'notice-info ';
|
||||
$icon = '';
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if ($this->is_removable)
|
||||
{
|
||||
$class .= 'is-dismissible ';
|
||||
}
|
||||
|
||||
if ($this->is_persistent)
|
||||
{
|
||||
$class .= 'is-persistent ';
|
||||
}
|
||||
|
||||
$id = ! is_null($this->id) ? $this->id : uniqid();
|
||||
//'id="' . $this->id . '"'
|
||||
$output = "<div id='$id' class='$class'><span class='icon'> " . $icon . "</span> <span class='content'>" . $this->message;
|
||||
if ($this->hasDetails())
|
||||
{
|
||||
$output .= '<div class="details-wrapper">
|
||||
<input type="checkbox" name="detailhider" id="check-' . $id .'">
|
||||
<label for="check-' . $id . '" class="show-details"><span>' . __('See Details', 'shortpixel-image-optimiser') . '</span>
|
||||
</label>';
|
||||
|
||||
$output .= "<div class='detail-content-wrapper'><p class='detail-content'>" . $this->parseDetails() . "</p></div>";
|
||||
$output .= '<label for="check-' . $id . '" class="hide-details"><span>' . __('Hide Details', 'shortpixel-image-optimiser') . '</span></label>';
|
||||
|
||||
$output .= '</div>'; // detail wrapper
|
||||
|
||||
}
|
||||
$output .= "</span>";
|
||||
|
||||
if ($this->is_removable)
|
||||
{
|
||||
$output .= '<button type="button" id="button-' . $id . '" class="notice-dismiss" data-dismiss="' . $this->suppress_period . '" ><span class="screen-reader-text">' . __('Dismiss this notice', 'shortpixel-image-optimiser') . '</span></button>';
|
||||
|
||||
if (! $this->is_persistent)
|
||||
{
|
||||
$output .= "<script type='text/javascript'>\n
|
||||
document.getElementById('button-$id').onclick = function()
|
||||
{
|
||||
var el = document.getElementById('$id');
|
||||
jQuery(el).fadeTo(100,0,function() {
|
||||
jQuery(el).slideUp(100, 0, function () {
|
||||
jQuery(el).remove();
|
||||
})
|
||||
});
|
||||
} </script>";
|
||||
}
|
||||
}
|
||||
|
||||
$output .= "</div>";
|
||||
|
||||
if ($this->is_persistent && $this->is_removable)
|
||||
{
|
||||
$output .= "<script type='text/javascript'>\n" . $this->getDismissJS() . "\n</script>";
|
||||
}
|
||||
return $output;
|
||||
|
||||
}
|
||||
|
||||
protected function hasDetails()
|
||||
{
|
||||
if (is_array($this->details) && count($this->details) > 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function parseDetails()
|
||||
{
|
||||
return implode('<BR>', $this->details);
|
||||
}
|
||||
|
||||
private function getDismissJS()
|
||||
{
|
||||
|
||||
$js = '';
|
||||
if (is_null(self::$jsDismissLoaded))
|
||||
{
|
||||
$nonce = wp_create_nonce('dismiss');
|
||||
$url = wp_json_encode(admin_url('admin-ajax.php'));
|
||||
$js = "function shortpixel_notice_dismiss(event) {
|
||||
event.preventDefault();
|
||||
var ev = event.detail;
|
||||
var target = event.target;
|
||||
var parent = target.parentElement;
|
||||
|
||||
var data = {
|
||||
'plugin_action': 'dismiss',
|
||||
'action' : '$this->notice_action',
|
||||
'nonce' : '$nonce',
|
||||
}
|
||||
data.time = target.getAttribute('data-dismiss');
|
||||
data.id = parent.getAttribute('id');
|
||||
jQuery.post($url,data);
|
||||
|
||||
jQuery(parent).fadeTo(100,0,function() {
|
||||
jQuery(parent).slideUp(100, 0, function () {
|
||||
jQuery(parent).remove();
|
||||
})
|
||||
});
|
||||
}";
|
||||
}
|
||||
|
||||
$js .= ' jQuery("#' . $this->id . '").find(".notice-dismiss").on("click", shortpixel_notice_dismiss); ';
|
||||
|
||||
return "\n jQuery(document).ready(function(){ \n" . $js . "\n});";
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
.shortpixel.shortpixel-notice {
|
||||
min-height: 75px;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: #fff;
|
||||
padding: 1px 12px;
|
||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
|
||||
border: 1px solid #c3c4c7;
|
||||
margin: 15px 0;
|
||||
border-left-width: 4px;
|
||||
border-left-color: #72aee6;
|
||||
position: relative;
|
||||
}
|
||||
.shortpixel.shortpixel-notice span {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.shortpixel.shortpixel-notice span.icon {
|
||||
margin: 0 25px 0 0;
|
||||
width: 80px;
|
||||
}
|
||||
.shortpixel.shortpixel-notice span.content {
|
||||
padding: 8px 0;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
}
|
||||
.shortpixel.shortpixel-notice img {
|
||||
display: inline-block;
|
||||
margin: 0 25px 0 0;
|
||||
max-height: 50px;
|
||||
}
|
||||
.shortpixel.shortpixel-notice .notice-dismiss {
|
||||
margin-top: 6px;
|
||||
}
|
||||
.shortpixel.shortpixel-notice.notice-success {
|
||||
border-left-color: #00a32a;
|
||||
}
|
||||
.shortpixel.shortpixel-notice.notice-warning {
|
||||
border-left-color: #dba617;
|
||||
}
|
||||
.shortpixel.shortpixel-notice.notice-error {
|
||||
border-left-color: #ff0000;
|
||||
}
|
||||
.shortpixel.shortpixel-notice.notice-info {
|
||||
border-left-color: #72aee6;
|
||||
}
|
||||
|
||||
/* In-view notice ( not on top, between the options ) - styled after WP notice */
|
||||
.view-notice {
|
||||
box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1);
|
||||
border: 4px solid #fff;
|
||||
padding: 1px 12px;
|
||||
}
|
||||
.view-notice p {
|
||||
margin: 1em 0 !important;
|
||||
}
|
||||
.view-notice.warning {
|
||||
border-left-color: #ffb900;
|
||||
}
|
||||
|
||||
.view-notice-row {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=notices.css.map */
|
@ -0,0 +1 @@
|
||||
{"version":3,"sourceRoot":"","sources":["notices.scss"],"names":[],"mappings":"AACA;EAGC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEC;;AACA;EACC;EACA;;AAED;EAEC;EACA;EACA;;AAKA;EAEE;EACA;EACA;;AAEF;EAEE;;AAGH;EAEC;;AAED;EAEC;;AAED;EAEC;;AAED;EAEE;;;AAIJ;AACA;EAGE;EACA;EAEA;;AACA;EACE;;AAEF;EAEE;;;AAIJ;EAEE","file":"notices.css"}
|
@ -0,0 +1,83 @@
|
||||
|
||||
.shortpixel.shortpixel-notice
|
||||
{
|
||||
|
||||
min-height: 75px;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: #fff;
|
||||
padding: 1px 12px;
|
||||
box-shadow: 0 1px 1px rgba(0,0,0,0.04);
|
||||
border: 1px solid #c3c4c7;
|
||||
margin: 15px 0;
|
||||
border-left-width: 4px;
|
||||
border-left-color: #72aee6;
|
||||
position: relative;
|
||||
|
||||
span
|
||||
{
|
||||
vertical-align: middle;
|
||||
&.icon {
|
||||
margin: 0 25px 0 0;
|
||||
width: 80px;
|
||||
}
|
||||
&.content
|
||||
{
|
||||
padding: 8px 0;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
//display: flex; // magically fixes verticality issues
|
||||
}
|
||||
}
|
||||
|
||||
img
|
||||
{
|
||||
display:inline-block;
|
||||
margin: 0 25px 0 0;
|
||||
max-height: 50px;
|
||||
}
|
||||
.notice-dismiss
|
||||
{
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
&.notice-success
|
||||
{
|
||||
border-left-color: #00a32a;
|
||||
}
|
||||
&.notice-warning
|
||||
{
|
||||
border-left-color: #dba617;
|
||||
}
|
||||
&.notice-error
|
||||
{
|
||||
border-left-color: #ff0000;
|
||||
}
|
||||
&.notice-info
|
||||
{
|
||||
border-left-color: #72aee6;
|
||||
}
|
||||
}
|
||||
|
||||
/* In-view notice ( not on top, between the options ) - styled after WP notice */
|
||||
.view-notice
|
||||
{
|
||||
|
||||
box-shadow: 0 1px 1px 0 rgba( 0, 0, 0, 0.1 );
|
||||
border: 4px solid #fff;
|
||||
|
||||
padding: 1px 12px;
|
||||
p {
|
||||
margin: 1em 0 !important;
|
||||
}
|
||||
&.warning
|
||||
{
|
||||
border-left-color: #ffb900;
|
||||
}
|
||||
}
|
||||
|
||||
.view-notice-row
|
||||
{
|
||||
display: none;
|
||||
}
|
Reference in New Issue
Block a user