File Manager

Current Directory: /home/astoriaah/www/plugins/system/shlib/shl_packages/db
Viewing File: /home/astoriaah/www/plugins/system/shlib/shl_packages/db/keystore.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; /** * Generic simple key/value storage * */ class ShlDb_Keystore { /** * Default db table name * * * CREATE TABLE `XXXXX_wblib_keystore` * ( * `id` INT PRIMARY KEY NOT NULL AUTO_INCREMENT, * `key` VARCHAR(333) NOT NULL, * `value` LONGTEXT NOT NULL, * `user_id` INT NOT NULL, * `modified_at` DATETIME DEFAULT '0000-00-00 00:00:00' NOT NULL, * `format` TINYINT DEFAULT 1 NOT NULL * ); * CREATE INDEX `element_key` ON `XXXXX_wblib_keystore` (`key`); * */ const TABLE_NAME = '#__wblib_keystore'; /** * Base format constant. Right now we de/serialize to and from php and json, and things are likely to stay like this */ const FORMAT_PHP = 0; const FORMAT_JSON = 1; /** * Do not encode */ const FORMAT_RAW = 128; /** * Not supported yet */ const FORMAT_YAML = 2; /** * default scope, when missing from requests */ const DEFAULT_SCOPE = 'default'; /** * Cache for current user id * * @var int|null */ protected $_userId = null; /** * @var string name of db table to hold keystore values */ protected $_tableName = ''; /** * Singleton * * @var \ShlDbKeystore */ private static $_instance = array(); /** * Public singleton * * @return \ShlDbKeystore */ public static function getInstance($tableName = self::TABLE_NAME) { if (empty(self::$_instance[$tableName])) { self::$_instance[$tableName] = new self($tableName); } return self::$_instance[$tableName]; } /** * Store commonly used upstream object * DB table to use for storage can be changed from the default wblib_keystore * * @param string $tableName */ private function __construct($tableName) { $this->_tableName = $tableName; $this->_userId = \JFactory::getUser()->id; } /** * Store data in keystore without any serialization * * @param string $key unique id for the data * @param mixed $value data to store * * @return $this * @throws \InvalidArgumentException */ public function putRaw($key, $value, $scope = self::DEFAULT_SCOPE) { if (!is_scalar($value) && !is_null($value)) { throw new \InvalidArgumentException('Raw value passed to keystore is invalid, not scalar'); } return $this->put($key, $value, $scope, self::FORMAT_RAW); } /** * Store a value into the keystore, identified by a key. Overwrite any pre-existing value with same key. * Value is serialized prior to being stored, using PHP serialization by default * Alternative is json * * @param string $key * @param mixed $value * @param int $format use of the class constants * * @return $this * @throws \InvalidArgumentException * @throws \Exception */ public function put($key, $value, $scope = self::DEFAULT_SCOPE, $format = self::FORMAT_PHP) { if (empty($key)) { throw new \InvalidArgumentException('Empty key while trying to put some data in key store'); } $data = array( 'scope' => $scope, 'key' => $key, 'value' => $this->_encode($value, $format), 'user_id' => $this->_userId, 'modified_at' => \ShlSystem_Date::getSiteNow(), 'format' => $format ); // insert or update the record in database \ShlDbHelper::insertUpdate($this->_tableName, $data, array('scope' => $scope, 'key' => $key)); return $this; } /** * Encode a value to one of the supported format, PHP serialization or json * * @param mixed $value * @param int $format see class constant * * @return string */ protected function _encode($value, $format) { switch ($format) { case self::FORMAT_PHP: $value = serialize($value); break; case self::FORMAT_JSON: $value = json_encode($value); break; default: break; } return $value; } /** * Retrieves a value from the keystore, identified by its key. * If not found, returns default value passed in. * * @param string $key * @param mixed $default * * @return mixed|null * @throws \InvalidArgumentException * @throws \Exception */ public function get($key, $default = null, $scope = self::DEFAULT_SCOPE) { if (empty($key)) { throw new \InvalidArgumentException('Empty key while trying to put some data in key store'); } $record = \ShlDbHelper::selectAssoc($this->_tableName, array('value', 'format'), array('scope' => $scope, 'key' => $key)); $value = empty($record) ? null : $this->_decode($record['value'], $record['format']); $value = is_null($value) ? $default : $value; return $value; } /** * Decode a raw value read from keystore, using the format also retrieved along the value. * See class constants for format code. * * @param string $value * @param int $format * * @return mixed */ protected function _decode($value, $format) { switch ($format) { case self::FORMAT_PHP: $value = unserialize($value); break; case self::FORMAT_JSON: $value = json_decode($value); break; default: break; } return $value; } /** * Delete a record in the keystore * * @param string $key * * @return $this * * @throws \InvalidArgumentException * @throws \Exception */ public function delete($key, $scope = self::DEFAULT_SCOPE) { if (empty($key)) { throw new \InvalidArgumentException('Empty key while trying to delete some data from key store'); } \ShlDbHelper::delete($this->_tableName, array('scope' => $scope, 'key' => $key)); return $this; } }