File Manager

Current Directory: /home/astoriaah/www/plugins/system/shlib/shl_packages/msg
Viewing File: /home/astoriaah/www/plugins/system/shlib/shl_packages/msg/manager.php
<?php /** * Shlib - programming library * * @author Yannick Gaultier * @copyright (c) Yannick Gaultier 2020 * @package shlib * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL * @version 0.4.0.716 * @date 2020-12-07 */ // Security check to ensure this file is being included by a parent file. defined('_JEXEC') or die; /** * Manages a message/notification center * * */ class ShlMsg_Manager { const DISPLAY_TYPE_INFO = 0; const DISPLAY_TYPE_NOTICE = 1; const DISPLAY_TYPE_WARNING = 2; const DISPLAY_TYPE_ERROR = 3; const DISPLAY_TYPE_IMPORTANT = 4; const ACTION_CAN_CLOSE = 0; const ACTION_CANNOT_CLOSE = 1; const ACTION_ON_CLOSE_DELAY_5MN = 2; const ACTION_ON_CLOSE_DELAY_10MN = 3; const ACTION_ON_CLOSE_DELAY_15MN = 4; const ACTION_ON_CLOSE_DELAY_30MN = 5; const ACTION_ON_CLOSE_DELAY_1H = 6; const ACTION_ON_CLOSE_DELAY_24H = 7; const ACTION_ON_CLOSE_DELAY_7D = 8; const ACTION_ON_CLOSE_DELAY_1M = 9; static $displayTypeClasses = array(); static $_manager = null; private $_tableName = '#__wblib_messages'; public static function getInstance() { if (is_null(self::$_manager)) { self::$displayTypeClasses = array( self::DISPLAY_TYPE_INFO => 'info', self::DISPLAY_TYPE_ERROR => 'error', self::DISPLAY_TYPE_WARNING => 'warning', self::DISPLAY_TYPE_NOTICE => 'notice', self::DISPLAY_TYPE_IMPORTANT => 'important' ); self::$_manager = new \ShlMsg_Manager; } return self::$_manager; } /** * Write a new message to the database * * @param array $msg Holds the message data */ public function add($msg) { // compute uid $msg['uid'] = sha1(serialize($msg) . mt_rand()); // update creation _date $msg['created_on'] = \ShlSystem_Date::getUTCNow(); // store to db \ShlDbHelper::insert($this->_tableName, $msg); } /** * Adds a message only once and only once * * @param $msg */ public function addOnce($msg) { if (!$this->validate($msg)) { return; }; $found = \ShlDbHelper::count($this->_tableName, 'id', array('scope' => $msg['scope'], 'type' => $msg['type'], 'sub_type' => $msg['sub_type'])); if (empty($found)) { $this->add($msg); } } /** * Add a msg, only if it doesn't exists * "Exists" is defined by an array of options * * @param array $msg * @param array $options */ public function addIfNotExists($msg, $options) { if (!$this->validate($msg)) { return; }; $found = \ShlDbHelper::count($this->_tableName, 'id', $options); if (empty($found)) { $this->add($msg); } } /** * Adds a message unless there's already one * of the same type, not yet acknowledge by user * * @param $msg */ public function addUnlessNotAcknowledged($msg) { if (!$this->validate($msg)) { return; }; $found = \ShlDbHelper::count($this->_tableName, 'id', array( 'scope' => $msg['scope'], 'type' => $msg['type'], 'sub_type' => $msg['sub_type'], 'acked_on' => '0000-00-00 00:00:00' ) ); if (empty($found)) { $this->add($msg); } } /** * Count how many messages would be displayed according to the * provided selection options * * @param array $options * @return mixed */ public function getCount($options = array()) { return $this->get($options, true); } /** * Gets messages from the db * * options: scope, type, display_type, uid, acknowledge * * @param array $options * @return mixed */ public function get($options = array(), $countOnly = false) { try { if (empty($options['scope'])) { throw new Exception('shLib: Empty scope trying to read messages'); } $where = array(); $db = \ShlDbHelper::getDb(); foreach ($options as $key => $value) { switch ($key) { case 'scope': case 'type': case 'sub_type': case 'display_type': case 'uid': if (!empty($options[$key])) { $where[] = $db->qn($key) . ' = ' . $db->q($value); } break; case 'acknowledged': if ($value) { $where[] = $db->qn('acked_on') . ' <> ' . $db->q('0000-00-00 00:00:00'); } else { $where[] = $db->qn('acked_on') . ' = ' . $db->q('0000-00-00 00:00:00'); } break; } } // hide or show after at give date $now = $db->q(\ShlSystem_Date::getUTCNow()); $where[] = '(' . $db->qn('hide_after') . ' = ' . $db->q('0000-00-00 00:00:00') . ' or ' . $db->qn('hide_after') . ' > ' . $now . ')'; $where[] = '(' . $db->qn('hide_until') . ' = ' . $db->q('0000-00-00 00:00:00') . ' or ' . $db->qn('hide_until') . ' < ' . $now . ')'; $whereClause = implode(' and ', $where); $orderBy = array('display_type' => 'DESC', 'created_on' => 'DESC'); $msgs = $countOnly ? \ShlDbHelper::count($this->_tableName, '*', $whereClause) : \ShlDbHelper::selectObjectList($this->_tableName, '*', $whereClause, array(), $orderBy); } catch (Exception $e) { \JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error'); $msgs = array(); } return $msgs; } public function delete($options = array()) { if (empty($options['scope']) || empty($options['type'])) { throw new RuntimeException('ShLib: trying to delete msg without scope or type.', 404); } \ShlDbHelper::delete($this->_tableName, $options); } public function acknowledgeById($uid) { if (empty($uid)) { throw new RuntimeException('ShLib: Empty message id while trying to acknowledge message.', 404); } $this->acknowledge(array('uid' => $uid)); } public function acknowledge($options, $force = false) { if (empty($options['acked_on'])) { $options['acked_on'] = '0000-00-00 00:00:00'; } // find record if ($force) { $action = self::ACTION_CAN_CLOSE; } else { $msg = \ShlDbHelper::selectAssoc($this->_tableName, '*', $options); if (empty($msg)) { throw new RuntimeException('ShLib: Cannot find db record trying to acknowledge a message.', 404); } $action = $msg['action']; } switch ($action) { case self::ACTION_CAN_CLOSE: \ShlDbHelper::update($this->_tableName, array('acked_on' => \ShlSystem_Date::getUTCNow()), $options); break; case self::ACTION_CANNOT_CLOSE: break; case self::ACTION_ON_CLOSE_DELAY_5MN: case self::ACTION_ON_CLOSE_DELAY_10MN: case self::ACTION_ON_CLOSE_DELAY_15MN: case self::ACTION_ON_CLOSE_DELAY_30MN: case self::ACTION_ON_CLOSE_DELAY_1H: case self::ACTION_ON_CLOSE_DELAY_24H: case self::ACTION_ON_CLOSE_DELAY_7D: case self::ACTION_ON_CLOSE_DELAY_1M: $hideUntil = new DateTime('now', new DateTimeZone('UTC')); $hideUntil->add(new DateInterval($this->getDelayFromActionCode($msg['action']))); \ShlDbHelper::update($this->_tableName, array('hide_until' => $hideUntil->format('Y-m-d H:i:s')), $options); break; default: throw new RuntimeException('ShLib:Invalid action code trying to acknowledge a message' . $msg['action'] . '.', 404); break; } } public function addAssets($document, $options = array()) { $htmlManager = \ShlHtml_Manager::getInstance(); $document->addStyleSheet($htmlManager->getMediaLink('msg', 'css', array('url_base' => JURI::root(true)))); $document->addScript($htmlManager->getMediaLink('msg', 'js', array('url_base' => JURI::root(true)))); } private function getDelayFromActionCode($actionCode) { switch ($actionCode) { case self::ACTION_ON_CLOSE_DELAY_5MN: $delay = 'PT5M'; break; case self::ACTION_ON_CLOSE_DELAY_10MN: $delay = 'PT10M'; break; case self::ACTION_ON_CLOSE_DELAY_15MN: $delay = 'PT15M'; break; case self::ACTION_ON_CLOSE_DELAY_30MN: $delay = 'PT20M'; break; case self::ACTION_ON_CLOSE_DELAY_1H: $delay = 'PT1H'; break; case self::ACTION_ON_CLOSE_DELAY_24H: $delay = 'P1D'; break; case self::ACTION_ON_CLOSE_DELAY_7D: $delay = 'P7D'; break; case self::ACTION_ON_CLOSE_DELAY_1M: $delay = 'P1M'; break; default: $delay = 0; break; } return $delay; } private function validate($msg) { if (empty($msg['scope']) || empty($msg['type']) || empty($msg['title'])) { \ShlSystem_Log::error('shlib', '%s::%d: %s', __METHOD__, __LINE__, 'Invalid message sent for storage ' . print_r($msg, true)); return false; } return true; } }