From 3ee305623f617c24cda97cc6df3df18c187d3624 Mon Sep 17 00:00:00 2001 From: Jakiboy Date: Sun, 21 Jul 2024 01:32:16 +0100 Subject: [PATCH] Update --- composer.json | 2 +- src/VanillePluginBase.php | 2 +- src/VanillePluginConfig.php | 478 +++++++++--------- src/VanillePluginOption.php | 97 ++-- src/VanillePluginValidator.php | 77 +-- src/bin/ajax.schema.json | 23 + src/bin/assets.schema.json | 82 +++ src/bin/config.schema.json | 306 ----------- src/bin/cron.schema.json | 57 +++ src/bin/global.schema.json | 132 +++++ src/bin/inputs.schema.json | 22 + src/bin/remote.schema.json | 33 ++ src/bin/requirements.schema.json | 238 +++++++++ src/bin/routes.schema.json | 28 + src/bin/settings.schema.json | 40 ++ src/bin/strings.schema.json | 17 + ...ationException.php => ConfigException.php} | 12 +- src/exc/ModelException.php | 2 +- src/exc/RequestException.php | 23 + src/inc/Archive.php | 6 +- src/inc/Arrayify.php | 17 +- src/inc/Attachment.php | 4 +- src/inc/Converter.php | 4 +- src/inc/Cookie.php | 2 +- src/inc/Crawler.php | 12 +- src/inc/Encryption.php | 31 +- src/inc/Exception.php | 33 +- src/inc/File.php | 64 ++- src/inc/Form.php | 5 +- src/inc/Format.php | 11 +- src/inc/Globals.php | 44 +- src/inc/Hook.php | 17 +- src/inc/Image.php | 19 +- src/inc/Restful.php | 12 + src/inc/Server.php | 24 +- src/inc/Session.php | 6 +- src/inc/Stringify.php | 19 +- src/inc/System.php | 10 +- src/inc/Table.php | 4 +- src/inc/Template.php | 4 +- src/inc/Tokenizer.php | 63 +-- src/inc/TypeCheck.php | 11 +- src/inc/Upload.php | 170 +++++-- src/inc/User.php | 17 +- src/inc/Validator.php | 36 +- src/int/AdminHelperInterface.php | 71 ++- src/int/AdminInterface.php | 16 +- src/int/AjaxCoreInterface.php | 42 -- src/int/AjaxInterface.php | 26 +- src/int/CallableInterface.php | 5 +- src/int/CronInterface.php | 85 +++- src/int/FrontHelperInterface.php | 38 +- src/int/FrontInterface.php | 28 +- src/int/GlobalHelperInterface.php | 47 ++ src/int/ModelInterface.php | 1 + src/int/NoticeInterface.php | 4 +- src/int/RequestInterface.php | 1 + src/int/RestfulInterface.php | 67 +-- src/int/SettingsInterface.php | 7 +- src/int/ShortcodeInterface.php | 2 +- src/int/UpgraderInterface.php | 32 ++ src/int/ViewInterface.php | 8 +- src/lib/API.php | 18 +- src/lib/Ajax.php | 131 +++-- src/lib/Asset.php | 115 +++-- src/lib/Backup.php | 8 - src/lib/Cache.php | 19 +- src/lib/Cron.php | 191 ++++--- src/lib/Hasher.php | 99 ++++ src/lib/Hook.php | 228 +++++++-- src/lib/Loader.php | 4 +- src/lib/Migrate.php | 9 +- src/lib/Model.php | 17 +- src/lib/Notice.php | 23 +- src/lib/Queue.php | 2 +- src/lib/Requirement.php | 429 ++++++++-------- src/lib/RestAPI.php | 184 +++---- src/lib/Rewrite.php | 4 +- src/lib/Shortcode.php | 457 ++++++++++++----- src/lib/Updater.php | 2 +- src/lib/View.php | 28 +- src/tr/TraitAuthenticatable.php | 148 ++++-- src/tr/TraitCacheable.php | 73 +-- src/tr/TraitConfigurable.php | 276 ++++++---- src/tr/TraitDatable.php | 53 +- src/tr/TraitDownloadable.php | 13 +- src/tr/TraitFormattable.php | 345 +++++++------ src/tr/TraitHookable.php | 79 ++- src/tr/TraitIO.php | 161 +++--- src/tr/TraitInjectable.php | 67 +++ src/tr/TraitLoggable.php | 3 + .../{TraitMapable.php => TraitMappable.php} | 34 +- src/tr/TraitMigratable.php | 27 +- src/tr/TraitPermissionable.php | 65 ++- src/tr/TraitRenderable.php | 91 ++-- src/tr/TraitRequestable.php | 204 +++++--- src/tr/TraitSecurable.php | 116 +++-- src/tr/TraitSerializable.php | 32 +- src/tr/TraitSessionable.php | 117 +++-- src/tr/TraitThrowable.php | 53 +- src/tr/TraitTranslatable.php | 7 +- src/tr/TraitUpdatable.php | 35 +- src/tr/TraitUploadable.php | 88 ++++ src/tr/TraitViewable.php | 5 +- 104 files changed, 4313 insertions(+), 2543 deletions(-) create mode 100644 src/bin/ajax.schema.json create mode 100644 src/bin/assets.schema.json delete mode 100644 src/bin/config.schema.json create mode 100644 src/bin/cron.schema.json create mode 100644 src/bin/global.schema.json create mode 100644 src/bin/inputs.schema.json create mode 100644 src/bin/remote.schema.json create mode 100644 src/bin/requirements.schema.json create mode 100644 src/bin/routes.schema.json create mode 100644 src/bin/settings.schema.json create mode 100644 src/bin/strings.schema.json rename src/exc/{ConfigurationException.php => ConfigException.php} (51%) create mode 100644 src/exc/RequestException.php delete mode 100644 src/int/AjaxCoreInterface.php create mode 100644 src/int/GlobalHelperInterface.php create mode 100644 src/int/UpgraderInterface.php create mode 100644 src/lib/Hasher.php create mode 100644 src/tr/TraitInjectable.php rename src/tr/{TraitMapable.php => TraitMappable.php} (51%) create mode 100644 src/tr/TraitUploadable.php diff --git a/composer.json b/composer.json index f71d8fb4..938de023 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name":"jakiboy/vanilleplugin", - "version":"1.0.8", + "version":"1.0.9", "type":"library", "description":"WordPress Plugin Framework", "keywords":[ diff --git a/src/VanillePluginBase.php b/src/VanillePluginBase.php index e44b014e..f3b7347e 100644 --- a/src/VanillePluginBase.php +++ b/src/VanillePluginBase.php @@ -15,7 +15,7 @@ namespace VanillePlugin; /** - * Define base functions used by plugin. + * Define base functions. * * - Hooking * - Rendering diff --git a/src/VanillePluginConfig.php b/src/VanillePluginConfig.php index 1ae09d96..0e9fa058 100644 --- a/src/VanillePluginConfig.php +++ b/src/VanillePluginConfig.php @@ -14,10 +14,10 @@ namespace VanillePlugin; -use VanillePlugin\exc\ConfigurationException; +use VanillePlugin\exc\ConfigException; /** - * Define base configuration used by plugin. + * Define plugin configuration. * * - Configuration * - Translation @@ -39,16 +39,16 @@ trait VanillePluginConfig * @access private * @var int $depth, Base path depth * @var bool $cacheable, Config cache - * @var string $config, Config path + * @var string $path, Config root path * @var object $global, Config global */ private $depth = 5; private $cacheable = true; - private $config = '/core/storage/config/global.json'; + private $root = '/core/storage/config'; private $global; /** - * Init configuration. + * Init config. */ public function __construct() { @@ -72,8 +72,7 @@ public function __wakeup() } /** - * Get static instance, - * Allows access to plugin config. + * Get static instance. * * @access protected * @return object @@ -84,7 +83,7 @@ protected static function getStatic() : object } /** - * Init plugin config. + * Init plugin global config. * * @access protected * @return void @@ -100,7 +99,7 @@ protected function initConfig() $this->depth = (int)constant('VanillePluginDepth'); } if ( defined('VanillePluginConfigPath') ) { - $this->config = (string)constant('VanillePluginConfigPath'); + $this->root = (string)constant('VanillePluginConfigPath'); } if ( defined('VanillePluginCache') ) { $this->cacheable = (bool)constant('VanillePluginCache'); @@ -110,36 +109,42 @@ protected function initConfig() $key = $this->applyPrefix('global'); if ( !($this->global = $this->getTransient($key)) ) { - $this->global = $this->parseConfig(); + $this->global = $this->parseConfig('global'); $this->setTransient($key, $this->global, 0); } } else { - $this->global = $this->parseConfig(); + $this->global = $this->parseConfig('global'); } } - + /** - * Parse plugin configuration file. + * Parse plugin config file. * * @access protected + * @param string $config + * @param bool $validate * @return mixed - * @throws ConfigurationException + * @throws ConfigException */ - protected function parseConfig() + protected function parseConfig(string $config, bool $validate = true) { - $json = $this->getRoot($this->config); - if ( $this->isFile($json) ) { - - $global = $this->parseJson($json); - VanillePluginValidator::checkConfig($global, $json); - return $global; + $file = $this->getRoot( + "{$this->root}/{$config}.json" + ); - } else { - throw new ConfigurationException( - ConfigurationException::invalidPluginConfigurationFile($json) + if ( !$this->isFile($file) ) { + throw new ConfigException( + ConfigException::invalidConfigFile($file) ); } + + $data = $this->parseJson($file); + if ( $validate ) { + VanillePluginValidator::validate($data, $config); + } + + return $data; } /** @@ -174,17 +179,27 @@ protected function getConfig(?string $key = null) } /** - * Update global custom options. + * Update global config options. * * @access protected * @param array $options * @param int $args * @return bool */ - protected function updateConfig(array $options = [], $args = 64|128|256) : bool + protected function updateConfig(array $options = [], int $args = 64|256) : bool { - $json = $this->getRoot($this->config); - $data = $this->parseJson($json, true); + if ( $this->getEnv() == 'dev' ) { + return false; + } + + if ( $this->hasDebug() ) { + $args = 64|128|256; + } + + $file = $this->getRoot( + "{$this->root}/global.json" + ); + $data = $this->parseJson($file); foreach ($options as $option => $value) { if ( isset($data['options'][$option]) ) { @@ -192,61 +207,41 @@ protected function updateConfig(array $options = [], $args = 64|128|256) : bool } } - $data['cron'] = (object)$data['cron']; - $data['hooks'] = (object)$data['hooks']; - $data['settings'] = (object)$data['settings']; - $data['inputs'] = (object)$data['inputs']; - $data['assets'] = (object)$data['assets']; + VanillePluginValidator::validate($data, 'global'); $data = $this->formatJson($data, $args); - return $this->writeFile($this->getRoot($this->config), $data); + return $this->writeFile($file, $data); } /** - * Load configuration file. + * Load partial config file. * * @access protected * @param string $config - * @param bool $isArray - * @return mixed + * @param bool $validate + * @return array */ - protected function loadConfig(string $config, bool $isArray = false) + protected function loadConfig(string $config, bool $validate = true) : array { - $value = false; - $dir = dirname($this->getRoot($this->config)); + $data = []; if ( $this->cacheable ) { + $key = $this->applyPrefix($config); - if ( !($value = $this->getTransient($key)) ) { - if ( $this->isFile( ($json = "{$dir}/{$config}.json") ) ) { - $value = $this->decodeJson($this->readfile($json), $isArray); - } - $this->setTransient($key, $value, 0); + if ( !($data = $this->getTransient($key)) ) { + $data = $this->parseConfig($config, $validate); + $this->setTransient($key, $data, 0); } } else { - if ( $this->isFile( ($json = "{$dir}/{$config}.json") ) ) { - $value = $this->decodeJson($this->readfile($json), $isArray); - } + $data = $this->parseConfig($config, $validate); } - return $value; - } - - /** - * Set global config path. - * - * @access protected - * @param string $path - * @return void - */ - protected function setConfigPath($path = '/global.json') - { - $this->config = $path; + return $this->toArray($data); } /** - * Get dynamic relative root. + * Get dynamic root path. * * @access protected * @param string $sub @@ -277,6 +272,24 @@ protected function getNameSpace() : string ); } + /** + * Get static prefix. + * + * @access protected + * @param bool $sep, Separator + * @return string + */ + protected function getPrefix(bool $sep = true) : string + { + $prefix = $this->undash( + $this->getNameSpace() + ); + if ( $sep ) { + $prefix = "{$prefix}_"; + } + return $prefix; + } + /** * Get static name. * @@ -332,24 +345,6 @@ protected function getPluginVersion() : string return $this->getConfig('version'); } - /** - * Get static prefix. - * - * @access protected - * @param bool $sep, Separator - * @return string - */ - protected function getPrefix(bool $sep = true) : string - { - $prefix = $this->undash( - $this->getNameSpace() - ); - if ( $sep ) { - $prefix = "{$prefix}_"; - } - return $prefix; - } - /** * Get static assets relative path. * @@ -452,8 +447,7 @@ protected function getTempPath(?string $sub = null) : string protected function getExpireIn() : int { $config = $this->getConfig('options'); - $data = $config->ttl ?? 0; - return (int)$data; + return$config->ttl; } /** @@ -465,8 +459,7 @@ protected function getExpireIn() : int protected function getTimeout() : int { $config = $this->getConfig('options'); - $data = $config->timeout ?? 0; - return (int)$data; + return $config->timeout; } /** @@ -478,8 +471,7 @@ protected function getTimeout() : int protected function getSecret() : string { $config = $this->getConfig('options'); - $data = $config->secret ?? 0; - return (string)$data; + return $config->secret; } /** @@ -517,10 +509,84 @@ protected function getLoggerPath() : string protected function getViewExtension() : string { $config = $this->getConfig('options'); - $data = $config->view->extension ?? '.html'; - return (string)$data; + return $config->view->extension; + } + + /** + * Get plugin roles. + * + * @access protected + * @return array + */ + protected function getPluginRoles() : array + { + $config = $this->getConfig('options'); + return $config->roles; + } + + /** + * Get multiling status. + * + * @access protected + * @return bool + */ + protected function isMultilingual() : bool + { + $config = $this->getConfig('options'); + return $config->multiling; + } + + /** + * Get multisite status. + * + * @access protected + * @return bool + */ + protected function allowedMultisite() : bool + { + $config = $this->getConfig('options'); + return $config->multisite; + } + + /** + * Get plugin debug status. + * + * @access protected + * @return bool + */ + protected function hasDebug() : bool + { + $config = $this->getConfig('options'); + return $config->debug; } + /** + * Get static environment. + * + * @access protected + * @return string + */ + protected function getEnv() : string + { + $config = $this->getConfig('options'); + return $config->environment; + } + + /** + * Get plugin remote server host. + * + * @access protected + * @return string + */ + protected function getHost() : string + { + $config = $this->getConfig('options'); + if ( !($data = $config->remote->host) ) { + $data = $this->getRemoteServer('host'); + } + return $data; + } + /** * Get main filename. * @@ -541,7 +607,9 @@ protected function getMainFile() : string */ protected function getMainFilePath() : string { - return $this->getRoot("{$this->getNameSpace()}.php"); + return $this->getRoot( + "{$this->getNameSpace()}.php" + ); } /** @@ -552,23 +620,24 @@ protected function getMainFilePath() : string */ protected function getBaseUrl() : string { - return $this->getPluginUrl("{$this->getNameSpace()}"); + return $this->getPluginUrl( + "{$this->getNameSpace()}" + ); } /** * Get ajax actions. * * @access protected - * @return object + * @param string $type + * @return array */ - protected function getAjax() : object + protected function getAjax(?string $type = null) : array { $this->initConfig(); - if ( !($data = $this->loadConfig('ajax')) ) { - $data = $this->global->ajax ?? []; - } + $data = $this->loadConfig('ajax'); $this->resetConfig(); - return (object)$data; + return ($type) ? $data[$type] : $data; } /** @@ -579,8 +648,7 @@ protected function getAjax() : object */ protected function getAdminAjax() : array { - $data = $this->getAjax()->admin ?? []; - return (array)$data; + return $this->getAjax('admin'); } /** @@ -591,40 +659,50 @@ protected function getAdminAjax() : array */ protected function getFrontAjax() : array { - $data = $this->getAjax()->front ?? []; - return (array)$data; + return $this->getAjax('front'); } /** - * Get plugin roles. + * Get cron data. * * @access protected + * @param string $type * @return array */ - protected function getPluginRoles() : array + protected function getCron(?string $type = null) : array { $this->initConfig(); - if ( !($data = $this->loadConfig('roles', true)) ) { - $data = $this->global->roles ?? []; - } + $data = $this->loadConfig('cron'); $this->resetConfig(); - return (array)$data; + return ($type) ? $data[$type] : $data; } /** - * Get cron actions. + * Get cron events. * * @access protected * @return array */ - protected function getCron() : array + protected function getEvents() : array { - $this->initConfig(); - if ( !($data = $this->loadConfig('cron', true)) ) { - $data = $this->global->cron ?? []; + return $this->getCron('events'); + } + + /** + * Get cron schedules. + * + * @access protected + * @return array + */ + protected function getSchedules() : array + { + $data = []; + foreach ($this->getCron('schedules') as $schedule) { + $name = $schedule['name']; + unset($schedule['name']); + $data[$name] = $schedule; } - $this->resetConfig(); - return (array)$data; + return $data; } /** @@ -636,59 +714,55 @@ protected function getCron() : array protected function getRoutes() : array { $this->initConfig(); - if ( !($data = $this->loadConfig('routes', true)) ) { - $data = $this->global->routes ?? []; - } + $data = $this->loadConfig('routes'); $this->resetConfig(); - return (array)$data; + return $data['routes']; } /** * Get requirements. * * @access protected - * @return object + * @return array */ - protected function getRequirements() : object + protected function getRequirements() : array { $this->initConfig(); - if ( !($data = $this->loadConfig('requirements')) ) { - $data = $this->global->requirements ?? []; - } + $data = $this->loadConfig('requirements'); $this->resetConfig(); - return (object)$data; + return $data; } /** - * Get hooks. + * Get settings inputs. * * @access protected * @return array */ - protected function getHooks() : array + protected function getInputs() : array { $this->initConfig(); - if ( !($data = $this->loadConfig('hooks', true)) ) { - $data = $this->global->hooks ?? []; - } + $data = $this->loadConfig('inputs'); $this->resetConfig(); - return (array)$data; + return $data; } /** - * Get settings inputs. + * Get hooks. * * @access protected * @return array */ - protected function getInputs() : array + protected function getHooks() : array { - $this->initConfig(); - if ( !($data = $this->loadConfig('inputs', true)) ) { - $data = $this->global->inputs ?? []; + $data = []; + foreach ($this->getInputs() as $key => $value) { + $active = $value['hook'] ?? false; + if ( $active === true ) { + $data[] = $key; + } } - $this->resetConfig(); - return (array)$data; + return $data; } /** @@ -700,11 +774,9 @@ protected function getInputs() : array protected function getSettings() : array { $this->initConfig(); - if ( !($data = $this->loadConfig('settings', true)) ) { - $data = $this->global->settings ?? []; - } + $data = $this->loadConfig('settings'); $this->resetConfig(); - return (array)$data; + return $data['settings']; } /** @@ -716,28 +788,28 @@ protected function getSettings() : array protected function getGroupSettings() : array { $data = []; - foreach ($this->getSettings() as $group) { - $name = $group['group']; - unset($group['group']); - $data[$name][] = $group; + foreach ($this->getSettings() as $option) { + $data[$option['name']] = [ + 'value' => $option['value'], + 'lang' => $option['lang'] + ]; } - return (array)$data; + return $data; } /** * Get plugin assets. * * @access protected + * @param string $type * @return array */ - protected function getAssets() : array + protected function getAssets(?string $type = null) : array { $this->initConfig(); - if ( !($data = $this->loadConfig('assets', true)) ) { - $data = $this->global->assets ?? []; - } + $data = $this->loadConfig('assets'); $this->resetConfig(); - return (array)$data; + return ($type) ? $data[$type] : $data; } /** @@ -748,20 +820,24 @@ protected function getAssets() : array */ protected function getRemoteAssets() : array { - $data = $this->getAssets()['remote'] ?? []; - return (array)$data; + $data = []; + foreach ($this->getAssets('remote') as $asset) { + $data[$asset['name']] = $asset['src']; + } + return $data; } /** * Get plugin local assets. * * @access protected + * @param string $type * @return array */ - protected function getLocalAssets() : array + protected function getLocalAssets(?string $type = null) : array { - $data = $this->getAssets()['local'] ?? []; - return (array)$data; + $data = $this->getAssets('local'); + return ($type) ? $data[$type] : $data; } /** @@ -774,8 +850,8 @@ protected function getLocalAssets() : array */ protected function getAdminAssets(string $type, string $env = 'main') : array { - $data = $this->getLocalAssets()['admin'] ?? []; - $data = $this->mapArray(function($item) use ($type, $env) { + $data = $this->getLocalAssets('admin'); + $data = $this->map(function($item) use ($type, $env) { if ( $item['type'] === $type && $item['env'] === $env ) { return $item['path']; } @@ -792,8 +868,8 @@ protected function getAdminAssets(string $type, string $env = 'main') : array */ protected function getFrontAssets(string $type, string $env = 'main') : array { - $data = $this->getLocalAssets()['front'] ?? []; - $data = $this->mapArray(function($item) use ($type, $env) { + $data = $this->getLocalAssets('front'); + $data = $this->map(function($item) use ($type, $env) { if ( $item['type'] === $type && $item['env'] === $env ) { return $item['path']; } @@ -806,96 +882,30 @@ protected function getFrontAssets(string $type, string $env = 'main') : array * Get strings. * * @access protected + * @param string $type * @return array */ - protected function getStrings() : array + protected function getStrings(?string $type = null) : array { $this->initConfig(); - if ( !($data = $this->loadConfig('strings', true)) ) { - $data = $this->global->strings ?? []; - } + $data = $this->loadConfig('strings'); $this->resetConfig(); - return (array)$data; - } - - /** - * Get multiling status. - * - * @access protected - * @return bool - */ - protected function isMultilingual() : bool - { - $config = $this->getConfig('options'); - $data = $config->multiling ?? false; - return (bool)$data; - } - - /** - * Get multisite status. - * - * @access protected - * @return bool - */ - protected function allowedMultisite() : bool - { - $config = $this->getConfig('options'); - $data = $config->multisite ?? false; - return (bool)$data; - } - - /** - * Get plugin debug status. - * - * @access protected - * @return bool - */ - protected function hasDebug() : bool - { - $config = $this->getConfig('options'); - $data = $config->debug ?? false; - return (bool)$data; - } - - /** - * Get static environment. - * - * @access protected - * @return string - */ - protected function getEnv() : string - { - $config = $this->getConfig('options'); - $data = $config->environment ?? 'dev'; - return (string)$data; + return ($type) ? $data[$type] : $data; } /** * Get plugin remote server. * * @access protected - * @return array + * @param string $var + * @return mixed */ - protected function getRemoteServer() : array + protected function getRemoteServer(?string $var = null) { $this->initConfig(); - if ( !($data = $this->loadConfig('remote', true)) ) { - $data = $this->global->remote ?? []; - } + $data = $this->loadConfig('remote'); $this->resetConfig(); - return (array)$data; - } - - /** - * Get plugin remote server host. - * - * @access protected - * @return string - */ - protected function getHost() : string - { - $host = $this->getRemoteServer()['host'] ?? false; - return $host ?: ''; + return ($var) ? $data[$var] : $data; } /** diff --git a/src/VanillePluginOption.php b/src/VanillePluginOption.php index f3d89c2f..f8053e90 100644 --- a/src/VanillePluginOption.php +++ b/src/VanillePluginOption.php @@ -15,7 +15,7 @@ namespace VanillePlugin; /** - * Define tweaked base functions used by plugin. + * Define tweaked plugin base functions. * * - Hooking * - Rendering @@ -23,8 +23,8 @@ * - Configuration * - Translation * - Formatting - * - IO * - Caching + * - IO * - Requesting * * @see https://developer.wordpress.org/plugins/ @@ -173,9 +173,9 @@ protected function hasPluginShortcode() : bool * @access protected * @inheritdoc */ - protected function registerPluginOption(string $group, string $key, array $args = [], bool $multi = true) + protected function registerPluginOption(string $group, string $key, array $args = [], bool $lang = true) { - $key = $this->getOptionLang($key, $multi); + $key = $this->getOptionLang($key, $lang); $group = $this->applyPrefix($group); $this->registerOption($group, $key, $args); } @@ -186,9 +186,9 @@ protected function registerPluginOption(string $group, string $key, array $args * @access protected * @inheritdoc */ - protected function addPluginOption(string $key, $value, bool $multi = true) : bool + protected function addPluginOption(string $key, $value, bool $lang = true) : bool { - $key = $this->getOptionLang($key, $multi); + $key = $this->getOptionLang($key, $lang); return $this->addOption($key, $value); } @@ -198,9 +198,9 @@ protected function addPluginOption(string $key, $value, bool $multi = true) : bo * @access protected * @inheritdoc */ - protected function getPluginOption(string $key, $default = [], bool $multi = true) + protected function getPluginOption(string $key, $default = [], bool $lang = true) { - $key = $this->getOptionLang($key, $multi); + $key = $this->getOptionLang($key, $lang); $value = $this->stripSlash( $this->getOption($key, $default) ); @@ -213,21 +213,38 @@ protected function getPluginOption(string $key, $default = [], bool $multi = tru * @access protected * @inheritdoc */ - protected function updatePluginOption(string $key, $value, bool $multi = true) : bool + protected function updatePluginOption(string $key, $value, bool $lang = true) : bool { - $key = $this->getOptionLang($key, $multi); + $key = $this->getOptionLang($key, $lang); return $this->updateOption($key, $value); } + /** + * Reset plugin option. + * + * @access protected + * @inheritdoc + */ + protected function resetPluginOption(string $key, $default = []) : bool + { + $settings = $this->getGroupSettings(); + if ( isset($settings[$key]) ) { + $settings = $settings[$key]; + $key = $this->getOptionLang($key, $settings['lang']); + return $this->updateOption($key, $settings['value']); + } + return $this->updateOption($key, $default); + } + /** * Remove plugin option. * * @access protected * @inheritdoc */ - protected function removePluginOption(string $key, bool $multi = true) : bool + protected function removePluginOption(string $key, bool $lang = true) : bool { - $key = $this->getOptionLang($key, $multi); + $key = $this->getOptionLang($key, $lang); return $this->removeOption($key); } @@ -236,12 +253,12 @@ protected function removePluginOption(string $key, bool $multi = true) : bool * * @access protected * @param string $key - * @param bool $multi + * @param bool $lang * @return string */ - protected function getOptionLang(string $key, bool $multi) : string + protected function getOptionLang(string $key, bool $lang) : string { - if ( $this->hasMultilingual() && $multi ) { + if ( $this->hasMultilingual() && $lang ) { $key = "{$key}-{$this->getLang()}"; } return $this->applyPrefix($key); @@ -573,7 +590,7 @@ protected function removePluginCap(string $role, string $cap = 'manage') */ protected function removePluginCaps($roles = [], string $cap = 'manage') { - $this->purgePluginTransients(); + $this->removePluginTransients(); if ( $this->isType('string', $roles) ) { $roles = [$roles]; } @@ -676,6 +693,18 @@ protected function verifyPermission($id = null) } } + /** + * Get plugin secret. + * + * @access protected + * @inheritdoc + */ + protected function getPluginSecret() : string + { + $default = $this->getSecret(); + return $this->getPluginOption('secret', $default, false); + } + /** * Get plugin transient. * @@ -725,18 +754,18 @@ protected function deletePluginTransient(string $key) : bool } /** - * Purge all plugin transients. + * Remove all plugin transients. * * @access protected * @inheritdoc */ - protected function purgePluginTransients() : bool + protected function removePluginTransients() : bool { $namespace = $this->getNameSpace(); if ( $this->isMultisite() && $this->allowedMultisite() ) { - return $this->purgeSiteTransients($namespace); + return $this->removeSiteTransients($namespace); } - return $this->purgeTransients($namespace); + return $this->removeTransients($namespace); } /** @@ -940,7 +969,7 @@ protected function addPluginWidget($cb, ?string $name = null) /** * Load plugin translation (Overridden). - * [Action: init]. + * [Action: front-init]. * [Filter: {plugin}-translation-path]. * * @access public @@ -983,7 +1012,7 @@ public function translateDeep(array $strings) : array } /** - * Load plugin translated strings, + * Load plugin translated strings. * Admin and Front. * * @access public @@ -992,23 +1021,11 @@ public function translateDeep(array $strings) : array */ public function loadStrings(?string $type = null) : array { - $strings = $this->getStrings(); - switch ($type) { - case 'admin': - return $this->translateDeep( - $strings['admin'] - ); - break; - - case 'front': - return $this->translateDeep( - $strings['front'] - ); - break; - } - return $this->translateDeep($strings); + return $this->translateDeep( + $this->getStrings($type) + ); } - + /** * Translate string. * May require quotes escaping. @@ -1023,7 +1040,7 @@ public function translate(string $string) : string } /** - * Translate string with variables, + * Translate string with variables. * May require quotes escaping. * * @access public @@ -1070,7 +1087,7 @@ public function transVar(?string $string, $vars = null) : string } /** - * Set HTTP response, + * Set HTTP response. * Including translated message. * * @access protected diff --git a/src/VanillePluginValidator.php b/src/VanillePluginValidator.php index 962a8a5d..99c93b50 100644 --- a/src/VanillePluginValidator.php +++ b/src/VanillePluginValidator.php @@ -14,61 +14,66 @@ namespace VanillePlugin; -use VanillePlugin\inc\TypeCheck; -use VanillePlugin\exc\ConfigurationException; +use VanillePlugin\exc\ConfigException; +use VanillePlugin\inc\{ + TypeCheck, Stringify, Arrayify +}; use JsonSchema\Validator; +/** + * Configuration validator. + */ final class VanillePluginValidator { /** - * Check configuration object. - * + * Validate config data using schema. + * * @access public - * @var mixed $global, - * @var string $file + * @var mixed $data + * @var string $schema * @return void - * @throws ConfigurationException + * @throws ConfigException */ - public static function checkConfig($global, ?string $file = null) + public static function validate($data, string $schema) { - $error = self::isValidConfig($global); - if ( TypeCheck::isString($error) ) { - throw new ConfigurationException( - ConfigurationException::invalidPluginConfiguration($error, $file) - ); + if ( !self::isValid($data, $schema, $error) ) { - } elseif ( $error === false ) { - throw new ConfigurationException( - ConfigurationException::invalidPluginConfigurationFormat($file) + if ( TypeCheck::isString($error) ) { + throw new ConfigException( + ConfigException::invalidConfig($error, $schema) + ); + } + + throw new ConfigException( + ConfigException::invalidConfigFormat($schema) ); } } /** - * Validate plugin configuration. - * + * Check whether config has valid schema. + * * @access private - * @var mixed $config - * @return mixed + * @var mixed $data + * @var string $schema + * @var string $error + * @return bool */ - private static function isValidConfig($config) + private static function isValid($data, string $schema, &$error = null) : bool { - if ( TypeCheck::isObject($config) ) { - $validator = new Validator(); - $validator->validate($config, (object)[ - '$ref' => 'file://' . __DIR__ . '/bin/config.schema.json' - ]); - if ( $validator->isValid() ) { - return true; + $validator = new Validator(); + $path = Stringify::formatPath(__DIR__ . "/bin/{$schema}.schema.json"); + $validator->validate($data, (object)[ + '$ref' => "file://{$path}" + ]); - } else { - $errors = []; - foreach ($validator->getErrors() as $error) { - $errors[] = sprintf("[%s] %s", $error['property'], $error['message']); - } - return implode("\n", $errors); - } + if ( !$validator->isValid() ) { + $errors = $validator->getErrors(); + $error = Arrayify::shift($errors); + $error = "{$error['message']} [{$error['property']}]"; + return false; } - return false; + + return true; } } diff --git a/src/bin/ajax.schema.json b/src/bin/ajax.schema.json new file mode 100644 index 00000000..03721181 --- /dev/null +++ b/src/bin/ajax.schema.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "plugin.ajax.schema.json", + "type": "object", + "properties": { + "admin": { + "type": "array", + "items": { + "type": "string" + } + }, + "front": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "admin", + "front" + ] +} \ No newline at end of file diff --git a/src/bin/assets.schema.json b/src/bin/assets.schema.json new file mode 100644 index 00000000..765fba9c --- /dev/null +++ b/src/bin/assets.schema.json @@ -0,0 +1,82 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "plugin.assets.schema.json", + "type": "object", + "properties": { + "remote": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "src": { + "type": "array" + } + }, + "required": [ + "name", + "src" + ] + } + }, + "local": { + "type": "object", + "properties": { + "admin": { + "type": "array", + "items": { + "type": "object", + "properties": { + "path": { + "type": "string" + }, + "type": { + "type": "string" + }, + "env": { + "type": "string" + } + }, + "required": [ + "path", + "type", + "env" + ] + } + }, + "front": { + "type": "array", + "items": { + "type": "object", + "properties": { + "path": { + "type": "string" + }, + "type": { + "type": "string" + }, + "env": { + "type": "string" + } + }, + "required": [ + "path", + "type", + "env" + ] + } + } + }, + "required": [ + "admin", + "front" + ] + } + }, + "required": [ + "remote", + "local" + ] +} \ No newline at end of file diff --git a/src/bin/config.schema.json b/src/bin/config.schema.json deleted file mode 100644 index dd1cd51e..00000000 --- a/src/bin/config.schema.json +++ /dev/null @@ -1,306 +0,0 @@ -{ - "$id": "plugin.config.schema.json", - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "version": { - "type": "string" - }, - "author": { - "type": "string" - }, - "description": { - "type": "string" - }, - "link": { - "type": "string" - }, - "path": { - "type": "object", - "required": ["asset", "view", "migrate", "logs", "temp", "cache"], - "properties":{ - "asset":{ - "type": "string" - }, - "view":{ - "type": "string" - }, - "migrate":{ - "type": "string" - }, - "logs":{ - "type": "string" - }, - "temp":{ - "type": "string" - }, - "cache":{ - "type": "string" - } - } - }, - "options": { - "type": "object", - "required": ["ttl", "timeout", "secret", "multiling", "multisite", "footprint", "debug", "view"], - "properties":{ - "ttl":{ - "type": "integer" - }, - "timeout":{ - "type": "integer" - }, - "secret":{ - "type": "string" - }, - "multiling":{ - "type": "boolean" - }, - "multisite":{ - "type": "boolean" - }, - "footprint":{ - "type": "boolean" - }, - "debug":{ - "type": "boolean" - }, - "view":{ - "type": "object", - "properties":{ - "extension":{ - "type": "string" - } - } - } - } - }, - "remote": { - "type": "object", - "required": ["host", "token", "user", "pswd", "key"] - }, - "roles": { - "type": "array" - }, - "ajax": { - "type": "object", - "required": ["admin", "front"], - "properties":{ - "admin":{ - "type": "array" - }, - "front":{ - "type": "array" - } - } - }, - "cron":{ - "type": "object", - "items": [ - { - "type": "object", - "properties":{ - "name":{ - "type": "string" - }, - "schedule":{ - "type": "string" - } - } - } - ] - }, - "hooks":{ - "type": "object", - "items": [ - { - "type": "object", - "properties":{ - "name":{ - "type": "string" - }, - "value":{ - "type": "string" - } - } - } - ] - }, - "settings":{ - "type": "object", - "items": [ - { - "type": "object", - "properties":{ - "name":{ - "type": "string" - }, - "type":{ - "type": "string" - }, - "group":{ - "type": "string" - }, - "value":{ - "type": "null" - }, - "multi":{ - "type": "boolean" - } - } - } - ] - }, - "inputs":{ - "type": "object", - "items": [ - { - "type": "object" - } - ] - }, - "requirements": { - "type": "object", - "required": ["plugins", "options", "templates", "modules", "php"], - "properties":{ - "plugins":{ - "type": "array", - "items": [ - { - "type": "object", - "required": ["slug"], - "properties":{ - "slug":{ - "type": "string" - }, - "callable":{ - "type": "string" - }, - "name":{ - "type": "string" - } - } - } - ] - }, - "options":{ - "type": "array", - "items": [ - { - "type": "object", - "required": ["slug", "value"], - "properties":{ - "slug":{ - "type": "string" - }, - "value":{ - "type": "string" - }, - "name":{ - "type": "string" - } - } - } - ] - }, - "templates":{ - "type": "array", - "items": [ - { - "type": "object", - "required": ["slug"], - "properties":{ - "slug":{ - "type": "string" - }, - "name":{ - "type": "string" - } - } - } - ] - }, - "modules":{ - "type": "array", - "items": [ - { - "type": "object", - "required": ["name", "callable"], - "properties":{ - "name":{ - "type": "string" - }, - "callable":{ - "type": "string" - }, - "override":{ - "type": "object", - "required": ["name", "value"], - "properties": { - "name":{ - "type": "string" - }, - "value":{ - "type": "string" - } - } - } - } - } - ] - }, - "php":{ - "type": "string" - } - } - }, - "routes": { - "type": "array" - }, - "assets": { - "type": "object", - "required": ["admin", "front"], - "properties":{ - "admin":{ - "type": "array" - }, - "front":{ - "type": "array" - } - } - }, - "strings": { - "type": "object", - "required": ["admin", "front"], - "properties":{ - "admin":{ - "type": "array" - }, - "front":{ - "type": "array" - } - } - } - }, - "required": [ - "name", - "version", - "author", - "description", - "link", - "path", - "options", - "remote", - "roles", - "cron", - "hooks", - "settings", - "inputs", - "requirements", - "routes", - "ajax", - "assets", - "strings" - ] -} \ No newline at end of file diff --git a/src/bin/cron.schema.json b/src/bin/cron.schema.json new file mode 100644 index 00000000..cd3a4907 --- /dev/null +++ b/src/bin/cron.schema.json @@ -0,0 +1,57 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "plugin.cron.schema.json", + "type": "object", + "properties": { + "schedules": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "display": { + "type": "string" + }, + "interval": { + "type": "integer" + } + } + } + ], + "required": [ + "name", + "interval" + ] + }, + "events": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "schedule": { + "type": "string" + }, + "callback": { + "type": "string" + } + } + } + ], + "required": [ + "name", + "schedule" + ] + } + }, + "required": [ + "schedules", + "events" + ] +} \ No newline at end of file diff --git a/src/bin/global.schema.json b/src/bin/global.schema.json new file mode 100644 index 00000000..29800d92 --- /dev/null +++ b/src/bin/global.schema.json @@ -0,0 +1,132 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "plugin.global.schema.json", + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "author": { + "type": "string" + }, + "description": { + "type": "string" + }, + "link": { + "type": "string" + }, + "path": { + "type": "object", + "properties": { + "asset": { + "type": "string" + }, + "view": { + "type": "string" + }, + "migrate": { + "type": "string" + }, + "logs": { + "type": "string" + }, + "temp": { + "type": "string" + }, + "cache": { + "type": "string" + } + }, + "required": [ + "asset", + "view", + "migrate", + "logs", + "temp", + "cache" + ] + }, + "options": { + "type": "object", + "properties": { + "ttl": { + "type": "number" + }, + "timeout": { + "type": "number" + }, + "secret": { + "type": "string" + }, + "footprint": { + "type": "boolean" + }, + "debug": { + "type": "boolean" + }, + "environment": { + "type": "string" + }, + "multiling": { + "type": "boolean" + }, + "multisite": { + "type": "boolean" + }, + "roles": { + "type": "array", + "items": { + "type": "string" + } + }, + "remote": { + "type": "object", + "properties": { + "host": { + "type": ["string","boolean"] + } + }, + "required": [ + "host" + ] + }, + "view": { + "type": "object", + "properties": { + "extension": { + "type": "string" + } + }, + "required": [ + "extension" + ] + } + }, + "required": [ + "ttl", + "timeout", + "secret", + "footprint", + "debug", + "environment", + "multiling", + "multisite", + "roles", + "remote", + "view" + ] + } + }, + "required": [ + "name", + "version", + "author", + "description", + "link", + "path", + "options" + ] +} \ No newline at end of file diff --git a/src/bin/inputs.schema.json b/src/bin/inputs.schema.json new file mode 100644 index 00000000..88f9688e --- /dev/null +++ b/src/bin/inputs.schema.json @@ -0,0 +1,22 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id":"plugin.inputs.schema.json", + "type":"object", + "items":[ + { + "type":"object", + "properties":{ + "inputs":{ + "type":"object" + }, + "hook":{ + "type":"boolean" + } + }, + "required": [ + "inputs", + "hook" + ] + } + ] +} \ No newline at end of file diff --git a/src/bin/remote.schema.json b/src/bin/remote.schema.json new file mode 100644 index 00000000..e1d5c85f --- /dev/null +++ b/src/bin/remote.schema.json @@ -0,0 +1,33 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id":"plugin.remote.schema.json", + "type":"object", + "properties":{ + "host":{ + "type":"string" + }, + "backup":{ + "type":"string" + }, + "token":{ + "type":"string" + }, + "user":{ + "type":"string" + }, + "pswd":{ + "type":"string" + }, + "key":{ + "type":"string" + } + }, + "required":[ + "host", + "backup", + "token", + "user", + "pswd", + "key" + ] +} \ No newline at end of file diff --git a/src/bin/requirements.schema.json b/src/bin/requirements.schema.json new file mode 100644 index 00000000..a4ca598c --- /dev/null +++ b/src/bin/requirements.schema.json @@ -0,0 +1,238 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id":"plugin.requirements.schema.json", + "type": "object", + "properties": { + "dependency": { + "type": "object", + "properties": { + "php": { + "type": "string" + }, + "plugins": { + "type": "array", + "items": { + "type": "object", + "properties": { + "slug": { + "type": "string" + }, + "name": { + "type": "string" + }, + "callable": { + "type": "string" + } + }, + "required": [ + "name" + ] + } + }, + "themes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "slug": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "required": [ + "slug", + "name" + ] + } + }, + "paths": { + "type": "array", + "items": { + "type": "string" + } + }, + "options": { + "type": "array", + "items": { + "type": "object", + "properties": { + "slug": { + "type": "string" + }, + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ] + } + }, + "modules": { + "type": "array", + "items": { + "type": "object", + "properties": { + "slug": { + "type": "string" + }, + "name": { + "type": "string" + }, + "callable": { + "type": "string" + }, + "override": { + "type": "object", + "properties": { + "slug": { + "type": "string" + }, + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ] + } + }, + "required": [ + "name", + "callable" + ] + } + } + }, + "required": [ + "php", + "plugins", + "themes", + "paths", + "options", + "modules" + ] + }, + "messages": { + "type": "object", + "properties": { + "php": { + "type": "object", + "properties": { + "version": { + "type": "string" + } + }, + "required": [ + "version" + ] + }, + "plugins": { + "type": "object", + "properties": { + "missing": { + "type": "string" + }, + "disabled": { + "type": "string" + } + }, + "required": [ + "missing", + "disabled" + ] + }, + "themes": { + "type": "object", + "properties": { + "single": { + "type": "string" + }, + "multiple": { + "type": "string" + } + }, + "required": [ + "single", + "multiple" + ] + }, + "paths": { + "type": "object", + "properties": { + "missing": { + "type": "string" + }, + "readable": { + "type": "string" + }, + "writable": { + "type": "string" + } + }, + "required": [ + "missing", + "readable", + "writable" + ] + }, + "options": { + "type": "object", + "properties": { + "missing": { + "type": "string" + }, + "invalid": { + "type": "string" + } + }, + "required": [ + "missing", + "invalid" + ] + }, + "modules": { + "type": "object", + "properties": { + "missing": { + "type": "string" + }, + "override": { + "type": "string" + } + }, + "required": [ + "missing", + "override" + ] + } + }, + "required": [ + "php", + "plugins", + "themes", + "paths", + "options", + "modules" + ] + }, + "template": { + "type": "string" + } + }, + "required": [ + "dependency", + "messages", + "template" + ] +} \ No newline at end of file diff --git a/src/bin/routes.schema.json b/src/bin/routes.schema.json new file mode 100644 index 00000000..cd0a44c2 --- /dev/null +++ b/src/bin/routes.schema.json @@ -0,0 +1,28 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "plugin.routes.schema.json", + "type": "object", + "properties": { + "routes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "route": { + "type": "string" + }, + "method": { + "type": ["string","array"] + } + }, + "required": [ + "route", + "method" + ] + } + } + }, + "required": [ + "routes" + ] +} \ No newline at end of file diff --git a/src/bin/settings.schema.json b/src/bin/settings.schema.json new file mode 100644 index 00000000..5bb1213f --- /dev/null +++ b/src/bin/settings.schema.json @@ -0,0 +1,40 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "plugin.settings.schema.json", + "type": "object", + "properties": { + "settings": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "group": { + "type": "string" + }, + "type": { + "type": "string" + }, + "value": { + "type": "object" + }, + "lang": { + "type": "boolean" + } + }, + "required": [ + "name", + "group", + "type", + "value", + "lang" + ] + } + } + }, + "required": [ + "settings" + ] +} \ No newline at end of file diff --git a/src/bin/strings.schema.json b/src/bin/strings.schema.json new file mode 100644 index 00000000..92dcfce9 --- /dev/null +++ b/src/bin/strings.schema.json @@ -0,0 +1,17 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "plugin.strings.schema.json", + "type": "object", + "properties": { + "admin": { + "type": "object" + }, + "front": { + "type": "object" + } + }, + "required": [ + "admin", + "front" + ] +} \ No newline at end of file diff --git a/src/exc/ConfigurationException.php b/src/exc/ConfigException.php similarity index 51% rename from src/exc/ConfigurationException.php rename to src/exc/ConfigException.php index 17ee5f19..81bcf1d9 100644 --- a/src/exc/ConfigurationException.php +++ b/src/exc/ConfigException.php @@ -14,20 +14,20 @@ namespace VanillePlugin\exc; -class ConfigurationException extends VanillePluginException +class ConfigException extends VanillePluginException { - public static function invalidPluginConfigurationFile($file) : string + public static function invalidConfigFile(string $file) : string { return "Couldn't find plugin configuration file: '{$file}'"; } - public static function invalidPluginConfigurationFormat($file) : string + public static function invalidConfigFormat(string $schema) : string { - return "Invalid plugin configuration JSON format: '{$file}'"; + return "Invalid plugin configuration JSON format: '{$schema}'"; } - public static function invalidPluginConfiguration($error, $file) : string + public static function invalidConfig(string $error, string $schema) : string { - return "Invalid plugin configuration: '{$error}' in '{$file}'"; + return "Invalid plugin configuration: '{$error}' in '{$schema}'"; } } diff --git a/src/exc/ModelException.php b/src/exc/ModelException.php index b7bbc66a..02bec2b6 100644 --- a/src/exc/ModelException.php +++ b/src/exc/ModelException.php @@ -23,6 +23,6 @@ public static function undefinedTable() : string public static function invalidInstance() : string { - return 'Invalid shortcode part instance'; + return 'Invalid db instance'; } } diff --git a/src/exc/RequestException.php b/src/exc/RequestException.php new file mode 100644 index 00000000..e083c0e4 --- /dev/null +++ b/src/exc/RequestException.php @@ -0,0 +1,23 @@ + + * @link : https://jakiboy.github.io/VanillePlugin/ + * @license : MIT + * + * This file if a part of VanillePlugin Framework. + */ + +declare(strict_types=1); + +namespace VanillePlugin\exc; + +class RequestException extends VanillePluginException +{ + public static function invalidInstance() : string + { + return 'Invalid request instance'; + } +} diff --git a/src/inc/Archive.php b/src/inc/Archive.php index a3e8ef91..4a6c6786 100644 --- a/src/inc/Archive.php +++ b/src/inc/Archive.php @@ -18,6 +18,10 @@ use \RecursiveIteratorIterator; use \RecursiveDirectoryIterator; +/** + * Built-in archive class. + * Filesystem API is recommended for external use. + */ final class Archive extends File { /** @@ -107,7 +111,7 @@ public static function uncompress(string $archive, string $to = '', bool $remove $status = self::unGzip($archive); } else { - self::init(); + Filesystem::init(); $unzip = unzip_file($archive, $to); if ( !Exception::isError($unzip) ) { $status = true; diff --git a/src/inc/Arrayify.php b/src/inc/Arrayify.php index f8270952..4ed6a853 100644 --- a/src/inc/Arrayify.php +++ b/src/inc/Arrayify.php @@ -77,8 +77,11 @@ public static function combine(array $keys, array $values) : array * @param array $arrays * @return array */ - public static function map($callback, array $array, ?array $arrays = null) + public static function map($callback, array $array, ?array $arrays = null) : array { + if ( TypeCheck::isString($callback) ) { + $callback = Stringify::undash($callback); + } if ( TypeCheck::isArray($arrays) ) { return array_map($callback, $array, $arrays); } @@ -152,6 +155,18 @@ public static function keys(array $array, $value = null, bool $search = false) : return array_keys($array); } + /** + * Get single array key. + * + * @access public + * @param array $array + * @return mixed + */ + public static function key(array $array) + { + return array_key_first($array); + } + /** * Fill array keys. * diff --git a/src/inc/Attachment.php b/src/inc/Attachment.php index 1fc7a0c4..6b0443cb 100644 --- a/src/inc/Attachment.php +++ b/src/inc/Attachment.php @@ -17,7 +17,7 @@ final class Attachment { /** - * Insert attachment, + * Insert attachment. * Returns attachment data if success. * * @access public @@ -38,7 +38,7 @@ public static function insert(string $path, array $data) } /** - * Pre-insert attachment, + * Pre-insert attachment. * Returns attachment Id on success. * * @access public diff --git a/src/inc/Converter.php b/src/inc/Converter.php index a013d560..0568266f 100644 --- a/src/inc/Converter.php +++ b/src/inc/Converter.php @@ -115,9 +115,7 @@ public static function toType($value) public static function toTypes($value) { if ( TypeCheck::isArray($value) ) { - return Arrayify::map(function($item){ - return self::toType($item); - }, $value); + return Arrayify::map([static::class, 'toTypes'], $value); } return Converter::toType($value); } diff --git a/src/inc/Cookie.php b/src/inc/Cookie.php index 44873704..86cb1492 100644 --- a/src/inc/Cookie.php +++ b/src/inc/Cookie.php @@ -32,7 +32,7 @@ public static function get(?string $key = null) } /** - * Sey _COOKIE value. + * Set _COOKIE value. * * @access public * @param string $key diff --git a/src/inc/Crawler.php b/src/inc/Crawler.php index 0ff5476f..f5cbfe83 100644 --- a/src/inc/Crawler.php +++ b/src/inc/Crawler.php @@ -29,9 +29,11 @@ final class Crawler extends Request * @access private * @var string $pattern * @var array $args + * @var int $status */ private $pattern; private $args; + private $status = 0; /** * Init crawler. @@ -55,9 +57,9 @@ public function __construct(string $pattern = self::PATTERN, array $args = []) * * @access public * @param int $try - * @return void + * @return bool */ - public function start(int $try = 2) + public function start(int $try = 2) : bool { if ( self::canStart() ) { $try = ($try <= 5) ? $try : 2; @@ -67,6 +69,7 @@ public function start(int $try = 2) } } } + return (bool)$this->status; } /** @@ -81,7 +84,10 @@ private function ping(string $url, int $try = 2) { $i = 1; while ( $i <= $try ) { - self::do($url, $this->args); + $response = self::do($url, $this->args); + if ( self::getStatusCode($response) == 200 ) { + $this->status += 1; + } $i++; sleep(1); } diff --git a/src/inc/Encryption.php b/src/inc/Encryption.php index 05255911..93405b0f 100644 --- a/src/inc/Encryption.php +++ b/src/inc/Encryption.php @@ -24,7 +24,7 @@ class Encryption * @access public * @var string PREFIX Default encryption prefix */ - public const PREFIX = '[vanillecrypt]'; + public const PREFIX = '[VanilleCrypt]'; /** * @access private @@ -45,7 +45,7 @@ class Encryption /** * @access private * @var mixed $data - * @var string $key, Secret key (Passphrase) + * @var string $secret, Secret key (Passphrase) * @var string $vector, Initialzation vector * @var int $length, Encryption vector length * @var string $prefix, Encryption prefix @@ -55,7 +55,7 @@ class Encryption * @var bool $bypass, Bypass encrypted string */ private $data; - private $key; + private $secret; private $vector; private $length; private $prefix; @@ -68,26 +68,26 @@ class Encryption * Init encryption (Encrypt / Decrypt). * * @param mixed $data - * @param string $key + * @param string $secret * @param string $vector * @param int $length */ - public function __construct($data, ?string $key = self::SECRET, ?string $vector = self::VECTOR, ?int $length = self::LENGTH) + public function __construct($data, ?string $secret = self::SECRET, ?string $vector = self::VECTOR, ?int $length = self::LENGTH) { // Set data $this->data = $data; // Set secret key - $this->key = $key; + $this->secret = $secret; // Set vector $this->vector = $vector; $this->length = $length; // Initialize + $this->setPrefix(self::PREFIX); $this->setOptions(); $this->setCipher(); - $this->setPrefix(); $this->initialize(); } @@ -124,11 +124,9 @@ public function setCipher(string $cipher = self::CIPHER) : self * @param string $prefix * @param object */ - public function setPrefix(string $prefix = self::PREFIX) : self + public function setPrefix(?string $prefix = null) : self { - $prefix = Stringify::remove('[', $prefix); - $prefix = Stringify::remove(']', $prefix); - $this->prefix = ($prefix) ? "[$prefix]" : $prefix; + $this->prefix = (string)$prefix; return $this; } @@ -141,7 +139,7 @@ public function setPrefix(string $prefix = self::PREFIX) : self */ public function initialize(string $algo = self::ALGO) : self { - $this->key = hash($algo, $this->key); + $this->secret = hash($algo, $this->secret); $this->vector = substr(hash($algo, $this->vector), 0, $this->length); return $this; } @@ -168,7 +166,7 @@ public function encrypt(int $loop = 1) : string $encrypt = openssl_encrypt( $this->data, $this->cipher, - $this->key, + $this->secret, $this->options, $this->vector ); @@ -196,7 +194,7 @@ public function decrypt(int $loop = 1) $decrypted = (string)openssl_decrypt( Tokenizer::unbase64($crypted, $loop), $this->cipher, - $this->key, + $this->secret, $this->options, $this->vector ); @@ -232,7 +230,7 @@ public function bypass() : self $this->bypass = true; return $this; } - + /** * Check whether data is crypted using prefix. * @@ -241,6 +239,7 @@ public function bypass() : self */ public function isCrypted() : bool { - return (substr($this->data, 0, strlen($this->prefix)) === $this->prefix); + $prefix = substr($this->data, 0, strlen($this->prefix)); + return ($prefix === $this->prefix); } } diff --git a/src/inc/Exception.php b/src/inc/Exception.php index d6961ef2..d0e63918 100644 --- a/src/inc/Exception.php +++ b/src/inc/Exception.php @@ -59,18 +59,20 @@ public static function clearLastError() /** * Trigger user error. * + * [E_USER_NOTICE: 1024] + * * @access public * @param string $error * @param int $type * @return bool */ - public static function trigger(string $error, int $type = E_USER_NOTICE) : bool + public static function trigger(string $error, int $type = 1024) : bool { return trigger_error($error, $type); } /** - * Return WordPress error object. + * Return error object. * * @access public * @param mixed $code @@ -84,8 +86,7 @@ public static function error($code, ?string $message = null, $data = []) : objec } /** - * Kill WordPress execution, - * Display optional message. + * Throw error and stop execution. * * @access public * @param mixed $message @@ -99,7 +100,7 @@ public static function throw($message = '', $title = '', $args = []) } /** - * Kill WordPress execution. + * Stop execution. * * @access public * @return void @@ -110,29 +111,29 @@ public static function die() } /** - * Check for WordPress error. + * Get object error message. * * @access public * @param mixed $object - * @return bool + * @return mixed */ - public static function isError($object) : bool + public static function getError($object) { - return is_wp_error($object); + if ( self::isError($object) ) { + return $object->get_error_message(); + } + return false; } /** - * Get WordPress error. + * Check object error. * * @access public * @param mixed $object - * @return mixed + * @return bool */ - public static function getError($object) + public static function isError($object) : bool { - if ( self::isError($object) ) { - return $object->get_error_message(); - } - return false; + return is_wp_error($object); } } diff --git a/src/inc/File.php b/src/inc/File.php index 1c43916a..5b083724 100644 --- a/src/inc/File.php +++ b/src/inc/File.php @@ -37,7 +37,8 @@ public static function analyse($path) : array 'accessed' => self::getLastAccess($path), 'changed' => self::getLastChange($path), 'size' => self::getSize($path), - 'permissions' => self::getPermissions($path) + 'permissions' => self::getPermissions($path), + 'type' => self::getMimeType($path) ]; } @@ -57,6 +58,7 @@ public static function getParentDir(string $path) : string /** * Get file extension. + * [PATHINFO_EXTENSION: 4]. * * @access public * @param string $path @@ -65,10 +67,8 @@ public static function getParentDir(string $path) : string */ public static function getExtension(string $path, bool $format = true) : string { - $ext = pathinfo( - Stringify::formatPath($path), - PATHINFO_EXTENSION - ); + $path = Stringify::formatPath($path); + $ext = pathinfo($path, 4); if ( $format ) { $ext = strtolower($ext); } @@ -431,12 +431,11 @@ public static function removeDir(string $path, bool $clear = false) : bool */ public static function clearDir(string $path) : bool { - $handler = false; - - if ( self::isDir($path) ) { - $handler = @opendir($path); + if ( !self::isDir($path) ) { + return false; } + $handler = @opendir($path); if ( !TypeCheck::isResource($handler) ) { return false; } @@ -463,6 +462,7 @@ public static function clearDir(string $path) : bool } } } + closedir($handler); return true; } @@ -696,48 +696,42 @@ public static function download($path, $remove = true, $timeout = 300, $verify = } /** - * Validate file. + * Get file mime type. + * [FILEINFO_MIME_TYPE: 16]. * * @access public - * @param string $file - * @param array $allowed - * @return mixed + * @param string $path + * @param string $ext + * @param array $types + * @return string */ - public static function validate($file, $allowed = []) + public static function getMimeType(string $path, ?string $ext = null, ?array $types = []) : string { - // Check filename - if ( empty($name = self::getFileName($file)) ) { - return false; + if ( TypeCheck::isClass('\finfo') ) { + return (new \finfo(16))->file($path) ?: 'undefined'; } - // Basic security check by mime type - if ( Validator::isValidMime($name, $allowed) ) { - return $name; + if ( !$ext ) { + $ext = self::getExtension($path); } - return false; - } + foreach ($types as $match => $type) { + $match = explode('|', $match); + if ( Arrayify::inArray($ext, $match)) { + return $type; + } + } - /** - * Get file mime type. - * - * @access public - * @param string $path - * @param array $mimes - * @return array - */ - public static function getMime($path, ?array $mimes = null) : array - { - return wp_check_filetype($path, $mimes); + return 'undefined'; } /** - * Get allowed files mimes types. + * Get file allowed mime types. * * @access public * @return array */ - public static function mimes() : array + public static function getMimes() : array { return get_allowed_mime_types(); } diff --git a/src/inc/Form.php b/src/inc/Form.php index 03486c00..c99c9e1a 100644 --- a/src/inc/Form.php +++ b/src/inc/Form.php @@ -1189,6 +1189,9 @@ protected function applyDefault() */ protected function applyVars() { - $this->output = Stringify::replaceArray($this->vars, $this->output); + $this->output = Stringify::replaceArray( + $this->vars, + $this->output + ); } } \ No newline at end of file diff --git a/src/inc/Format.php b/src/inc/Format.php index be8388c7..a65956a8 100644 --- a/src/inc/Format.php +++ b/src/inc/Format.php @@ -74,8 +74,11 @@ public static function hook(string $hook) : string // Format custom hooks $format = [ 'loaded' => 'wp_loaded', + 'setup' => 'wp', 'headers' => 'wp_headers', 'head' => 'wp_head', + 'front-init' => 'init', + 'template' => 'template_redirect', 'body' => 'wp_body_open', 'title' => 'the_title', 'content' => 'the_content', @@ -134,6 +137,10 @@ public static function hook(string $hook) : string 'rest-api-dispatch' => 'rest_pre_dispatch', 'rest-api-callback' => 'rest_request_before_callbacks', 'rest-api-nocache' => 'rest_send_nocache_headers', + 'app-password' => 'wp_is_application_passwords_available', + 'app-password-user' => 'wp_is_application_passwords_available_for_user', + 'user-profile' => 'show_user_profile', + 'update-profile' => 'personal_options_update' ]; if ( isset($format[$name]) ) { @@ -232,7 +239,7 @@ public static function undash(array $args) : array } return $args; } - + /** * Get post formatted data. * @@ -277,7 +284,7 @@ public static function user($user) $name = $user->data->user_nicename; } return [ - 'id' => $user->data->ID, + 'id' => (int)$user->data->ID, 'login' => $user->data->user_login, 'name' => $name, 'email' => $user->data->user_email, diff --git a/src/inc/Globals.php b/src/inc/Globals.php index 29501cee..d7f8e5f6 100644 --- a/src/inc/Globals.php +++ b/src/inc/Globals.php @@ -73,6 +73,17 @@ public static function styles() return $wp_styles; } + /** + * Get site installing status. + * + * @access public + * @return bool + */ + public static function installing() : bool + { + return wp_installing(); + } + /** * Get site debug status. * @@ -107,7 +118,7 @@ public static function multisite() : bool } /** - * Check mobile. + * Check mobile device. * * @access public * @return bool @@ -118,7 +129,7 @@ public static function mobile() : bool } /** - * Check ajax. + * Check Ajax request. * * @access public * @return bool @@ -126,7 +137,8 @@ public static function mobile() : bool public static function ajax() : bool { $request = Server::get('request-uri'); - return Stringify::contains($request, 'admin-ajax.php'); + $ajax = Stringify::basename(self::ajaxUrl()); + return (Stringify::contains($request, $ajax)); } /** @@ -207,7 +219,7 @@ public static function pluginDir() : string */ public static function pluginMuDir() : string { - return WPMU_PLUGIN_URL; + return WPMU_PLUGIN_DIR; } /** @@ -259,7 +271,7 @@ public static function rootDir(?string $path = null) : string } /** - * Get front url. + * Get front URL. * * @access public * @param string $path @@ -301,7 +313,7 @@ public static function siteDomain() : string } /** - * Get admin url. + * Get admin URL. * * @access public * @param string $path @@ -315,7 +327,7 @@ public static function adminUrl(?string $path = null, string $scheme = 'admin') } /** - * Get includes url. + * Get includes URL. * * @access public * @param string $path @@ -329,7 +341,7 @@ public static function includesUrl(?string $path = null, string $scheme = 'admin } /** - * Get REST url. + * Get REST URL. * * @access public * @param string $path @@ -342,7 +354,7 @@ public static function restUrl(?string $path = null, string $scheme = 'rest') } /** - * Get ajax url. + * Get Ajax URL. * * @access public * @param string $scheme @@ -388,4 +400,18 @@ public static function privacyUrl() : string { return get_privacy_policy_url(); } + + /** + * Get upload directory info. + * + * @access public + * @param string $time + * @param bool $create + * @param bool $refresh + * @return array + */ + public static function upload(?string $time = null, bool $create = true, bool $refresh = false) : array + { + return wp_upload_dir($time, $create, $refresh); + } } diff --git a/src/inc/Hook.php b/src/inc/Hook.php index 59a0f0f8..f9833885 100644 --- a/src/inc/Hook.php +++ b/src/inc/Hook.php @@ -14,6 +14,9 @@ namespace VanillePlugin\inc; +/** + * @see https://developer.wordpress.org/apis/hooks/ + */ final class Hook { /** @@ -46,8 +49,7 @@ public static function deactivation(string $file, $callback) /** * Register plugin uninstall hook. - * Use class name instead of object ['Plugin', 'uninstall']. - * @uses isAdmin() + * Use static class [static::class, 'uninstall']. * * @access public * @param string $file @@ -56,9 +58,7 @@ public static function deactivation(string $file, $callback) */ public static function uninstall(string $file, $callback) { - if ( Page::isAdmin() ) { - register_uninstall_hook($file, $callback); - } + register_uninstall_hook($file, $callback); } /** @@ -322,13 +322,14 @@ public static function hasScript(string $search, $scripts) : bool */ public static function removeScripts(array $exclude) { - foreach (Globals::scripts()->queue as $script) { + $scripts = Globals::scripts()->queue ?? []; + foreach ($scripts as $script) { if ( self::hasScript($script, $exclude) !== false ) { self::removeJS($script); } } - - foreach (Globals::styles()->queue as $style) { + $styles = Globals::styles()->queue ?? []; + foreach ($styles as $style) { if ( self::hasScript($style, $exclude) !== false ) { self::removeCSS($style); } diff --git a/src/inc/Image.php b/src/inc/Image.php index 441fe16d..1ad82b9e 100644 --- a/src/inc/Image.php +++ b/src/inc/Image.php @@ -27,14 +27,14 @@ final class Image extends File public static function importUrl(string $url, bool $override = true) { // Check valid image - if ( !($name = self::validateMime($url)) ) { + if ( !($name = self::isValidMime($url)) ) { return false; } // Set image upload data - $data = self::getMime($name); + $data = self::getMimeType($name); $mime = $data['type']; - $dir = Upload::dir(); + $dir = Globals::upload(); $path = "{$dir['path']}/{$name}"; // Keep non formatted path // Get existing image from gallery by filename (Title) @@ -83,7 +83,7 @@ public static function upload(array $args = []) ? (array)Upload::get('file') : []; // Check valid image mime - if ( !self::validateMime($file['name']) ) { + if ( !self::isValidMime($file['name']) ) { return false; } @@ -99,20 +99,17 @@ public static function upload(array $args = []) * * @access public * @param string $file - * @param array $allowed - * @return mixed + * @return bool */ - public static function validateMime(string $file, array $allowed = []) + public static function isValidMime(string $file) : bool { - $allowed = self::mimes(Arrayify::merge([ + return Validator::isValidMime($file, [ 'jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'bmp' => 'image/bmp', 'png' => 'image/png', 'gif' => 'image/gif' - ], $allowed)); - - return self::validate($file, $allowed); + ]); } /** diff --git a/src/inc/Restful.php b/src/inc/Restful.php index 516f4af9..6b267ad1 100644 --- a/src/inc/Restful.php +++ b/src/inc/Restful.php @@ -226,6 +226,18 @@ public static function getHeaders(RestfulRequest $request) : array return $request->get_headers(); } + /** + * Get request header value. + * + * @access public + * @param RestfulRequest $request + * @return mixed + */ + public static function getHeader(RestfulRequest $request, string $key) + { + return $request->get_header($key); + } + /** * Get request method. * diff --git a/src/inc/Server.php b/src/inc/Server.php index 4a02c971..d8c0948b 100644 --- a/src/inc/Server.php +++ b/src/inc/Server.php @@ -123,7 +123,7 @@ public static function getIp(?string $domain = null) } /** - * Get prefered protocol. + * Get protocol. * * @access public * @return string @@ -161,7 +161,7 @@ public static function getCountryCode(array $headers = []) return false; } - + /** * Redirect request. * @@ -173,7 +173,6 @@ public static function getCountryCode(array $headers = []) public static function redirect(string $location, int $status = 301) { wp_redirect($location, $status); - exit(); } /** @@ -357,7 +356,7 @@ public static function getBasicAuthUser() : string } /** - * Get get basic authentication password. + * Get basic authentication password. * * @access public * @return string @@ -381,7 +380,7 @@ public static function getAuthorizationHeaders() } elseif ( self::isSetted('http-authorization') ) { return trim(self::get('http-authorization')); - } elseif ( function_exists('apache_request_headers') ) { + } elseif ( TypeCheck::isFunction('apache-request-headers') ) { $requestHeaders = apache_request_headers(); $requestHeaders = Arrayify::combine( Arrayify::map('ucwords', Arrayify::keys($requestHeaders)), @@ -470,4 +469,19 @@ public static function getReferer() { return wp_get_referer(); } + + /** + * Get server modules. + * + * @access public + * @return array + */ + public static function getModules() : array + { + $modules = []; + if ( TypeCheck::isFunction('apache-get-modules') ) { + $modules = apache_get_modules(); + } + return $modules; + } } diff --git a/src/inc/Session.php b/src/inc/Session.php index a66efa40..cbb05ebf 100644 --- a/src/inc/Session.php +++ b/src/inc/Session.php @@ -23,7 +23,7 @@ final class Session { /** - * Start session. + * Start session if not active. */ public function __construct() { @@ -195,7 +195,7 @@ public static function isActive() : bool } /** - * Close session (Write data). + * Close session (Read-only). * * @access public * @return bool @@ -206,7 +206,7 @@ public static function close() : bool } /** - * End session (Destroy data). + * End session (Destroy). * * @access public * @return bool diff --git a/src/inc/Stringify.php b/src/inc/Stringify.php index 02d48bed..107d9515 100644 --- a/src/inc/Stringify.php +++ b/src/inc/Stringify.php @@ -468,7 +468,7 @@ public static function unShortcode(string $string) : string } /** - * Unserialize value only if it was serialized. + * Unserialize serialized value. * * @access public * @param string $value @@ -492,7 +492,7 @@ public static function serialize($value) } /** - * Check whether value is serialized. + * Check serialized value. * * @access public * @param string $value @@ -635,7 +635,7 @@ public static function sanitizeTextarea(string $string) : string */ public static function sanitizeTitle(string $string, ?string $fallback = null, string $context = 'save') : string { - return sanitize_title($string, $fallback, $context); + return (string)sanitize_title($string, $fallback, $context); } /** @@ -966,12 +966,12 @@ public static function parse(string $string, &$result = []) /** * Parse URL (URL toolkit). - * - * [SCHEME : 0] - * [HOST : 1] - * [PATH : 5] - * [QUERY : 6] - * + * + * [SCHEME: 0] + * [HOST: 1] + * [PATH: 5] + * [QUERY: 6] + * * @access public * @param string $url * @param int $component @@ -1104,7 +1104,6 @@ public static function toInterface(string $string) : string { $i = self::lowercase($string); if ( !self::contains($i, 'interface') ) { - $string = self::capitalize($string); $string = "{$string}Interface"; } return $string; diff --git a/src/inc/System.php b/src/inc/System.php index fdfdaa4e..dab0070a 100644 --- a/src/inc/System.php +++ b/src/inc/System.php @@ -55,8 +55,8 @@ public static function isMemoryOut(float $percent = 0.9) : bool */ public static function getMemoryLimit() : int { - if ( TypeCheck::isFunction('ini_get') ) { - $limit = self::getIni('memory_limit'); + if ( TypeCheck::isFunction('ini-get') ) { + $limit = self::getIni('memory-limit'); if ( Stringify::contains(Stringify::lowercase($limit), 'g') ) { $limit = intval($limit) * 1024; $limit = "{$limit}M"; @@ -250,7 +250,7 @@ public static function setTimeLimit(int $seconds = 30) : bool */ public static function setMemoryLimit($value = '128M') { - return self::setIni('memory_limit', $value); + return self::setIni('memory-limit', $value); } /** @@ -323,11 +323,11 @@ public static function getCpuUsage() : array public static function getCpuCores() : int { $count = 1; // Init with min - if ( !TypeCheck::isFunction('ini_get') ) { + if ( !TypeCheck::isFunction('ini-get') ) { return $count; } - if ( self::getIni('open_basedir') ) { + if ( self::getIni('open-basedir') ) { return $count; } diff --git a/src/inc/Table.php b/src/inc/Table.php index 86c99d9e..590a540c 100644 --- a/src/inc/Table.php +++ b/src/inc/Table.php @@ -18,7 +18,9 @@ require_once Globals::rootDir('wp-admin/includes/class-wp-list-table.php'); } -class Table extends \WP_List_Table +use \WP_List_Table as Core; + +class Table extends Core { /** * @access protected diff --git a/src/inc/Template.php b/src/inc/Template.php index 648a6087..f4b0678d 100644 --- a/src/inc/Template.php +++ b/src/inc/Template.php @@ -27,7 +27,7 @@ final class Template /** * Get view environment. * Used single path for security. - * + * * @access public * @param string $path * @param array $options @@ -40,7 +40,7 @@ public static function getEnvironment(string $path, array $options = []) : Envir /** * Add view callable. - * + * * @access public * @param string $name * @param callable $callable diff --git a/src/inc/Tokenizer.php b/src/inc/Tokenizer.php index ceb01d8b..8b572b53 100644 --- a/src/inc/Tokenizer.php +++ b/src/inc/Tokenizer.php @@ -16,59 +16,9 @@ /** * Built-in tokenizer class. - * JWT for external use is recommended. */ class Tokenizer { - /** - * Get token authentication. - * - * @access public - * @param string $user - * @param string $pswd - * @param string $prefix - * @return array - */ - public static function get(string $user, string $pswd, ?string $prefix = null) : array - { - $secret = self::getUniqueId(); - $token = trim("{user:{$user}}{pswd:{$pswd}}"); - - $encryption = new Encryption($token, $secret); - $encryption->setPrefix((string)$prefix); - - return [ - 'token' => $encryption->encrypt(), - 'secret' => $secret - ]; - } - - /** - * Match token authentication. - * - * @access public - * @param string $token - * @param string $secret - * @param string $prefix - * @return mixed - */ - public static function match(string $token, string $secret, ?string $prefix = null) - { - $pattern = '/{user:(.*?)}{pswd:(.*?)}/'; - $cryptor = new Encryption($token, $secret); - $cryptor->setPrefix((string)$prefix); - - $access = $cryptor->decrypt(); - $user = Stringify::match($pattern, $access, 1); - $pswd = Stringify::match($pattern, $access, 2); - - if ( $user && $pswd ) { - return ['user' => $user, 'pswd' => $pswd]; - } - - return false; - } - /** * Get range of numbers. * @@ -99,7 +49,7 @@ public static function range(int $min = 5, int $max = 10) : int } /** - * Generate token. + * Generate random token. * * @access public * @param int $length @@ -161,13 +111,13 @@ public static function unbase64(string $value, int $loop = 1) : string * Get unique Id. * * @access public + * @param bool $md5 * @return string */ - public static function getUniqueId() : string + public static function getUniqueId(bool $md5 = true) : string { - return md5( - uniqid((string)time()) - ); + $id = uniqid((string)time()); + return ($md5) ? md5($id) : $id; } /** @@ -185,6 +135,7 @@ public static function getUuid(bool $format = false) : string } return $uuid; } + /** * Create nonce. * @@ -234,7 +185,7 @@ public static function checkAjaxNonce($action = -1, $arg = 'nonce') : bool public static function hash($data, string $salt = 'Y3biC') : string { if ( !TypeCheck::isString($data) ) { - $data = String::serialize($data); + $data = Stringify::serialize($data); } $data = "{$salt}{$data}"; return hash('sha256', $data); diff --git a/src/inc/TypeCheck.php b/src/inc/TypeCheck.php index 1b7fa419..e0256e35 100644 --- a/src/inc/TypeCheck.php +++ b/src/inc/TypeCheck.php @@ -341,20 +341,25 @@ public static function isStream(string $path) : bool * * @access public * @param string $type - * @param string $value + * @param mixed $value * @return mixed * @internal */ - public static function isDynamicType(string $type, ?string $value = null) + public static function isDynamicType(string $type, $value = null) { + if ( !self::isString($value) ) { + return false; + } + $pattern = sprintf('/^%s\|(.+)$/', $type); - if ( ($match = Stringify::match($pattern, (string)$value, -1)) ) { + if ( ($match = Stringify::match($pattern, $value, -1)) ) { $match = $match[1] ?? 'NaN'; if ( $type == 'bool' && $match == '0' ) { $match = 'NaN'; } return $match; } + return false; } } diff --git a/src/inc/Upload.php b/src/inc/Upload.php index ef663a7e..813ed445 100644 --- a/src/inc/Upload.php +++ b/src/inc/Upload.php @@ -18,7 +18,7 @@ final class Upload { /** * Get _FILES value. - * + * * @access public * @param string $key * @return mixed @@ -33,7 +33,7 @@ public static function get(?string $key = null) /** * Set _FILES value. - * + * * @access public * @param string $key * @param mixed $value @@ -43,10 +43,10 @@ public static function set(string $key, $value = null) { $_FILES[$key] = $value; } - + /** * Check _FILES value. - * + * * @access public * @param string $key * @return bool @@ -61,7 +61,7 @@ public static function isSetted(?string $key = null) : bool /** * Unset _FILES value. - * + * * @access public * @param string $key * @return void @@ -77,58 +77,162 @@ public static function unset(?string $key = null) } /** - * Move uploaded file. - * + * Move uploaded files. + * * @access public - * @param string $temp - * @param string $path + * @param string $from + * @param string $to * @return bool */ - public static function moveUploadedFile(string $temp, string $path) : bool + public static function move(string $from, string $to) : bool { - return move_uploaded_file($temp, $path); + $to = Stringify::formatPath($to); + return move_uploaded_file($from, $to); + } + + /** + * Sanitize uploaded files. + * + * @access public + * @param array $files, $_FILES + * @param array $types, Mime types + * @return array + */ + public static function sanitize(array $files, ?array $types = []) : array + { + $data = []; + $types = self::getMimes($types); + + foreach ($files as $file) { + + if ( $file['error'] ) { + continue; + } + + $name = $file['name']; + if ( !($ext = File::getExtension($name)) ) { + continue; + } + + $temp = $file['tmp_name']; + $type = File::getMimeType($temp, $ext, $types); + if ( $type == 'undefined' ) { + continue; + } + + if ( !Validator::isValidMime($name, $types) ) { + continue; + } + + $rand = Tokenizer::getUniqueId(false); + $name = Stringify::remove(".{$ext}", $name); + $name = Stringify::slugify("{$name}"); + $path = "{$name}.{$ext}"; + $path = (substr($path, 0, 1) !== '.') ? "{$rand}-{$path}" : "{$rand}{$path}"; + + $key = (!empty($name)) ? $name : $ext; + $data[$key] = [ + 'path' => $path, + 'temp' => $temp + ]; + + } + + return $data; } /** * Handle uploaded file. - * + * * @access public - * @param array $file, $_FILES - * @param array $args, Override default args + * @param array $file, single $_FILES + * @param array $args, Override * @param string $time - * @return mixed + * @return array */ - public static function handle($file, $args = [], $time = null) + public static function handle(array $file, array $args = [], ?string $time = null) : array { - // Validate global file - if ( !TypeCheck::isArray($file) ) { - return false; - } + $args = (!$args) ? ['test-form' => false] : $args; - // Include upload handler - if ( !TypeCheck::isFunction('wp_handle_upload') ) { + if ( !TypeCheck::isFunction('wp-handle-upload') ) { require_once Globals::rootDir('wp-admin/includes/file.php'); } - // Set defaut handler args - if ( !$args ) { - $args = [ - 'test_form' => false - ]; + return wp_handle_upload($file, Format::undash($args), $time); + } + + /** + * Get upload directory. + * + * @access public + * @param string $sub + * @return string + */ + public static function getDir(?string $sub = null) : string + { + $dir = Globals::upload(); + $path = $dir['basedir'] ?? ''; + if ( $sub ) { + $path .= "/{$sub}"; } + return Stringify::formatPath($path); + } - return wp_handle_upload($file, $args, $time); + /** + * Get upload URL. + * + * @access public + * @param string $sub + * @return string + */ + public static function getUrl(?string $sub = null) : string + { + $dir = Globals::upload(); + $url = $dir['baseurl'] ?? ''; + if ( $sub ) { + $url .= "/{$sub}"; + } + return Stringify::formatPath($url); } /** + * Get upload allowed mime types. + * * @access public - * @param int $time - * @param bool $create - * @param bool $refresh + * @param array $types * @return array */ - public static function dir($time = null, $create = true, $refresh = false) + public static function getMimes(?array $types = []) : array { - return wp_upload_dir($time, $create, $refresh); + $mimes = [ + 'txt' => 'text/plain', + 'csv' => 'text/csv', + 'tsv' => 'text/tab-separated-values', + 'ics' => 'text/calendar', + 'rtx' => 'text/richtext', + 'jpg' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'gif' => 'image/gif', + 'png' => 'image/png', + 'bmp' => 'image/bmp', + 'mp3' => 'audio/mpeg', + 'ogg' => 'audio/ogg', + 'wav' => 'audio/wav', + 'mp4' => 'video/mp4', + 'mpeg' => 'video/mpeg', + 'ogv' => 'video/ogg', + 'zip' => 'application/zip', + 'rar' => 'application/rar', + '7z' => 'application/x-7z-compressed', + 'pdf' => 'application/pdf', + 'doc' => 'application/msword', + 'xls' => 'application/vnd.ms-excel', + 'xla' => 'application/vnd.ms-excel', + 'ppt' => 'application/vnd.ms-powerpoint', + 'mdb' => 'application/vnd.ms-access', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + ]; + return Arrayify::merge($types, $mimes); } } diff --git a/src/inc/User.php b/src/inc/User.php index 80fdc3f2..f8a1b376 100644 --- a/src/inc/User.php +++ b/src/inc/User.php @@ -172,6 +172,19 @@ public static function getByEmail(string $email, bool $format = true) return self::getBy('email', $email, $format); } + /** + * Get user by login. + * + * @access public + * @param string $login + * @param bool $format + * @return mixed + */ + public static function getByLogin(string $login, bool $format = true) + { + return self::getBy('login', $login, $format); + } + /** * Get users by meta. * @@ -587,7 +600,7 @@ public static function getRole(string $role) } /** - * Add role(s) to user. + * Add role. * * @access public * @param string $display @@ -595,7 +608,7 @@ public static function getRole(string $role) * @param array $cap * @return mixed */ - public static function addRole(string $display, string $role = null, array $cap = []) + public static function addRole(string $display, ?string $role = null, array $cap = []) { $role = ($role) ? (string)$role : $display; $role = Stringify::undash( diff --git a/src/inc/Validator.php b/src/inc/Validator.php index 60b3ec8d..62474da5 100644 --- a/src/inc/Validator.php +++ b/src/inc/Validator.php @@ -87,20 +87,17 @@ public static function isValidIp(string $ip) : bool } /** - * Validate mime type. + * Validate file mime type. * * @access public - * @param string $filename - * @param array $mimes + * @param string $file + * @param array $types * @return bool */ - public static function isValidMime(string $filename, ?array $mimes = null) : bool + public static function isValidMime(string $file, ?array $types = null) : bool { - $data = wp_check_filetype($filename, $mimes); - if ( $data['ext'] && $data['type'] ) { - return true; - } - return false; + $data = wp_check_filetype($file, $types); + return ($data['ext'] && $data['type']); } /** @@ -122,12 +119,25 @@ public static function isValidMac(string $address) : bool * Validate PHP module. * * @access public - * @param string $extension + * @param string $ext + * @return bool + */ + public static function isModule(string $module) : bool + { + return extension_loaded($module); + } + + /** + * Validate server module. + * + * @access public + * @param string $module * @return bool */ - public static function isModule(string $extension) : bool + public static function isServerModule(string $module) : bool { - return extension_loaded($extension); + $module = Stringify::undash($module); + return Arrayify::inArray($module, Server::getModules()); } /** @@ -158,7 +168,7 @@ public static function isVersion(string $v1, string $v2, string $operator = '==' } /** - * Validate plugin file, + * Validate plugin file. * [{pluginDir}/{pluginMain}.php]. * * @access public diff --git a/src/int/AdminHelperInterface.php b/src/int/AdminHelperInterface.php index ff86d2cb..d03d79ba 100644 --- a/src/int/AdminHelperInterface.php +++ b/src/int/AdminHelperInterface.php @@ -17,12 +17,12 @@ interface AdminHelperInterface { /** - * Init admin helper. + * Trigger admin helper hooks. */ function __construct(); /** - * Plugin activate action. + * Plugin activate. * [Action: {plugin}-activate]. * * @return void @@ -30,7 +30,7 @@ function __construct(); function activate(); /** - * Plugin deactivate action. + * Plugin deactivate. * [Action: {plugin}-deactivate]. * * @return void @@ -38,7 +38,7 @@ function activate(); function deactivate(); /** - * Plugin upgrade action. + * Plugin upgrade. * [Action: {plugin}-upgrade]. * * @return void @@ -46,7 +46,7 @@ function deactivate(); function upgrade(); /** - * Plugin load action. + * Plugin admin load. * [Action: {plugin}-load]. * * @return void @@ -54,13 +54,45 @@ function upgrade(); function load(); /** - * Plugin admin loaded action. - * [Action: {plugin}-admin-loaded]. + * Plugin admin scripts. + * [Action: {plugin}-admin-script]. + * + * @return void + */ + function adminScript(); + + /** + * Plugin global scripts. + * [Action: {plugin}-global-script]. + * + * @return void + */ + function globalScript(); + + /** + * Admin loaded (Core, Plugins, Themes). + * [Action: loaded]. * * @return void */ function loaded(); + /** + * Admin init. + * [Action: admin-init]. + * + * @return void + */ + function init(); + + /** + * Admin dashboard. + * [Action: dashboard-setup]. + * + * @return void + */ + function dashboard(); + /** * Plugin action links. * [Filter: {plugin}-action]. @@ -72,7 +104,7 @@ function action(array $links) : array; /** * Plugin about. - * [Filter: {plugin}-about]. + * [Filter: {plugin}-about-text]. * * @param string $output * @return string @@ -81,7 +113,7 @@ function about(string $output) : string; /** * Plugin version. - * [Filter: {plugin}-version]. + * [Filter: {plugin}-about-version]. * * @param string $output * @return string @@ -117,28 +149,13 @@ function adminData(array $data) : array; function globalData(array $data) : array; /** - * Plugin init action. - * [Action: admin-init]. - * - * @return void - */ - function init(); - - /** - * Plugin dashboard action. - * [Action: dashboard-setup]. - * - * @return void - */ - function dashboard(); - - /** - * Disable plugin auto-update. + * Plugin auto-update. * [Filter: auto-update-plugin]. + * [Filter: {plugin}-disable-auto-update]. * * @param mixed $update * @param object $item * @return mixed */ - function disableAutoUpdate($update, object $item); + function autoUpdate($update, object $item); } diff --git a/src/int/AdminInterface.php b/src/int/AdminInterface.php index 75291b4e..2568b97c 100644 --- a/src/int/AdminInterface.php +++ b/src/int/AdminInterface.php @@ -19,19 +19,24 @@ interface AdminInterface /** * Setup plugin admin. * [Action: plugins-loaded]. + * [Filter: {plugin}-load-menu]. + * [Filter: {plugin}-load-admin]. + * [Uses: isAdmin()]. * * @param MenuInterface $menu * @param SettingsInterface $settings - * @uses isAdmin() + * @uses */ function __construct(?MenuInterface $menu = null, ?SettingsInterface $settings = null); /** * Init plugin admin. - * [Action: plugins-loaded]. + * [Action: admin-init]. + * [Action: {plugin}-admin-loaded]. + * [Filter: {plugin}-load-ajax]. + * [Filter: {plugin}-requirements]. * * @return void - * @uses isPluginAdmin() */ function init(); @@ -46,6 +51,8 @@ function initCSS(); /** * Add admin JS. * [Action: admin-enqueue-scripts]. + * [Filter: {plugin}-remove-jquery]. + * [Filter: {plugin}-admin-data]. * * @return void */ @@ -62,6 +69,7 @@ function globalCSS(); /** * Add global admin JS. * [Action: admin-enqueue-scripts]. + * [Filter: {plugin}-global-data]. * * @return void */ @@ -79,6 +87,7 @@ function addClass(string $classes) : string; /** * Display plugin about. * [Filter: admin-footer-text]. + * [Filter: {plugin}-about-text]. * * @return string */ @@ -87,6 +96,7 @@ function about(); /** * Display plugin version. * [Filter: update-footer]. + * [Filter: {plugin}-about-version]. * * @return string */ diff --git a/src/int/AjaxCoreInterface.php b/src/int/AjaxCoreInterface.php deleted file mode 100644 index bfa00eef..00000000 --- a/src/int/AjaxCoreInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @link : https://jakiboy.github.io/VanillePlugin/ - * @license : MIT - * - * This file if a part of VanillePlugin Framework. - */ - -declare(strict_types=1); - -namespace VanillePlugin\int; - -interface AjaxCoreInterface -{ - /** - * Init plugin Ajax. - * - * @param AjaxInterface $callable - */ - function __construct(AjaxInterface $callable); - - /** - * Ajax action callback, - * Uses isAction() to validate action. - * - * @return void - */ - function callback(); - - /** - * Validate Ajax action, - * Accept all HTTP methods. - * - * @param string $action - * @return bool - */ - function isAction(string $action) : bool; -} diff --git a/src/int/AjaxInterface.php b/src/int/AjaxInterface.php index 90140285..5750c94c 100644 --- a/src/int/AjaxInterface.php +++ b/src/int/AjaxInterface.php @@ -14,4 +14,28 @@ namespace VanillePlugin\int; -interface AjaxInterface {} +interface AjaxInterface +{ + /** + * Init Ajax actions. + * [Action: admin-init]. + */ + function __construct(); + + /** + * Register Ajax actions. + * [Action: wp-ajax-nopriv-{plugin}-{action}]. + * [Action: wp-ajax-{plugin}-{action}]. + * + * @return void + */ + function register(); + + /** + * Ajax action callback. + * [Uses: isAction()]. + * + * @return void + */ + function callback(); +} diff --git a/src/int/CallableInterface.php b/src/int/CallableInterface.php index febd6080..08705aab 100644 --- a/src/int/CallableInterface.php +++ b/src/int/CallableInterface.php @@ -17,9 +17,8 @@ interface CallableInterface { /** - * Incude custom callables. - * - * @access public + * Get extended view callables. + * * @return array */ function getCallables() : array; diff --git a/src/int/CronInterface.php b/src/int/CronInterface.php index 1b3e72b4..84d95a56 100644 --- a/src/int/CronInterface.php +++ b/src/int/CronInterface.php @@ -17,56 +17,97 @@ interface CronInterface { /** - * Init schedule, - * Add schedulers actions. + * Init event timestamp. + * + * @param int $timestamp */ - function __construct(); + function __construct(?int $timestamp = null); /** - * Apply schedules, + * Register events. + * [Action: {plugin}-load]. * [Filter: cron-schedules]. * - * @param array $schedules - * @return array + * @return void */ - function apply(array $schedules) : array; + function register(); /** - * Start schedules. + * Run scheduled events. + * [Action: init]. * * @return void */ - function start(); + function run(); /** - * Check scheduled waitlist. + * Remove scheduled events. + * [Action: {plugin}-deactivate]. + * + * @return void + */ + function remove(); + + /** + * Use server cron. + * [Action: {plugin}-load]. + * + * @return void + */ + function useServer(); + + /** + * Check server cron handler. + * [Action: {plugin}-load]. * - * @param string $name * @return bool */ - function next($name); + function isServer() : bool; /** - * Check scheduled waitlist. + * Get next event timestamp. + * + * @param string $name + * @param array $args + * @return int + */ + function next(string $name, array $args = []) : int; + + /** + * Schedule recurring event. * * @param string $interval * @param string $hook - * @return mixed + * @param array $args + * @return bool */ - function schedule(string $interval, string $hook); + function schedule(string $interval, string $hook, array $args = []) : bool; /** - * Clear hooked schedules. + * Schedule event once. * - * @param string $name - * @return mixed + * @param string $hook + * @param array $args + * @return bool */ - function clear(string $name); + function once(string $hook, array $args = []) : bool; /** - * Remove schedules. + * Unschedule scheduled event. * - * @return void + * @param string $hook + * @param array $args + * @return bool */ - function remove(); + function unschedule(string $hook, array $args = []) : bool; + + /** + * Clear schedule event. + * [Action: {plugin}-deactivate]. + * + * @param string $hook + * @param array $args + * @return int + */ + function clear(string $hook, array $args = []) : int; } diff --git a/src/int/FrontHelperInterface.php b/src/int/FrontHelperInterface.php index 88f3d32f..aafe3ded 100644 --- a/src/int/FrontHelperInterface.php +++ b/src/int/FrontHelperInterface.php @@ -17,26 +17,43 @@ interface FrontHelperInterface { /** - * Init front helper. + * Trigger front helper hooks. */ function __construct(); /** - * Apply AMP. - * [Action: amp-css]. + * Plugin front load. + * [Action: {plugin}-load]. * * @return void */ - function amp(); + function load(); /** - * Front loaded. + * Front loaded (Core, Plugins, Themes). * [Action: loaded]. * * @return void */ function loaded(); + /** + * Front setup (Core). + * [Action: setup]. + * + * @return void + */ + function setup(); + + /** + * Front AMP. + * [Action: amp-css]. + * [Action: amp-head]. + * + * @return void + */ + function amp(); + /** * Front head. * [Action: head]. @@ -47,12 +64,21 @@ function head(); /** * Front init. - * [Action: init]. + * [Action: front-init]. * * @return void */ function init(); + /** + * Front template (Redirect). + * [Action: template]. + * [Action: template-redirect]. + * + * @return void + */ + function template(); + /** * Plugin front data (JS). * [Filter: {plugin}-front-data]. diff --git a/src/int/FrontInterface.php b/src/int/FrontInterface.php index 91fb29cd..34246a75 100644 --- a/src/int/FrontInterface.php +++ b/src/int/FrontInterface.php @@ -18,29 +18,31 @@ interface FrontInterface { /** * Setup plugin front. + * [Action: plugins-loaded]. + * [Uses: !isAdmin()]. * * @param ShortcodeInterface $shortcode - * @uses !isAdmin() */ function __construct(?ShortcodeInterface $shortcode = null); /** * Init front. - * [Action: wp]. + * [Action: front-init]. + * [Action: front-init]. + * [Uses: !AMP::isEnabled()]. * * @return void - * @uses !AMP::isActive() */ function init(); /** - * Init login. - * [Action: init]. + * Init amp. + * [Action: setup]. + * [Uses: !AMP::isActive()]. * * @return void - * @uses isLogin() */ - function initLogin(); + function amp(); /** * Add front CSS. @@ -78,18 +80,10 @@ function loginJS(); /** * Add front body class. * [Filter: body-class]. - * - * @param array $classes - * @return array - */ - function addClass(array $classes) : array; - - /** - * Add login body class. * [Filter: login-body-class]. - * + * * @param array $classes * @return array */ - function addLoginClass(array $classes) : array; + function addClass(array $classes) : array; } diff --git a/src/int/GlobalHelperInterface.php b/src/int/GlobalHelperInterface.php new file mode 100644 index 00000000..3f9fff14 --- /dev/null +++ b/src/int/GlobalHelperInterface.php @@ -0,0 +1,47 @@ + + * @link : https://jakiboy.github.io/VanillePlugin/ + * @license : MIT + * + * This file if a part of VanillePlugin Framework. + */ + +declare(strict_types=1); + +namespace VanillePlugin\int; + +interface GlobalHelperInterface +{ + /** + * Trigger global helper hooks. + */ + function __construct(); + + /** + * Plugin global load. + * [Action: {plugin}-load]. + * + * @return void + */ + function load(); + + /** + * Global loaded (Core, Plugins, Themes). + * [Action: loaded]. + * + * @return void + */ + function loaded(); + + /** + * Global init. + * [Action: init]. + * + * @return void + */ + function init(); +} diff --git a/src/int/ModelInterface.php b/src/int/ModelInterface.php index 7a08a251..b3f58ade 100644 --- a/src/int/ModelInterface.php +++ b/src/int/ModelInterface.php @@ -135,6 +135,7 @@ function assign(array $data) : string; * @param string $path * @param mixed $args * @return mixed + * @throws ModelException */ static function instance(string $name, $path = 'db', ...$args); } diff --git a/src/int/NoticeInterface.php b/src/int/NoticeInterface.php index 46dd5724..754b664d 100644 --- a/src/int/NoticeInterface.php +++ b/src/int/NoticeInterface.php @@ -17,10 +17,10 @@ interface NoticeInterface { /** - * Add notice. + * Display notice. * [Action: admin-notices]. * * @param mixed $callable */ - function add($callable); + function display(callable $callable); } diff --git a/src/int/RequestInterface.php b/src/int/RequestInterface.php index 147d3cc6..f845446c 100644 --- a/src/int/RequestInterface.php +++ b/src/int/RequestInterface.php @@ -239,6 +239,7 @@ function filterSSL($args) : array; * @param string $path * @param mixed $args * @return mixed + * @throws RequestException */ static function instance(string $name, $path = 'api', ...$args); } diff --git a/src/int/RestfulInterface.php b/src/int/RestfulInterface.php index e3e1642d..fb6848b1 100644 --- a/src/int/RestfulInterface.php +++ b/src/int/RestfulInterface.php @@ -25,13 +25,21 @@ interface RestfulInterface function __construct(?string $namespace = null, ?string $version = null); /** - * Init REST API. - * [Action: init]. - * [Action: admin-init]. + * Register REST routes. + * [Action: front-init]. * * @return object */ - function init() : self; + function register() : self; + + /** + * Add REST routes. + * [Action: rest-api-init]. + * + * @param object $server + * @return void + */ + function addRoutes($server); /** * Set REST prefix. @@ -45,7 +53,7 @@ function prefix(string $prefix) : self; /** * Disable REST index. - * [Action: init]. + * [Action: front-init]. * [Filter: rest-api-index]. * * @param bool $grant @@ -55,7 +63,7 @@ function noIndex(bool $grant = false) : self; /** * Disable REST endpoints. - * [Action: init]. + * [Action: front-init]. * [Filter: rest-api-endpoint]. * * @param bool $grant @@ -65,7 +73,7 @@ function noRoute(array $except = []) : self; /** * Disable REST JSONP. - * [Action: init]. + * [Action: front-init]. * [Filter: rest-api-jsonp]. * * @return object @@ -74,7 +82,7 @@ function noPadding() : self; /** * Override REST response. - * [Action: init]. + * [Action: front-init]. * [Filter: rest-api-response]. * * @return object @@ -83,7 +91,7 @@ function override() : self; /** * Disable REST. - * [Action: init]. + * [Action: front-init]. * [Filter: rest-api-error]. * * @return void @@ -92,25 +100,16 @@ function disable(); /** * Restrict REST by rules. - * [Action: init]. + * [Action: front-init]. * [Filter: rest-api-error]. * * @param array $rules * @return void */ function restrict(array $rules); - - /** - * Add REST routes. - * [Action: rest-api-init]. - * - * @param $server - * @return void - */ - function addRoutes($server); /** - * Set endpoint action callback. + * Set endpoint default action callback. * * @param object $request * @return mixed @@ -118,7 +117,7 @@ function addRoutes($server); function action($request); /** - * Set endpoint access callback. + * Set endpoint default access callback. * * @param object $request * @return mixed @@ -132,30 +131,12 @@ function access($request); * @return mixed */ function internal($request); - - /** - * Add auth token. - * - * @param int $user - * @param string $token - * @return bool - */ - function addToken(int $user, string $token) : bool; /** - * Update auth token. + * Set REST authentication method. * - * @param int $user - * @param string $token - * @return bool - */ - function updateToken(int $user, string $token) : bool; - - /** - * Delete auth token. - * - * @param int $user - * @return bool + * @param string $auth + * @return void */ - function deleteToken(int $user) : bool; + function setAuthMethod(string $auth); } diff --git a/src/int/SettingsInterface.php b/src/int/SettingsInterface.php index 49d66d0d..fb511a32 100644 --- a/src/int/SettingsInterface.php +++ b/src/int/SettingsInterface.php @@ -29,16 +29,15 @@ interface SettingsInterface function init(); /** - * Set default settings. - * + * Define default settings. * * @return void */ - static function setDefault(); + function define(); /** * Remove plugin settings. - * [Action: uninstall_{plugin}]. + * [Action: uninstall-{plugin}]. * * @return void */ diff --git a/src/int/ShortcodeInterface.php b/src/int/ShortcodeInterface.php index aa39a1e0..5c265be5 100644 --- a/src/int/ShortcodeInterface.php +++ b/src/int/ShortcodeInterface.php @@ -18,7 +18,7 @@ interface ShortcodeInterface { /** * Init shortcode(s). - * [Action: init]. + * [Action: front-init]. * * @return void */ diff --git a/src/int/UpgraderInterface.php b/src/int/UpgraderInterface.php new file mode 100644 index 00000000..eebe9b69 --- /dev/null +++ b/src/int/UpgraderInterface.php @@ -0,0 +1,32 @@ + + * @link : https://jakiboy.github.io/VanillePlugin/ + * @license : MIT + * + * This file if a part of VanillePlugin Framework. + */ + +declare(strict_types=1); + +namespace VanillePlugin\int; + +interface UpgraderInterface +{ + /** + * Disable upgrader notice. + * + * @return object + */ + function silent() : self; + + /** + * Do plugin upgrade. + * + * @return void + */ + function upgrade(); +} diff --git a/src/int/ViewInterface.php b/src/int/ViewInterface.php index 954bb224..563cd7f8 100644 --- a/src/int/ViewInterface.php +++ b/src/int/ViewInterface.php @@ -17,13 +17,13 @@ interface ViewInterface { /** - * Set custom view callables. + * Set extended view callables. * - * @param array $callables + * @param CallableInterface $callable * @return void */ - function setCallables(array $callables = []); - + function setCallables(?CallableInterface $callable = null); + /** * Render view. * diff --git a/src/lib/API.php b/src/lib/API.php index 6d21da0d..d9df1f80 100644 --- a/src/lib/API.php +++ b/src/lib/API.php @@ -14,8 +14,11 @@ namespace VanillePlugin\lib; -use VanillePlugin\inc\Request; +use VanillePlugin\inc\{ + Request, TypeCheck +}; use VanillePlugin\int\RequestInterface; +use VanillePlugin\exc\RequestException; /** * Plugin API helper. @@ -402,7 +405,18 @@ public function error() */ public static function instance(string $name, $path = 'api', ...$args) { - return (new Loader())->i($path, $name, ...$args); + $class = (new Loader())->i($path, $name, ...$args); + + $int = TypeCheck::hasInterface($class, 'RequestInterface'); + $obj = TypeCheck::isObject($class, static::class); + + if ( $int || $obj ) { + return $class; + } + + throw new RequestException( + RequestException::invalidInstance() + ); } /** diff --git a/src/lib/Ajax.php b/src/lib/Ajax.php index 898dd8c7..fbaa9318 100644 --- a/src/lib/Ajax.php +++ b/src/lib/Ajax.php @@ -14,133 +14,130 @@ namespace VanillePlugin\lib; -use VanillePlugin\int\{ - AjaxCoreInterface, AjaxInterface -}; +use VanillePlugin\int\AjaxInterface; /** * Plugin AJAX manager. */ -final class Ajax implements AjaxCoreInterface +class Ajax implements AjaxInterface { use \VanillePlugin\VanillePluginOption; /** * @access private - * @var object $callable * @var array $actions + * @var bool $isAdmin */ - private AjaxInterface $callable; private $actions = []; + private $isAdmin = false; - /** - * @inheritdoc - */ - public function __construct(AjaxInterface $callable) + /** + * @inheritdoc + */ + public final function __construct() { - // Set callable - $this->callable = $callable; + if ( !$this->isAjax() ) { + return; + } - // Init admin actions if ( $this->isAdminCallable() ) { + $this->isAdmin = true; $this->actions = $this->getAdminAjax(); - $this->initAdminActions(); - } - // Init front actions - if ( $this->isFrontCallable() ) { + } elseif ( $this->isFrontCallable() ) { $this->actions = $this->getFrontAjax(); - $this->initFrontActions(); } } - /** - * @inheritdoc - */ - public function callback() + /** + * @inheritdoc + */ + public final function register() { foreach ($this->actions as $action) { + $action = $this->applyNamespace($action); + $this->addAction("wp-ajax-{$action}", [$this, 'callback']); + if ( !$this->isAdmin ) { + $this->addAction("wp-ajax-nopriv-{$action}", [$this, 'callback']); + } + } + } + + /** + * @inheritdoc + */ + public final function callback() + { + foreach ($this->actions as $action) { + if ( $this->isAction($action) ) { $this->verifyToken($action); - if ( $this->isAdminCallable() ) { + if ( $this->isAdmin ) { $this->verifyPermission(); } $action = $this->camelcase($action); - $this->callable->{$action}(); + $this->{$action}(); break; + } } + die(); } /** - * @inheritdoc + * Validate Ajax action. + * [Methods: GET|POST]. + * + * @access protected + * @param string $action + * @return bool */ - public function isAction(string $action) : bool + protected function isAction(string $action) : bool { - if ( $this->hasRequest('action') ) { - if ( $this->getRequest('action') == $this->applyNamespace($action) ) { - return true; - } + $action = $this->applyNamespace($action); + if ( $this->getRequest('action') == $action ) { + return true; } return false; } /** - * Check whether Ajax callable is admin. + * Check request value in payload. * - * @access private - * @return bool + * @access protected + * @param string $item + * @return mixed */ - private function isAdminCallable() : bool + protected function inPayload(string $item) { - return $this->hasObject('interface', $this->callable, 'AdminAjaxInterface'); + if ( !($value = $this->getRequest($item)) ) { + return false; + } + return $value; } /** - * Check whether Ajax callable is front. + * Check whether Ajax callable is admin. * - * @access private + * @access protected * @return bool */ - private function isFrontCallable() : bool + protected function isAdminCallable() : bool { - return $this->hasObject('interface', $this->callable, 'FrontAjaxInterface'); + return $this->hasObject('interface', $this, 'AdminAjax'); } /** - * Init admin actions. - * [Action: wp-ajax-{plugin}-{action}]. - * - * @access private - * @return void - */ - private function initAdminActions() - { - foreach ($this->actions as $action) { - $this->addAction( - "wp-ajax-{$this->applyNamespace($action)}", - [$this, 'callback'] - ); - } - } - - /** - * Init front actions. - * [Action: wp-ajax-nopriv-{plugin}-{action}]. + * Check whether Ajax callable is front. * - * @access private - * @return void + * @access protected + * @return bool */ - private function initFrontActions() + protected function isFrontCallable() : bool { - foreach ($this->actions as $action) { - $this->addAction( - "wp-ajax-nopriv-{$this->applyNamespace($action)}", - [$this, 'callback'] - ); - } + return $this->hasObject('interface', $this, 'FrontAjax'); } } diff --git a/src/lib/Asset.php b/src/lib/Asset.php index a72bc4ef..65c41a57 100644 --- a/src/lib/Asset.php +++ b/src/lib/Asset.php @@ -14,13 +14,14 @@ namespace VanillePlugin\lib; +use VanillePlugin\inc\Request; + /** * Plugin assets manager. */ final class Asset { - use \VanillePlugin\VanillePluginConfig, - \VanillePlugin\tr\TraitRequestable; + use \VanillePlugin\VanillePluginConfig; /** * @access private @@ -49,49 +50,45 @@ final class Asset */ public function __construct(string $dir = self::DIR) { - // Set base dir $this->dir = $this->getAssetPath( $this->basename($dir) ); - - // Set remote assets $this->assets = $this->getRemoteAssets(); - - // Set cdn url $this->cdn = self::CDN; } /** - * Check asset lock. + * Check asset path lock. * * @access public * @return bool */ public function hasAsset() : bool { - return $this->isFile($this->dir . '/' . self::LOCK); + return $this->isFile("{$this->dir}/" . self::LOCK); } /** - * Lock asset. + * Lock asset path. * * @access public * @return bool */ public function lock() : bool { - return $this->writeFile($this->dir . '/' . self::LOCK); + return $this->writeFile("{$this->dir}/" . self::LOCK); } /** - * Unlock asset. + * Unlock asset path. * * @access public * @return bool */ public function unlock() : bool { - return $this->removeFile($this->dir . '/' . self::LOCK); + $file = "{$this->dir}/" . self::LOCK; + return $this->removeFile($file, $this->getRoot()); } /** @@ -121,41 +118,50 @@ public function setCdn(string $url) : self } /** - * Download remote assets. + * Download assets. * * @access public - * @return void - * @todo + * @return bool */ - public function download() + public function download() : bool { - // Allow CDN by default - $cdn = true; + if ( !$this->isAdmin() ) { + return false; + } - // Get from remote + $downloaded = false; + if ( $this->remote ) { - $api = $this->getHttpClient('GET', [ + + $response = Request::do($this->remote, [ 'timeout' => 30, 'redirection' => 1 ]); - $api->send($this->remote); - if ( $api->getStatusCode() == 200 ) { - $archive = "{$this->dir}/{$this->getFileName($this->remote)}"; - if ( $this->writeFile($archive, $api->getBody()) ) { + + if ( Request::getStatusCode($response) == 200 ) { + + $body = Request::getBody($response); + $file = $this->getFileName($this->remote); + $zip = "{$this->dir}/{$file}"; + + if ( $this->writeFile($zip, $body) ) { + $this->reset(); - $this->extract($archive); - if ( $this->check() ) { - $cdn = false; + if ( $this->extract($zip) && $this->check() ) { + $downloaded = true; $this->lock(); } + } } + } - // Get from CDN - if ( $cdn ) { - $this->downloadCdn(); + if ( !$downloaded ) { + return $this->downloadCdn(); } + + return true; } /** @@ -166,25 +172,37 @@ public function download() */ private function downloadCdn() { - $api = $this->getHttpClient('GET', [ - 'timeout' => 10, - 'redirection' => 1 - ]); foreach ($this->assets as $asset => $files) { foreach ($files as $file) { - $filename = "{$this->dir}/{$asset}/{$this->getFileName($file)}"; + + $filename = $this->getFileName($file); + $filename = "{$this->dir}/{$asset}/{$filename}"; + if ( !$this->check($filename) ) { - $api->send("{$this->cdn}/{$file}"); - if ( $api->getStatusCode() == 200 ) { + + $remote = "{$this->cdn}/{$file}"; + $response = Request::do($remote, [ + 'timeout' => 5, + 'redirection' => 2 + ]); + + if ( Request::getStatusCode($response) == 200 ) { + $body = Request::getBody($response); $this->addDir("{$this->dir}/{$asset}"); - $this->writeFile($filename, $api->getBody()); + $this->writeFile($filename, $body); } + } + } } + if ( $this->check() ) { $this->lock(); + return true; } + + return false; } /** @@ -197,7 +215,7 @@ private function downloadCdn() private function extract(string $archive) : bool { if ( $this->uncompressArchive($archive, $this->dir, false) ) { - $this->removeFile("{$this->dir}/assets.zip"); + $this->removeFile("{$this->dir}/assets.zip", $this->getRoot()); return true; } return false; @@ -212,12 +230,10 @@ private function extract(string $archive) : bool */ private function check(?string $path = null) : bool { - // Check for single asset if ( $this->isType('string', $path) && !empty($path) ) { return $this->isFile($path); } - // Check for all assets foreach ($this->get() as $asset => $files) { foreach ($files as $file) { if ( !$this->isFile("{$this->dir}/{$asset}/{$file}") ) { @@ -237,15 +253,10 @@ private function check(?string $path = null) : bool */ private function reset() { - // Secured removing foreach ($this->get() as $asset => $files) { $dir = "{$this->dir}/{$asset}"; - if ( $this->isDir($dir) ) { - if ( $this->hasString($dir, "/{$this->getNameSpace()}/") ) { - $this->clearDir($dir); - $this->removeDir($dir); - } - } + $this->clearDir($dir, $this->getRoot()); + $this->removeDir($dir, $this->getRoot()); } } @@ -256,7 +267,7 @@ private function reset() * @param string $path * @return string */ - private function getFileName($path) + private function getFileName(string $path) : string { return $this->basename($path); } @@ -267,11 +278,11 @@ private function getFileName($path) * @access private * @return array */ - private function get() + private function get() : array { $wrapper = []; foreach ($this->assets as $asset => $files) { - $wrapper[$asset] = $this->mapArray(function($file) { + $wrapper[$asset] = $this->map(function($file) { return $this->getFileName($file); }, $files); } diff --git a/src/lib/Backup.php b/src/lib/Backup.php index 4b9a65d0..3c472547 100644 --- a/src/lib/Backup.php +++ b/src/lib/Backup.php @@ -30,14 +30,6 @@ final class Backup extends Orm private $tables = []; private $options = []; - /** - * Init backup. - */ - public function __construct() - { - parent::__construct(); - } - /** * Set backup tables. * diff --git a/src/lib/Cache.php b/src/lib/Cache.php index f7c714d0..77ec0ea4 100644 --- a/src/lib/Cache.php +++ b/src/lib/Cache.php @@ -17,7 +17,7 @@ /** * Plugin cache manager. */ -final class Cache +class Cache { use \VanillePlugin\VanillePluginOption; @@ -90,9 +90,7 @@ public function purge(bool $force = false) : bool $path[] = $this->getTempPath(); $path[] = $this->getCachePath(); foreach ($path as $path) { - $count += (int)$this->clearDir($path, [ - $this->getNameSpace() - ]); + $count += (int)$this->clearDir($path, $this->getRoot()); } } @@ -126,4 +124,17 @@ public function hasInternalCache() : bool { return $this->isType('class', self::INTERNAL); } + + /** + * Get internal cache. + * + * @access public + * @param string $driver + * @return object + */ + public function getInternalCache(string $driver = 'File') : object + { + $cache = self::INTERNAL; + return new $cache($driver); + } } diff --git a/src/lib/Cron.php b/src/lib/Cron.php index cc56ce75..ed07a1d5 100644 --- a/src/lib/Cron.php +++ b/src/lib/Cron.php @@ -25,178 +25,203 @@ class Cron implements CronInterface /** * @access protected - * @var array $schedules - * @var array $actions + * @var string SERVER, Server constant + */ + protected const SERVER = 'disable-wp-cron'; + + /** + * @access protected + * @var array $schedules, Cron custom schedules + * @var array $events, Cron events + * @var int $timestamp, Cron timestamp */ protected $schedules = []; - protected $actions = []; + protected $events = []; + protected $timestamp; /** * @inheritdoc */ - public function __construct() + public function __construct(?int $timestamp = null) { - foreach ($this->getCron() as $scheduler) { - $this->addSchedulerAction($scheduler); - } + $this->timestamp = $timestamp ?: time(); } /** * @inheritdoc */ - public function apply(array $schedules) : array + public function register() { - foreach ($this->sanitizeSchedules() as $schedule) { - if ( !isset($schedules[$schedule['name']]) ) { - $schedules[$schedule['name']] = [ - 'display' => $schedule['display'], - 'interval' => $schedule['interval'] - ]; - } + $this->addFilter('cron-schedules', function($schedules) { + $custom = $this->sanitizeSchedules( + $this->getSchedules() + ); + return $this->mergeArray($custom, $schedules); + }); + + $events = $this->sanitizeEvents( + $this->getEvents() + ); + + foreach ($events as $event) { + $name = $this->applyNameSpace("do-{$event['name']}"); + $this->addAction($name, $event['callback']); } - return $schedules; + $this->doPluginAction("{$this->getNameSpace()}-cron"); } /** * @inheritdoc */ - public function start() + public function run() { - $this->addFilter('cron-schedules', [$this, 'apply']); + if ( $this->isInstalling() ) { + return; + } + + $events = $this->sanitizeEvents( + $this->getEvents() + ); - foreach ($this->sanitizeActions() as $action) { - $name = $this->applyNameSpace($action['name']); + foreach ($events as $event) { + $name = $this->applyNameSpace("do-{$event['name']}"); if ( !$this->next($name) ) { - $this->schedule($action['schedule'], $name); + $this->schedule($event['schedule'], $name); } - $this->addAction($name, $action['callable']); } } /** * @inheritdoc */ - public function next($name) + public function remove() { - return wp_next_scheduled($name); + $events = $this->sanitizeEvents( + $this->getEvents() + ); + + foreach ($events as $event) { + $name = $this->applyNameSpace("do-{$event['name']}"); + $this->clear($name); + } } /** * @inheritdoc */ - public function schedule(string $interval, string $hook) + public function useServer() { - return wp_schedule_event(time(), $interval, $hook); + $const = $this->undash(static::SERVER, true); + if ( !defined($const) ) { + define($const, true); + } } /** * @inheritdoc */ - public function clear(string $name) + public function isServer() : bool { - $name = $this->applyNameSpace($name); - return wp_clear_scheduled_hook($name); + $const = $this->undash(static::SERVER, true); + return defined($const); } /** * @inheritdoc */ - public function remove() + public function next(string $name, array $args = []) : int { - foreach ($this->getCron() as $scheduler) { - $this->clear($scheduler['name']); - } + return (int)wp_next_scheduled($name, $args); } /** - * Add schedule. - * - * @access protected - * @param array $schedule - * @return void + * @inheritdoc */ - protected function addSchedule(array $schedule = []) + public function schedule(string $interval, string $hook, array $args = []) : bool { - $this->schedules[] = $schedule; + return wp_schedule_event($this->timestamp, $interval, $hook, $args, false); } /** - * Add scheduler action. - * - * @access protected - * @param array $actions - * @return void + * @inheritdoc */ - protected function addSchedulerAction(array $action = []) + public function once(string $hook, array $args = []) : bool { - $this->actions[] = $action; + return wp_schedule_single_event($this->timestamp, $hook, $args, false); } /** - * Sanitize schedulers actions. - * [Filter: {plugin}-schedulers-actions]. + * @inheritdoc + */ + public function unschedule(string $hook, array $args = []) : bool + { + return wp_unschedule_event($this->timestamp, $hook, $args); + } + + /** + * @inheritdoc + */ + public function clear(string $hook, array $args = []) : int + { + return (int)wp_clear_scheduled_hook($hook, $args); + } + + /** + * Sanitize cron event. + * [Filter: {plugin}-cron-events]. * * @access protected + * @param array $events * @return array */ - protected function sanitizeActions() + protected function sanitizeEvents(array $events) : array { - $this->actions = $this->uniqueMultiArray( - $this->applyPluginFilter('schedulers-actions', $this->actions) + $events = $this->uniqueMultiArray( + $this->applyPluginFilter('cron-events', $events) ); - foreach ($this->actions as $key => $action) { - - if ( !isset($action['name']) ) { - unset($this->actions[$key]); - } - - if ( !isset($action['schedule']) ) { - $this->actions[$key]['schedule'] = 'daily'; - } + foreach ($events as $key => $event) { - if ( !isset($action['callable']) && isset($action['name']) ) { + if ( !isset($event['callback']) ) { + $callback = $this->camelcase($event['name']); - $callable = $this->camelcase($action['name']); - if ( $this->hasObject('method', $this, $callable) ) { - $this->actions[$key]['callable'] = [$this, $callable]; + if ( $this->hasObject('method', static::class, $callback) ) { + $events[$key]['callback'] = [$this, $callback]; } else { - unset($this->actions[$key]); + unset($events[$key]); + continue; } - - } else { - unset($this->actions[$key]); } } - return $this->actions; + + return $events; } /** - * Sanitize schedulers, + * Sanitize event schedules. * [Filter: {plugin}-cron-schedules]. * * @access protected + * @param array $schedules * @return array */ - protected function sanitizeSchedules() + protected function sanitizeSchedules(array $schedules) : array { - $this->schedules = $this->uniqueMultiArray( - $this->applyPluginFilter('cron-schedules', $this->schedules) + $schedules = $this->uniqueMultiArray( + (array)$this->applyPluginFilter('cron-schedules', $schedules) ); - foreach ($this->schedules as $key => $schedule) { - if ( !isset($schedule['name']) - || !isset($schedule['display']) - || !isset($schedule['interval']) ) { - unset($this->schedules[$key]); - - } else { - $this->schedules[$key]['interval'] = (int)$schedule['interval']; + foreach ($schedules as $name => $data) { + $display = $data['display'] ?? false; + if ( !$display ) { + $display = $this->capitalize($name); } + $display = $this->translate($display); + $schedules[$name]['display'] = $display; } - return $this->schedules; + return $schedules; } } diff --git a/src/lib/Hasher.php b/src/lib/Hasher.php new file mode 100644 index 00000000..0d51090f --- /dev/null +++ b/src/lib/Hasher.php @@ -0,0 +1,99 @@ + + * @link : https://jakiboy.github.io/VanillePlugin/ + * @license : MIT + * + * This file if a part of VanillePlugin Framework. + */ + +declare(strict_types=1); + +namespace VanillePlugin\lib; + +/** + * Plugin hash manager. + */ +final class Hasher extends Cache +{ + /** + * @access private + */ + private const SECRET = '8Srs'; + private const SALT = 'l3qw'; + private const TTL = 86400; + + /** + * @access private + * @var string $secret, Hash secret + * @var string $salt, Hash salt + * @var int $ttl, Hash TTL + */ + private $secret; + private $salt; + private $ttl; + + public function __construct(string $secret = self::SECRET, string $salt = self::SALT, int $ttl = self::TTL) + { + $this->secret = $secret; + $this->salt = $salt; + $this->ttl = $ttl; + } + + /** + * Hash data. + * + * @access public + * @param mixed $data + * @return mixed + */ + public function hash($data = null) + { + if ( !$this->hasInternalCache() ) { + return $data; + } + + $key = $this->generateHash($data, $this->salt); + $cache = $this->getInternalCache(); + if ( !$cache->has($key) ) { + $data = $this->encrypt($data, $this->secret, 'data:'); + if ( !$cache->set($key, $data, $this->ttl) ) { + return $data; + } + } + + return "hash:{$key}"; + } + + /** + * Unhash data. + * + * @access public + * @param mixed $data + * @return mixed + */ + public function unhash($data = null) + { + if ( !$this->hasInternalCache() ) { + return $data; + } + + if ( $this->hasString((string)$data, 'hash:') ) { + + $key = $this->generateHash($data, $this->salt); + $key = $this->removeString('token:', $data); + + $cache = $this->getInternalCache(); + $temp = $cache->get($key); + + if ( $cache->has($key) ) { + $data = $temp; + } + } + + return $this->decrypt($data, $this->secret, 'data:'); + } +} diff --git a/src/lib/Hook.php b/src/lib/Hook.php index 868d2a68..6704d0d0 100644 --- a/src/lib/Hook.php +++ b/src/lib/Hook.php @@ -23,22 +23,50 @@ final class Hook /** * @access public - * @var string FILTER - * @var string OPTION + * @var string FILTER, Hooks filter name + * @var string OPTION, Hooks option name + * @var string GROUP, Hooks option group + * @var string MAX, Hooks max inputs + * @var array TAGS, Hooks allowed tags + * @var array INPUT, Hooks default inputs args */ - public const FILTER = 'admin-extras'; - public const OPTION = 'extras'; + public const FILTER = 'admin-hooks'; + public const OPTION = 'hooks'; public const GROUP = 'options'; + public const MAX = 10; + public const TAGS = ['input', 'checkbox', 'color', 'button', 'p']; + public const INPUT = [ + 'type' => 'text', + 'tag' => 'input', + 'column' => 3, + 'default' => null, + 'disabled' => false, + 'required' => false, + 'name' => false, + 'title' => false, + 'description' => false, + 'placeholder' => false, + 'class' => false, + 'max' => false, + 'min' => false, + 'step' => false + ]; /** * @access private * @var string $filter * @var string $option * @var string $group + * @var array $types + * @var array $input + * @var string $max */ private $filter; private $option; private $group; + private $tags; + private $input; + private $max; /** * Init hook. @@ -47,81 +75,193 @@ public function __construct(string $filter = self::FILTER, string $option = self { $this->filter = $filter; $this->option = $option; - $this->group = self::GROUP; + $this->group = $this->applyPluginFilter('hooks-group', self::GROUP); + $this->tags = $this->applyPluginFilter('hooks-tags', self::TAGS); + $this->input = $this->applyPluginFilter('hooks-input', self::INPUT); + $this->max = $this->applyPluginFilter('hooks-max', self::MAX); } /** - * Get valid hooks. + * Get filtered hooks. * [Filter: {plugin}-{filter}]. - * + * * @access public * @return mixed */ public function get() { - // Filter settings - if ( $this->hasFilter($this->filter) ) { - - $default = $this->getPluginOption($this->option, 'array', []); - $extras = $this->applyPluginFilter($this->filter, $default); - - // Reset settings - foreach ($extras as $type => $extra) { - foreach ($extra as $key => $value) { - if ( !isset($value['enable']) || $value['enable'] !== true ) { - // Hook removed or not enabled - unset($extras[$type][$key]); - unset($default[$type][$key]); - - } else { - if ( isset($default[$type][$key]['value']) ) { - // Hook registred - $extras[$type][$key]['value'] = $default[$type][$key]['value']; - } - } - } - } - - // Return filtered extras - $this->updateOption($this->option, $default); - return $extras; + if ( $this->hasPluginFilter($this->filter) ) { + $registered = $this->getRegistered(); + $hooks = $this->applyPluginFilter($this->filter, $registered); + return $this->filter($registered, $hooks); } return false; } /** - * Register hooks inside group. + * Get hooks values. * * @access public - * @return void + * @param string $group + * @param string $option + * @return mixed */ - public function register() + public function getValues(?string $group = null, ?string $option = null) { - $this->registerPluginOption($this->group, $this->option); + $values = $this->getRegistered(); + + foreach ($values as $key => $value) { + $values[$key] = $this->map(function($item) { + return $item['value'] ?? null; + }, $value); + } + + if ( $group && isset($values[$group]) ) { + $values = (array)$values[$group]; + if ( $option ) { + return $values[$option] ?? null; + } + } + + return $values; } /** - * Add default hooks if not exists. + * Update hooks values. * * @access public - * @param array $hooks + * @param array $data * @return bool */ - public function add(array $hooks) : bool + public function updateValues(array $data) : bool { + $registered = $this->getRegistered(); + foreach ($data as $group => $inputs) { + foreach ($inputs as $key => $value) { + $registered[$group][$key]['value'] = $value; + } + } + return $this->update($registered); + } + + /** + * Add hooks. + * + * @access public + * @return bool + */ + public function add() : bool + { + $hooks = []; + foreach ($this->getHooks() as $hook) { + $hooks[$hook] = []; + } return $this->addPluginOption($this->option, $hooks); } /** - * Set hooks group. + * Register hooks inside option group. * * @access public - * @param string $group * @return void */ - public function setGroup(string $group = self::GROUP) + public function register() + { + $this->registerPluginOption($this->group, $this->option); + } + + /** + * Filter hooks. + * + * @access private + * @param array $registered + * @param array $hooks + * @return array + */ + private function filter(array $registered, array $hooks) : array + { + foreach ($hooks as $group => $inputs) { + + // Validate group + if ( !$this->inArray($group, $this->getHooks()) ) { + unset($hooks[$group]); + continue; + } + + // Validate group items + if ( count($registered[$group]) == $this->max ) { + continue; + } + + // Validate inputs + foreach ($inputs as $key => $args) { + + if ( !$this->isType('string', $key) ) { + continue; + } + if ( !$this->isType('array', $args) ) { + continue; + } + + // Format hooked input + $hooked = $hooks[$group][$key]; + $hooked = $this->mergeArray($this->input, $hooked); + unset($hooked['value']); + + // Validate tags + if ( !$this->inArray($hooked['tag'], $this->tags)) { + continue; + } + + // Add or update input + if ( !isset($registered[$group][$key]) ) { + $registered[$group][$key] = $hooked; + $this->update($registered); + + } else { + $saved = $registered[$group][$key]; + $temp = $saved['value'] ?? null; + unset($saved['value']); + + if ( $this->diffArray($saved, $hooked) ) { + + $registered[$group][$key] = $hooked; + $this->update($registered); + + if ( $this->isType('null', $temp) ) { + $registered[$group][$key]['value'] = $temp; + } + } + } + + } + + } + + return $registered; + } + + /** + * Get registered hooks. + * + * @access private + * @return array + */ + private function getRegistered() : array + { + return (array)$this->getPluginOption($this->option, []); + } + + /** + * Update hooks. + * + * @access private + * @param array $data + * @return bool + */ + private function update(array $data) : bool { - $this->group = $group; + return $this->updatePluginOption($this->option, $data); } } diff --git a/src/lib/Loader.php b/src/lib/Loader.php index 5b4b8675..af66f85c 100644 --- a/src/lib/Loader.php +++ b/src/lib/Loader.php @@ -68,7 +68,7 @@ public function instance($path, $className, ...$args) } /** - * Instance alias. + * Instance class (Alias). * * @access public * @param string $path @@ -76,7 +76,7 @@ public function instance($path, $className, ...$args) * @param mixed $args * @return mixed */ - public function i($path, $className, ...$args) + public final function i($path, $className, ...$args) { return $this->instance($path, $className, ...$args); } diff --git a/src/lib/Migrate.php b/src/lib/Migrate.php index bbaf5a68..9c937e6c 100644 --- a/src/lib/Migrate.php +++ b/src/lib/Migrate.php @@ -167,10 +167,10 @@ public function option(array $options) : bool * * @access public * @param string $table - * @param mixed $column + * @param string $column * @return mixed */ - public function export(string $table, $column) + public function export(string $table, ?string $column = null) { $file = $this->getTempPath("{$table}.csv"); $res = fopen($file, 'w'); @@ -229,9 +229,8 @@ public function isMigrated() : bool */ public function unlock() : bool { - return $this->removeFile( - $this->getMigratePath(self::LOCK) - ); + $file = $this->getMigratePath(self::LOCK); + return $this->removeFile($file, $this->getRoot()); } /** diff --git a/src/lib/Model.php b/src/lib/Model.php index 3461bc4e..0463fcee 100644 --- a/src/lib/Model.php +++ b/src/lib/Model.php @@ -14,9 +14,9 @@ namespace VanillePlugin\lib; -use VanillePlugin\exc\ModelException; use VanillePlugin\inc\TypeCheck; use VanillePlugin\int\ModelInterface; +use VanillePlugin\exc\ModelException; /** * Plugin table helper. @@ -249,12 +249,17 @@ public static function getCacheKey($key) : string public static function instance(string $name, $path = 'db', ...$args) { $class = (new Loader())->i($path, $name, ...$args); - if ( !TypeCheck::hasInterface($class, 'ModelInterface') ) { - throw new ModelException( - ModelException::invalidInstance() - ); + + $int = TypeCheck::hasInterface($class, 'ModelInterface'); + $obj = TypeCheck::isObject($class, static::class); + + if ( $int || $obj ) { + return $class; } - return $class; + + throw new ModelException( + ModelException::invalidInstance() + ); } /** diff --git a/src/lib/Notice.php b/src/lib/Notice.php index 14da081c..41b134ab 100644 --- a/src/lib/Notice.php +++ b/src/lib/Notice.php @@ -17,15 +17,34 @@ use VanillePlugin\int\NoticeInterface; /** - * Plugin admin notice. + * Plugin notice manager. */ class Notice extends View implements NoticeInterface { /** * @inheritdoc */ - public function add($callable) + public final function display(callable $callable) { $this->addAction('admin-notices', $callable); } + + /** + * @inheritdoc + */ + public function do(string $message, string $type = 'info', array $args = []) + { + $args = $this->mergeArray([ + 'icon' => 'info', + 'class' => 'notice', + 'title' => 'Notice', + 'detail' => false + ], $args); + + $this->render('admin/inc/notice', [ + 'message' => $message, + 'type' => $type, + 'args' => $args + ]); + } } diff --git a/src/lib/Queue.php b/src/lib/Queue.php index 2c1df127..f1a5eca8 100644 --- a/src/lib/Queue.php +++ b/src/lib/Queue.php @@ -21,7 +21,7 @@ class Queue { use \VanillePlugin\VanillePluginConfig, \VanillePlugin\tr\TraitCacheable; - + /** * Add item to queue. * diff --git a/src/lib/Requirement.php b/src/lib/Requirement.php index 2751ed90..73ec31a5 100644 --- a/src/lib/Requirement.php +++ b/src/lib/Requirement.php @@ -20,276 +20,297 @@ class Requirement extends Notice { /** - * @access private - * @var string $tpl - * @var array $strings + * @access protected + * @var array $dependency + * @var array $messages + * @var string $template */ - private $tpl; - private $strings; + protected $dependency; + protected $messages; + protected $template; /** - * Init requirement. - * [Filter: {plugin}-requirement-template]. - * [Filter: {plugin}-requirement-strings]. + * Init requirements. + * [Action: admin-init]. */ public function __construct() { - $this->add([$this, 'requirePath']); - $this->add([$this, 'requirePlugins']); - $this->add([$this, 'requireOptions']); - $this->add([$this, 'requireTemplates']); - $this->add([$this, 'requireModules']); - $this->add([$this, 'php']); - - // Set template - $this->tpl = 'admin/inc/notice/requirement'; - $this->tpl = $this->applyPluginFilter('requirement-template', $this->tpl); - - // Set strings - $this->strings = $this->applyPluginFilter('requirement-strings', [ - 'path' => [ - 'exists' => '%1$s requires path \'%2$s\'' - ], - 'plugin' => [ - 'install' => 'Required, Please install it', - 'activate' => 'Required, Please activate it' - ], - 'option' => [ - 'missing' => 'Option Required', - 'empty' => 'Option Not Defined' - ], - 'template' => [ - 'single' => 'Template Required', - 'multiple' => 'One Of Templates Required' - ], - 'module' => [ - 'required' => 'Required on server, Please activate it', - 'config' => 'Required on server, Please activate it, Otherwise set \'%1$s\' to \'%2$s\'' - ], - 'php' => [ - 'required' => 'Required' - ] - ]); + $data = $this->getRequirements(); + $this->dependency = $data['dependency']; + $this->messages = $data['messages']; + $this->template = $data['template']; + $this->verify(); } - + /** - * @inheritdoc + * Verify requirements. + * + * @access protected + * @return void */ - public function requirePath() + protected function verify() { - // Get required paths - $paths = []; - if ( $this->getCachePath() ) { - $paths[] = $this->getCachePath(); - } - if ( $this->getTempPath() ) { - $paths[] = $this->getTempPath(); - } - if ( $this->getLoggerPath() ) { - $paths[] = $this->getLoggerPath(); + $this->requirePaths(); + $this->requirePlugins(); + $this->requireThemes(); + $this->requireOptions(); + $this->requireModules(); + $this->requirePhp(); + } + + /** + * Verify required paths. + * + * @access protected + * @return void + */ + protected function requirePaths() + { + if ( !($paths = $this->dependency['paths']) ) { + return; } + $paths = $this->uniqueMultiArray($paths); foreach ($paths as $path) { + + $path = $this->getRoot($path); + + if ( !$this->isDir($path) ) { + $message = $this->messages['paths']['missing']; + $message = $this->transVar($message, [$path]); + $this->display(function() use ($message) { + $this->do($message, 'error'); + }); + continue; + } - // Check path - if ( !$this->isDir($path) || !$this->isWritable($path) ) { - - // Try creating path - if ( !$this->addDir($this->formatPath($path)) ) { - - $message = $this->transVar( - $this->strings['path']['exists'], - [ - $this->getPluginName(), - $this->basename($path) - ] - ); - - $notice = '
'; - $notice .= '

'; - $notice .= ' '; - $notice .= ''; - $notice .= $this->trans('Warning') . ' : '; - $notice .= ''; - $notice .= $message; - $notice .= '

'; - $notice .= ''; - $notice .= $path; - $notice .= ''; - $notice .= '
'; - - echo $notice; - } + if ( !$this->isReadable($path) ) { + $message = $this->messages['paths']['readable']; + $message = $this->transVar($message, [$path]); + $this->display(function() use ($message) { + $this->do($message, 'error'); + }); + continue; + } + if ( !$this->isWritable($path) ) { + $message = $this->messages['paths']['writable']; + $message = $this->transVar($message, [$path]); + $this->display(function() use ($message) { + $this->do($message, 'error'); + }); + continue; } } } /** - * @inheritdoc + * Verify required plugins. + * + * @access protected + * @return void */ - public function requirePlugins() + protected function requirePlugins() { - // Check plugins - if ( !($plugins = $this->getConfig()->requirements->plugins) ) { + if ( !($plugins = $this->dependency['plugins']) ) { return; } - // Requires plugins - foreach ($this->uniqueMultiArray($plugins) as $plugin) { + $plugins = $this->uniqueMultiArray($plugins); + foreach ($plugins as $plugin) { - $name = $plugin->name ?? $plugin->slug; - if ( !$this->isInstalled($plugin->slug) ) { - - $this->render($this->tpl, [ - 'item' => $name, - 'notice' => $this->trans($this->strings['plugin']['install']) - ]); + $slug = $plugin['slug'] ?? false; + if ( !$slug ) { + $slug = $this->slugify($plugin['name']); + } - } else { - $callable = $plugin->callable ?? $plugin->slug; - if ( !$this->isActivated($callable) ) { - $this->render($this->tpl, [ - 'item' => $name, - 'notice' => $this->trans($this->strings['plugin']['activate']) - ]); - } + if ( !$this->isInstalled($slug) ) { + $message = $this->messages['plugins']['missing']; + $message = $this->transVar($message, [$plugin['name']]); + $this->display(function() use ($message) { + $this->do($message, 'error'); + }); + continue; } + + $callable = $plugin['callable'] ?? false; + if ( !$callable ) { + $callable = $this->undash( + $this->slugify($plugin['name']) + ); + } + + if ( !$this->isActivated($callable) ) { + $message = $this->messages['plugins']['missing']; + $message = $this->transVar($message, [$plugin['name']]); + $this->display(function() use ($message) { + $this->do($message, 'error'); + }); + continue; + } + } } /** - * @inheritdoc + * Verify required themes. + * + * @access protected + * @return void */ - public function requireOptions() + protected function requireThemes() { - // Check options - if ( !($options = $this->getConfig()->requirements->options) ) { + if ( !($themes = $this->dependency['themes']) ) { return; } - // Requires options - foreach ($this->uniqueMultiArray($options) as $option) { + $themes = $this->uniqueMultiArray($themes); + foreach ($themes as $key => $theme) { + $themes[$theme['slug']] = $theme['name']; + unset($themes[$key]); + } - $name = $option->name ?? $option->slug; - if ( $this->getOption($option->slug) !== $option->value ) { - $this->render($this->tpl, [ - 'item' => $name, - 'notice' => $this->trans($this->strings['option']['missing']) - ]); + $active = $this->getOption('template'); + if ( !$this->inArray($active, $this->arrayKeys($themes)) ) { - } elseif ( empty($this->getOption($option->slug)) ) { - $this->render($this->tpl, [ - 'item' => $name, - 'notice' => $this->trans($this->strings['option']['empty']) - ]); - } + $count = (count($themes) > 1 ) ? 'multiple' : 'single'; + $themes = $this->arrayValues($themes); + $themes = implode(', ', $themes); + + $message = $this->messages['themes'][$count]; + $message = $this->transVar($message, [$themes]); + + $this->display(function() use ($message) { + $this->do($message, 'error'); + }); } } /** - * @inheritdoc + * Verify required options. + * + * @access protected + * @return void */ - public function requireTemplates() + protected function requireOptions() { - // Check templates - if ( !($templates = $this->getConfig()->requirements->templates) ) { + if ( !($options = $this->dependency['options']) ) { return; } - // Requires templates - $slugs = []; - $names = []; - - foreach ($this->uniqueMultiArray($templates) as $template) { - $slugs[] = $template->slug; - $names[] = $template->name ?? $template->slug; - } - - if ( !$this->hasString($slugs, $this->getOption('template')) ) { + $options = $this->uniqueMultiArray($options); + foreach ($options as $option) { - if ( count($slugs) > 1 ) { - // Check for multiple templates - $item = implode(', ',$names); - $notice = $this->trans($this->strings['template']['multiple']); + $slug = $option['slug'] ?? false; + if ( !$slug ) { + $slug = $this->undash( + $this->slugify($option['name']) + ); + } - } else { - // Check for single template - $item = trim(implode('',$names)); - $notice = $this->trans($this->strings['template']['single']); + if ( !$this->isOption($slug) ) { + $message = $this->messages['options']['missing']; + $message = $this->transVar($message, [$option['name']]); + $this->display(function() use ($message) { + $this->do($message, 'error'); + }); + continue; } - $this->render($this->tpl, [ - 'item' => $item, - 'notice' => $notice, - ]); + if ( $this->getOption($slug) !== $option['value'] ) { + $message = $this->messages['options']['invalid']; + $message = $this->transVar($message, [ + $option['name'], $option['value'] + ]); + $this->display(function() use ($message) { + $this->do($message, 'error'); + }); + continue; + } } } /** - * @inheritdoc + * Verify required modules. + * + * @access protected + * @return void */ - public function requireModules() + protected function requireModules() { - // Check modules - if ( !($modules = $this->getConfig()->requirements->modules) ) { + if ( !($modules = $this->dependency['modules']) ) { return; } - // Requires modules - foreach ($this->uniqueMultiArray($modules) as $module) { + $modules = $this->uniqueMultiArray($modules); + foreach ($modules as $module) { - if ( isset($module->override) ) { + $slug = $module['slug'] ?? false; + if ( !$slug ) { + $slug = $this->undash( + $this->slugify($module['name']) + ); + } - // Overrided module check - $name = $module->override->name ?? ''; - $value = $module->override->value ?? ''; + if ( !$this->isModule($slug) && !$this->isServerModule($slug) ) { + + if ( isset($module['override']) ) { + + $option = $module['override']; + $oSlug = $option['slug'] ?? false; + if ( !$oSlug ) { + $oSlug = $this->undash( + $this->slugify($option['name']) + ); + } + + if ( $this->getOption($oSlug) !== $option['value'] ) { + $message = $this->messages['modules']['override']; + $message = $this->transVar($message, [ + $module['name'], $option['name'], $option['value'] + ]); + $this->display(function() use ($message) { + $this->do($message, 'error'); + }); + continue; + } - if ( !$this->isActivated($module->callable) && !$this->isConfig($name,$value) ) { - $notice = $this->transVar( - $this->strings['module']['config'], - [$name, $value] - ); - $this->render($this->tpl, [ - 'item' => $module->name, - 'notice' => $notice - ]); } - } else { - - // Single module check - if ( !$this->isActivated($module->callable) ) { - $this->render($this->tpl, [ - 'item' => $module->name, - 'notice' => $this->trans($this->strings['module']['required']) - ]); - } + $message = $this->messages['modules']['missing']; + $message = $this->transVar($message, [$module['name']]); + $this->display(function() use ($message) { + $this->do($message, 'error'); + }); + continue; + } + } } /** - * @inheritdoc + * Verify required PHP version. + * + * @access protected + * @return void */ - public function php() + protected function requirePhp() { - // Check version - if ( !($version = $this->getConfig()->requirements->php) ) { + if ( !($php = $this->dependency['php']) ) { return; } - if ( $this->isVersion(phpversion(), $version, '<') ) { - $this->render($this->tpl, [ - 'item' => "PHP {$version}", - 'notice' => $this->trans($this->strings['php']['required']) - ]); - }; + if ( $this->isVersion(phpversion(), $php, '<') ) { + $message = $this->messages['php']['version']; + $message = $this->transVar($message, $php); + $this->display(function() use ($message) { + $this->do($message, 'error'); + }); + } } /** @@ -301,17 +322,26 @@ public function php() */ protected function isInstalled(string $slug) : bool { - if ( $this->isFile($this->getPluginDir("/{$slug}/{$slug}.php")) ) { + $file = "{$slug}.php"; + if ( !$this->hasString($slug, '/') ) { + $file = "{$slug}/{$file}"; + } + + if ( $this->isFile($this->getPluginDir($file)) ) { return true; - } elseif ( $this->isFile($this->getPluginDir("/{$slug}.php")) ) { + } elseif ( $this->isFile($this->getPluginDir("{$slug}.php")) ) { + return true; + + } elseif ( $this->isFile($this->getPluginMuDir("{$slug}.php")) ) { return true; } + return false; } /** - * Check whether plugin or PHP module activated. + * Check whether plugin activated. * * @access protected * @param string $callable @@ -319,7 +349,12 @@ protected function isInstalled(string $slug) : bool */ protected function isActivated(string $callable) : bool { - if ( $this->isPlugin("{$callable}/{$callable}.php") ) { + $file = "{$callable}.php"; + if ( !$this->hasString($callable, '/') ) { + $file = "{$callable}/{$file}"; + } + + if ( $this->isPlugin($file) ) { return true; } elseif ( $this->isPluginClass($callable) ) { @@ -330,10 +365,8 @@ protected function isActivated(string $callable) : bool } elseif ( defined($callable) ) { return true; - - } elseif ( $this->isModule($callable) ) { - return true; } + return false; } } diff --git a/src/lib/RestAPI.php b/src/lib/RestAPI.php index c5e5c657..25ce942e 100644 --- a/src/lib/RestAPI.php +++ b/src/lib/RestAPI.php @@ -33,14 +33,10 @@ class RestAPI implements RestfulInterface /** * @access protected * @var string AUTH REST auth method - * @var string TOKEN User token key - * @var string SECRET User secret key * @var string VERSION Default REST version * @var array SETTINGS Default REST settings */ - protected const AUTH = 'token'; - protected const TOKEN = '--token'; - protected const SECRET = '--secret'; + protected const AUTH = 'basic'; protected const VERSION = 'v1'; protected const SETTINGS = [ 'show-in-index' => false @@ -55,6 +51,7 @@ class RestAPI implements RestfulInterface protected $namespace; protected $version; protected $prefix; + protected $auth; /** * @inheritdoc @@ -63,12 +60,13 @@ public function __construct(?string $namespace = null, ?string $version = null) { $this->namespace = $namespace ?: $this->getNameSpace(); $this->version = $version ?: static::VERSION; + $this->auth = static::AUTH; } /** * @inheritdoc */ - public function init() : self + public final function register() : self { $this->namespace = $this->formatPath( "{$this->namespace}/{$this->version}" @@ -77,6 +75,16 @@ public function init() : self return $this; } + /** + * @inheritdoc + */ + public function addRoutes($server) + { + foreach ($this->getRoutes() as $item) { + $this->add($item); + } + } + /** * @inheritdoc */ @@ -217,16 +225,6 @@ public function restrict(array $rules) }, 99); } - /** - * @inheritdoc - */ - public function addRoutes($server) - { - foreach ($this->getRoutes() as $item) { - $this->register($item); - } - } - /** * @inheritdoc */ @@ -258,6 +256,14 @@ public function internal($request) } /** + * @inheritdoc + */ + public function setAuthMethod(string $auth) + { + $this->auth = $auth; + } + + /** * Fetch response body. * * @access public @@ -271,30 +277,6 @@ public function fetch(string $method, string $route, array $atts = []) : string return Restful::fetch($method, $route, $atts); } - /** - * @inheritdoc - */ - public function addToken(int $user, string $token) : bool - { - return (bool)$this->addUserMeta(static::TOKEN, $token, $user); - } - - /** - * @inheritdoc - */ - public function updateToken(int $user, string $token) : bool - { - return (bool)$this->updateUserMeta(static::TOKEN, $token, $user); - } - - /** - * @inheritdoc - */ - public function deleteToken(int $user) : bool - { - return (bool)$this->deleteUserMeta(static::TOKEN, $user); - } - /** * Register route. * @@ -443,6 +425,17 @@ protected function getHeaders($request) : array return Restful::getHeaders($request); } + /** + * Get request header value. + * + * @access protected + * @inheritdoc + */ + protected function getHeader($request, string $key) + { + return Restful::getHeader($request, $key); + } + /** * Get request method. * @@ -499,13 +492,30 @@ protected function isGet($request) : bool } /** - * Register plugin route item. + * Check DELETE method. + * + * @access protected + * @inheritdoc + */ + protected function isDelete($request) : bool + { + if ( $this->getMethod($request) == 'DELETE' ) { + return true; + } + if ( $this->isPost($request) ) { + return ($this->getHeader($request, 'X-Method') == 'DELETE'); + } + return false; + } + + /** + * Add route. * * @access protected * @param array $item * @return void */ - protected function register(array $item) + protected function add(array $item) { // Parse args $route = $item['route']; @@ -534,7 +544,7 @@ protected function register(array $item) $this->registerRoute($this->namespace, $route, $args, $override); } - + /** * Restrict REST by rules. * [ip, user, role, cap]. @@ -634,21 +644,40 @@ protected function restrictByRules(array $rules = []) : bool */ protected function isAuthorized() : bool { - if ( static::AUTH == 'token' ) { + if ( $this->auth == 'token' ) { return $this->doTokenAuth(); } - if ( static::AUTH == 'basic' ) { + if ( $this->auth == 'basic' ) { return $this->doAuth(); } - if ( static::AUTH == 'any' ) { + if ( $this->auth == 'any' ) { return ($this->doAuth() || $this->doTokenAuth()); } return false; } + /** + * Get authentication status. + * + * @access protected + * @return bool + */ + protected function isAuthenticated() : bool + { + if ( $this->getBearerToken() ) { + return true; + } + + if ( $this->isBasicAuth() ) { + return true; + } + + return false; + } + /** * Authenticate using "Bearer" token. * @@ -659,24 +688,12 @@ protected function doTokenAuth() : bool { if ( ($token = $this->getBearerToken()) ) { - // Get user - if ( !($id = $this->getUserByToken($token) ) ) { - return false; - } - - // Get secret - if ( !($secret = $this->getUserSecret($id)) ) { - return false; - } - - // Match token - if ( !($match = $this->matchToken($token, $secret)) ) { - return false; - } + $secret = $this->getPluginSecret(); + $access = $this->getAccess($token, $secret); + $user = (string)$access['user']; + $pswd = (string)$access['pswd']; // Try authentication - $user = $match['user'] ?? false; - $pswd = $match['pswd'] ?? false; $auth = $this->authenticate($user, $pswd); if ( !$this->isError($auth) ) { @@ -712,32 +729,6 @@ protected function doAuth() : bool return false; } - /** - * Get user by token. - * - * @access protected - * @param string $token - * @return mixed - */ - protected function getUserByToken(string $token) - { - $users = $this->getUserByMeta(static::TOKEN, $token); - $user = $this->shiftArray($users); - return ($user) ? (int)$user['id'] : false; - } - - /** - * Get user secret. - * - * @access protected - * @param int $id - * @return mixed - */ - protected function getUserSecret(int $id) - { - return $this->getUserMeta(static::SECRET, $id); - } - /** * Get user Id by auth. * @@ -747,19 +738,28 @@ protected function getUserSecret(int $id) protected function getUserByAuth() : int { $id = 0; - + if ( $this->isBasicAuth() ) { + $login = $this->getBasicAuthUser(); - $user = $this->getUserBy('login', $login); + $user = $this->getUserByLogin($login); + if ( isset($user['id']) ) { $id = (int)$user['id']; } } if ( ($token = $this->getBearerToken()) ) { - $id = (int)$this->getUserByToken($token); + + $secret = $this->getPluginSecret(); + $access = $this->getAccess($token, $secret); + + $email = (string)$access['user']; + $user = $this->getUserByEmail($email); + $id = (int)$user['id']; + } - + return $id; } } diff --git a/src/lib/Rewrite.php b/src/lib/Rewrite.php index 12ccc255..96d366b5 100644 --- a/src/lib/Rewrite.php +++ b/src/lib/Rewrite.php @@ -56,7 +56,7 @@ public function setRules(string $rules) /** * Add rules. - * [Action: init]. + * [Action: front-init]. * * @access public * @param string $regex @@ -71,7 +71,7 @@ public function addRules(string $regex, $query, string $after = 'bottom') /** * Add endpoint. - * [Action: init]. + * [Action: front-init]. * [EP_ALL: 8191]. * * @access public diff --git a/src/lib/Shortcode.php b/src/lib/Shortcode.php index fbcfe145..1bbeff43 100644 --- a/src/lib/Shortcode.php +++ b/src/lib/Shortcode.php @@ -18,13 +18,20 @@ TypeCheck, Shortcode as Core }; use VanillePlugin\int\CallableInterface; +use VanillePlugin\int\ShortcodedInterface; use VanillePlugin\exc\ShortcodeException; /** * Plugin shortcode manager. */ -class Shortcode extends View +abstract class Shortcode extends View { + /** + * @access protected + */ + protected const PATH = 'shortcode'; + protected const TEMPLATE = 'front/shortcode'; + /** * @access protected * @var array $atts @@ -37,8 +44,10 @@ class Shortcode extends View /** * @access private + * @var mixed $name, Shortcode name * @var string $output, Shortcode output */ + private $name; private $output; /** @@ -46,36 +55,48 @@ class Shortcode extends View */ public function __construct(?CallableInterface $callable = null) { - // Set custom view callables - if ( $callable ) { - $this->setCallables( - $callable->getCallables() - ); - } + // Set extended view callables + $this->setCallables($callable); // Init output $this->setOutput(); } /** - * Set shortcode content. - * [Filter: {plugin}-shortcode-nested]. - * [Filter: {plugin}-shortcode-content]. + * Geenrate shortcode output. * * @access public - * @param string $atts + * @return string + */ + abstract public function generate() : string; + + /** + * Set attributes. + * [Filter: {plugin}-shortcode-global]. + * + * @access protected + * @param array $atts * @return void */ - public function setContent(?string $content = null) + protected function setAttributes(array $atts = []) { - unset($this->content); - if ( $content ) { - if ( $this->applyPluginFilter('shortcode-nested', false) ) { - $content = $this->do($content); - } - $content = $this->applyPluginFilter('shortcode-content', $content); + $this->atts = $this->formatAtts($atts); + if ( $this->applyPluginFilter('shortcode-global', false) ) { + $namespace = $this->undash($this->getNameSpace()); + global ${$namespace}; + ${$namespace} = $this->atts; } - $this->content = $this->applyPluginFilter('shortcode-content', $content, $this->atts); + } + + /** + * Set attributes (Alias). + * [Filter: {plugin}-shortcode-global]. + * + * @inheritdoc + */ + public function setAtts(array $atts = []) + { + $this->setAttributes($atts); } /** @@ -92,13 +113,53 @@ public function setTag(?string $tag = null) } /** - * Set shortcode output. + * Set shortcode content. + * [Filter: {plugin}-shortcode-nested]. + * [Filter: {plugin}-shortcode-content]. + * + * @access public + * @param string $content + * @return void + */ + public function setContent(?string $content = null) + { + unset($this->content); + if ( $this->applyPluginFilter('shortcode-nested', false) ) { + $content = $this->do($content); + } + $hook = 'shortcode-content'; + $this->content = $this->applyPluginFilter($hook, $content, $this->atts); + } + + /** + * Instance shortcode. * * @access public + * @param string $name + * @param string $path + * @param mixed $args + * @return mixed + * @throws ShortcodeException + */ + public static function instance(string $name, ?string $path = self::PATH, ...$args) + { + $class = (new Loader())->i($path, $name, ...$args); + if ( !TypeCheck::hasInterface($class, 'ShortcodedInterface') ) { + throw new ShortcodeException( + ShortcodeException::invalidInstance() + ); + } + return $class; + } + + /** + * Set shortcode output. + * + * @access protected * @param string $output * @return void */ - public function setOutput(string $output = '') + protected function setOutput(string $output = '') { unset($this->output); $this->output = $output; @@ -107,233 +168,271 @@ public function setOutput(string $output = '') /** * Add shortcode output. * - * @access public + * @access protected * @param string $output * @return void */ - public function addOutput(string $output) + protected function addOutput(string $output) { $this->output .= $output; } /** - * Get shortcode output. + * Get shortcode current output. * - * @access public + * @access protected * @return string */ - public function getOutput() : string + protected function getCurrentOutput() : string { - return $this->output; + return (string)$this->output; } - + /** - * Geenrate shortcode output. + * Get filtered shortcode output. * - * @access public + * @access protected * @return string */ - public function generate() : string + protected function getOutput() : string { - return "{$this->getNameSpace()}"; + $hook = 'shortcode-output'; + return (string)$this->applyPluginFilter($hook, $this->output, $this->atts); } /** - * Set shortcode atts. - * [Filter: {plugin}-shortcode-global]. + * Get shortcode instance. * - * @access public - * @param array $atts - * @return void + * @access protected + * @param string $name + * @param mixed $args + * @return mixed */ - public function setAtts(array $atts = []) + protected function get(string $name, ...$args) { - $this->atts = $this->formatAtts($atts); - if ( $this->applyPluginFilter('shortcode-global', false) ) { - $namespace = $this->undash($this->getNameSpace()); - global ${$namespace}; - ${$namespace} = $this->atts; - } + $this->name = $name; + $instance = self::instance($name, static::PATH, ...$args); + $this->sanitizeAtts($instance); + return $instance; } /** - * Instance shortcode. + * Get shortcode identifier keyword. * - * @access public - * @param string $name - * @param string $path - * @param mixed $args + * @access protected * @return mixed - * @throws ShortcodeException */ - public static function instance(string $name, $path = 'shortcode', ...$args) + protected function getKeyword() { - $class = (new Loader())->i($path, $name, ...$args); - if ( !TypeCheck::hasInterface($class, 'ShortcodedInterface') ) { - throw new ShortcodeException( - ShortcodeException::invalidInstance() - ); + $keyword = $this->atts[$this->name] ?? null; + if ( $keyword ) { + $this->removeAttr($this->name); } - return $class; + return $keyword; } /** - * Show shortcode error. - * [Filter: {plugin}-shortcode-error]. - * [Filter: {plugin}-shortcode-template]. + * Get shortcode name. * * @access protected - * @param string $error + * @return mixed + */ + protected function getName() + { + return $this->name; + } + + /** + * Get shortcode instance name. + * + * @access protected + * @param ShortcodedInterface $instance * @return string */ - protected function error(string $error) : string + protected function getInstanceName(ShortcodedInterface $instance) : string { - $error = $this->applyPluginFilter('shortcode-error', $error, $this->atts); - if ( $error ) { - $template = $this->applyPluginFilter('shortcode-template', 'front/error'); - return $this->assign($template, [ - 'error' => $error, - 'atts' => $this->filterArray($this->atts) - ]); - } + $class = new \ReflectionClass($instance); + $name = $this->basename($class->getName()); + return $this->slugify($name); } /** - * Get shortcode default atts. + * Sanitize shortcode attributes. * [Filter: {plugin}-shortcode-default-atts]. * * @access protected - * @param string $type - * @return array + * @param ShortcodedInterface $instance + * @return void */ - protected function getDefaults(string $type) : array + protected function sanitizeAtts(ShortcodedInterface $instance) { - $defaults = []; - if ( $this->hasPluginFilter('shortcode-default-atts') ) { - $defaults = $this->applyPluginFilter('shortcode-default-atts', $type, $defaults); - } - return $defaults; + $hook = 'shortcode-default-atts'; + $name = $this->getInstanceName($instance); + + $default = $this->setAttsValues($instance::atts()); + $default = (array)$this->applyPluginFilter($hook, $default, $name); + + $this->atts = $this->getAtts($default, $this->atts, $this->tag); } /** - * Apply object default atts. - * [Filter: {plugin}-shortcode-atts]. + * Add attributes. * * @access protected - * @param string $type + * @param array $atts * @return void */ - protected function applyDefaults(string $type) + protected function addAttributes(array $atts) { - $this->atts = $this->getAtts( - $this->getDefaults($type), - $this->atts, - $this->tag - ); - $this->atts = $this->applyPluginFilter('shortcode-atts', $this->atts); + $this->atts = $this->mergeArray($atts, $this->atts); } /** - * Set attribute. + * Add attributes (Alias). + * + * @inheritdoc + */ + protected function addAtts(array $atts) + { + $this->addAttributes($atts); + } + + /** + * Add single attribute. * * @access protected * @param string $attr * @param mixed $value * @return void */ - protected function setAttribute(string $attr, $value) + protected function addAttribute(string $attr, $value) { $this->atts[$attr] = $value; } /** - * Set attribute (Alias). + * Add single attribute (Alias). + * + * @inheritdoc + */ + protected function addAttr(string $attr, $value) + { + $this->addAttribute($attr, $value); + } + + /** + * Remove single attribute. * * @access protected * @param string $attr - * @param mixed $value * @return void */ - protected function setAttr(string $attr, $value) + protected function removeAttribute(string $attr) { - $this->setAttribute($attr, $value); + unset($this->atts[$attr]); } /** - * Get attribute. + * Remove single attribute (Alias). * - * @access protected - * @param string $attr - * @return mixed + * @inheritdoc */ - protected function getAttribute(string $attr) + protected function removeAttr(string $attr) { - return $this->atts[$attr] ?? null; + $this->removeAttribute($attr); } /** - * Get attribute (Alias). + * Get output attributes. + * [Filter: {plugin}-shortcode-atts]. * * @access protected - * @param string $attr - * @return mixed + * @return array */ - protected function getAttr(string $attr) + protected function getOutputAtts() : array { - return $this->getAttribute($attr); + $hook = 'shortcode-atts'; + return $this->uniqueMultiArray( + (array)$this->applyPluginFilter($hook, $this->atts) + ); } /** - * Assign content to shortcode. + * Get output template. + * [Filter: {plugin}-shortcode-output-template]. * * @access protected + * @return string + */ + protected function getTemplate() : string + { + $hook = 'shortcode-output-template'; + $template = static::TEMPLATE; + $template = "{$template}/{$this->name}"; + return (string)$this->applyPluginFilter($hook, $template, $this->name); + } + + /** + * Get attributes. + * * @inheritdoc */ - protected function do(string $content, bool $ignore = false) : string + protected function getAttributes(array $default = [], array $atts = [], ?string $tag = null) : array { - return Core::do($content, $ignore); + return Core::getAtts($default, $atts, $tag); } /** - * Get shortcode attributes. + * Get attributes (Alias). * - * @access protected * @inheritdoc */ protected function getAtts(array $default = [], array $atts = [], ?string $tag = null) : array { - return Core::getAtts($default, $atts, $tag); + return $this->getAttributes($default, $atts, $tag); } /** - * Check shortcode attribute empty to allow override. - * + * Get single attribute. + * * @access protected - * @param array $atts * @param string $attr - * @return bool + * @return mixed */ - protected function isEmpty(array $atts, string $attr) : bool + protected function getAttribute(string $attr) { - $attr = $this->formatAttrName($attr); - $atts = $this->formatAtts($atts); - if ( isset($atts[$attr]) ) { - if ( $atts[$attr] === '0' || $atts[$attr] === 0 ) { - return false; - } - return empty($atts[$attr]); - } - return false; + return $this->atts[$attr] ?? null; } /** - * Format shortcode attributes. + * Get single attribute (Alias). + * + * @inheritdoc + */ + protected function getAttr(string $attr) + { + return $this->getAttribute($attr); + } + + /** + * Get hashed attributes. + * + * @access protected + * @return mixed + */ + protected function getHash() + { + return (new Hasher())->hash($this->atts); + } + + /** + * Format attributes. * * @access protected * @param array $atts * @return array */ - protected function formatAtts(array $atts) : array + protected function formatAttributes(array $atts) : array { $attributes = []; $atts = $this->formatKeyCase($atts); @@ -347,8 +446,20 @@ protected function formatAtts(array $atts) : array } /** - * Format shortcode attribute name. - * + * Format attributes (Alias). + * + * @access protected + * @param array $atts + * @return array + */ + protected function formatAtts(array $atts) : array + { + return $this->formatAttributes($atts); + } + + /** + * Format single attribute name. + * * @access protected * @param string $attr * @return string @@ -360,6 +471,66 @@ protected function formatAttrName(string $attr) : string ); } + /** + * Show shortcode error. + * [Filter: {plugin}-shortcode-error]. + * [Filter: {plugin}-shortcode-template]. + * + * @access protected + * @param string $error + * @return mixed + */ + protected function error(string $error) + { + $hook = 'shortcode-error'; + $error = $this->applyPluginFilter($hook, $error, $this->atts); + + if ( $error ) { + + $hook = 'shortcode-template'; + $template = static::TEMPLATE; + $template = "{$template}/error"; + $template = $this->applyPluginFilter($hook, $template, 'error'); + + return $this->assign($template, [ + 'error' => $error, + 'atts' => $this->getOutputAtts() + ]); + + } + } + + /** + * Assign content to shortcode. + * + * @inheritdoc + */ + protected function do(string $content, bool $ignore = false) : string + { + return Core::do($content, $ignore); + } + + /** + * Check whether attribute is empty to allow override. + * + * @access protected + * @param array $atts + * @param string $attr + * @return bool + */ + protected function isEmpty(array $atts, string $attr) : bool + { + $attr = $this->formatAttrName($attr); + $atts = $this->formatAtts($atts); + if ( isset($atts[$attr]) ) { + if ( $atts[$attr] === '0' || $atts[$attr] === 0 ) { + return false; + } + return empty($atts[$attr]); + } + return false; + } + /** * Format attribute value separator. * @@ -379,7 +550,7 @@ protected function formatSep(string $value, bool $strip = false) } /** - * Set shortcode attributes default values. + * Set attributes default values. * * @access protected * @param array $atts @@ -395,8 +566,8 @@ protected function setAttsValues(array $atts) : array } /** - * Check shortcode has attribute (Not flag attribut). - * + * Check shortcode has attribute (Not flag). + * * @access protected * @param array $atts * @param string $attr @@ -409,6 +580,16 @@ protected function hasAttribute(array $atts, string $attr) : bool return isset($atts[$attr]) ? true : false; } + /** + * Check shortcode has attribute (Alias). + * + * @inheritdoc + */ + protected function hasAttr(array $atts, string $attr) : bool + { + return $this->hasAttribute($atts, $attr); + } + /** * Check shortcode has flag attribute. * @@ -428,9 +609,9 @@ protected function hasFlag(array $atts, string $attr) : bool } return $this->inArray($attr, $flags); } - + /** - * Get shortcode attribute value. + * Get attribute value. * * @access protected * @param array $atts @@ -469,7 +650,7 @@ protected function getValue(array $atts, string $attr, ?string $type = null) } /** - * Check shortcode attribute value. + * Check attribute value. * * @access protected * @param array $atts @@ -495,7 +676,7 @@ protected function hasValue(array $atts, string $attr, $value) : bool } /** - * Check shortcode attribute disabled. + * Check attribute disabled. * * @access protected * @param array $atts @@ -514,7 +695,7 @@ protected function isDisabled(array $atts, string $attr) : bool } /** - * Check shortcode attribute enabled. + * Check attribute enabled. * * @access protected * @param array $atts diff --git a/src/lib/Updater.php b/src/lib/Updater.php index d9558f67..5e9ca8af 100644 --- a/src/lib/Updater.php +++ b/src/lib/Updater.php @@ -257,7 +257,7 @@ public function clearCache($upgrader, $options) if ( isset($options['plugins']) ) { foreach ($options['plugins'] as $plugin) { if ( $plugin == $this->file ) { - $this->purgePluginTransients(); + $this->removePluginTransients(); $this->purgePluginCache(); break; } diff --git a/src/lib/View.php b/src/lib/View.php index 0a061f84..3a85a5a1 100644 --- a/src/lib/View.php +++ b/src/lib/View.php @@ -14,7 +14,9 @@ namespace VanillePlugin\lib; -use VanillePlugin\int\ViewInterface; +use VanillePlugin\int\{ + ViewInterface, CallableInterface +}; /** * Plugin view controller. @@ -46,12 +48,11 @@ class View implements ViewInterface /** * @inheritdoc */ - public function setCallables(array $callables = []) + public function setCallables(?CallableInterface $callable = null) { - $this->callables = $this->mergeArray( - $this->getDefaultCallables(), - $callables - ); + $default = $this->getDefaultCallables(); + $callables = ($callable) ? $callable->getCallables() : []; + $this->callables = $this->mergeArray($default, $callables); } /** @@ -70,7 +71,7 @@ public function render(string $tpl = 'default', array $content = [], bool $end = */ public function assign(string $tpl = 'default', array $content = []) : string { - // Get View environment + // Get environment $env = $this->getEnvironment($this->getPath($tpl), [ 'cache' => $this->getCachePath(), 'debug' => $this->hasDebug() @@ -91,9 +92,9 @@ public function assign(string $tpl = 'default', array $content = []) : string $view = $env->load("{$tpl}{$this->getViewExtension()}"); return $view->render($content); - } catch (\Exception $e) { + } catch (\Exception | \RuntimeException $e) { if ( $this->hasDebug() ) { - die($e); + die($e->getMessage()); } $this->clearLastError(); } @@ -141,7 +142,10 @@ protected function getDefaultCallables() : array return $this->createToken($action); }, 'translate' => function(?string $string) : string { - return $this->trans($string); + return $this->translate($string); + }, + 'translateVar' => function(string $string, $vars = null) : string { + return $this->translateVar($string, $vars); }, 'unJson' => function(string $value, bool $isArray = false) { return $this->decodeJson($value, $isArray); @@ -211,11 +215,11 @@ protected function getDefaultCallables() : array * Get view path (Overridden), * [Filter: {plugin}-template-path]. * - * @access private + * @access protected * @param string $tpl * @return string */ - private function getPath(string $tpl) : string + protected function getPath(string $tpl) : string { $path = $this->getThemeDir($this->getNameSpace()); $path = $this->applyPluginFilter('template-path', $path); diff --git a/src/tr/TraitAuthenticatable.php b/src/tr/TraitAuthenticatable.php index 05aad321..12894701 100644 --- a/src/tr/TraitAuthenticatable.php +++ b/src/tr/TraitAuthenticatable.php @@ -16,6 +16,9 @@ use VanillePlugin\inc\User; +/** + * Define authentication functions. + */ trait TraitAuthenticatable { use TraitSessionable, @@ -23,157 +26,190 @@ trait TraitAuthenticatable TraitSecurable; /** - * Register user. + * Check whether user exists. * - * @access protected + * @access public * @inheritdoc */ - protected function registerUser(string $email, ?string $pswd = null, ?string $user = null) + public function isUser($user, string $property = 'username') : bool { - return User::register($email, $pswd, $user); + return User::isUser($user, $property); } /** - * Advanced user login. + * Check whether user is logged-in. * - * @access protected + * @access public * @inheritdoc */ - protected function login(string $user, string $pswd, bool $memory = false) : bool + public function isLoggedIn() : bool { - return User::login($user, $pswd, $memory); + return User::isLoggedIn(); } /** - * Authenticate user. + * Validate user password. * - * @access protected + * @access public * @inheritdoc */ - protected function authenticate(string $user, string $pswd) + public function isPassword(string $pswd, string $hash, $id = null) : bool { - return User::authenticate($user, $pswd); + return User::isPassword($pswd, $hash, $id); } /** - * Logout user. + * Get user by Id. * - * @access protected + * @access public * @inheritdoc */ - protected function logout() + public function getUser($id = null) { - User::logout(); + return User::get($id); } /** - * Check whether user exists. + * Get current user Id. * - * @access protected + * @access public * @inheritdoc */ - protected function isUser($user, string $property = 'username') : bool + public function getUserId() : int { - return User::isUser($user, $property); + return User::getId(); } /** - * Check whether user is logged-in. - * - * @access protected + * Get user by field. + * + * @access public * @inheritdoc */ - protected function isLoggedIn() : bool + public function getUserBy(string $key, $value) { - return User::isLoggedIn(); + return User::getBy($key, $value); } /** - * Validate user password. - * - * @access protected + * Get user by Id. + * + * @access public * @inheritdoc */ - protected function isPassword(string $pswd, string $hash, $id = null) : bool + public function getUserById($id = null) { - return User::isPassword($pswd, $hash, $id); + return User::getById($id); } /** - * Send user password. - * - * @access protected + * Get user by login. + * + * @access public * @inheritdoc */ - protected function sendPassword($id = null) : bool + public function getUserByLogin(string $login) { - return User::sendPassword($id); + return User::getByLogin($login); } /** - * Get user by Id. + * Get user by email. + * + * @access public + * @inheritdoc + */ + public function getUserByEmail(string $email) + { + return User::getByEmail($email); + } + + /** + * Get users by meta. + * + * @access public + * @inheritdoc + */ + public function getUserByMeta(string $key, $value) : array + { + return User::getByMeta($key, $value); + } + + /** + * Get user meta. + * + * @access public + * @inheritdoc + */ + public function getUserMeta(string $key, $id = null) + { + return User::getMeta($key, $id); + } + + /** + * Register user. * * @access protected * @inheritdoc */ - protected function getUser($id = null) + protected function registerUser(string $email, ?string $pswd = null, ?string $user = null) { - return User::get($id); + return User::register($email, $pswd, $user); } /** - * Get current user Id. + * Advanced user login. * * @access protected * @inheritdoc */ - protected function getUserId() : int + protected function login(string $user, string $pswd, bool $memory = false) : bool { - return User::getId(); + return User::login($user, $pswd, $memory); } /** - * Get user by field. - * + * Authenticate user. + * * @access protected * @inheritdoc */ - protected function getUserBy(string $key, $value) + protected function authenticate(string $user, string $pswd) { - return User::getBy($key, $value); + return User::authenticate($user, $pswd); } /** - * Get users by meta. - * + * Logout user. + * * @access protected * @inheritdoc */ - protected function getUserByMeta(string $key, $value) : array + protected function logout() { - return User::getByMeta($key, $value); + User::logout(); } /** - * Add user meta. - * + * Send user password. + * * @access protected * @inheritdoc */ - protected function addUserMeta(string $key, $value, $id = null) + protected function sendPassword($id = null) : bool { - return User::addMeta($key, $value, $id); + return User::sendPassword($id); } /** - * Get user meta. + * Add user meta. * * @access protected * @inheritdoc */ - protected function getUserMeta(string $key, $id = null) + protected function addUserMeta(string $key, $value, $id = null) { - return User::getMeta($key, $id); + return User::addMeta($key, $value, $id); } /** diff --git a/src/tr/TraitCacheable.php b/src/tr/TraitCacheable.php index 5f332d3c..efac6c3e 100644 --- a/src/tr/TraitCacheable.php +++ b/src/tr/TraitCacheable.php @@ -19,19 +19,44 @@ }; use VanillePlugin\lib\Orm; +/** + * Define caching functions. + */ trait TraitCacheable { /** * Get cache value. * - * @access protected + * @access public * @inheritdoc */ - protected function getCache(string $key, ?bool &$status = null, ?string $group = null) + public function getCache(string $key, ?bool &$status = null, ?string $group = null) { return Cache::get($key, (string)$group, false, $status); } + /** + * Get transient. + * + * @access public + * @inheritdoc + */ + public function getTransient(string $key) + { + return Transient::get($key); + } + + /** + * Get site transient. + * + * @access public + * @inheritdoc + */ + public function getSiteTransient(string $key) + { + return Transient::getSite($key); + } + /** * Set cache value. * @@ -87,28 +112,6 @@ protected function purgeCache() : bool return Cache::purge(); } - /** - * Get transient. - * - * @access protected - * @inheritdoc - */ - protected function getTransient(string $key) - { - return Transient::get($key); - } - - /** - * Get site transient. - * - * @access protected - * @inheritdoc - */ - protected function getSiteTransient(string $key) - { - return Transient::getSite($key); - } - /** * Set transient. * @@ -154,38 +157,44 @@ protected function deleteSiteTransient(string $key) : bool } /** - * Purge transients, + * Remove transients. * Under namespace. * * @access protected * @param string $namespace * @return bool */ - protected function purgeTransients(string $namespace) : bool + protected function removeTransients(string $namespace) : bool { if ( empty($namespace) ) { return false; } - $db = new Orm(); - $sql = "DELETE FROM {$db->prefix}options WHERE `option_name` LIKE '%_transient_{$namespace}%';"; + + $db = new Orm(); + $sql = "DELETE FROM `{$db->prefix}options` "; + $sql .= "WHERE `option_name` LIKE '%_transient_{$namespace}%';"; + return (bool)$db->execute($sql); } /** - * Purge site transients, + * Remove site transients. * Under namespace. * * @access protected * @param string $namespace * @return bool */ - protected function purgeSiteTransients(string $namespace) : bool + protected function removeSiteTransients(string $namespace) : bool { if ( empty($namespace) ) { return false; } - $db = new Orm(); - $sql = "DELETE FROM {$db->prefix}options WHERE `option_name` LIKE '%_site_transient_{$namespace}%';"; + + $db = new Orm(); + $sql = "DELETE FROM {$db->prefix}options "; + $sql .= "WHERE `option_name` LIKE '%_site_transient_{$namespace}%';"; + return (bool)$db->execute($sql); } } diff --git a/src/tr/TraitConfigurable.php b/src/tr/TraitConfigurable.php index 90f188e0..6d22aee6 100644 --- a/src/tr/TraitConfigurable.php +++ b/src/tr/TraitConfigurable.php @@ -15,214 +15,204 @@ namespace VanillePlugin\tr; use VanillePlugin\inc\{ - Globals, Plugin, Theme + Globals, Page, Plugin, Theme }; use VanillePlugin\lib\Orm; +/** + * Define base configuration. + */ trait TraitConfigurable { - /** - * Register settings. - * - * @access protected - * @param string $group - * @param string $key - * @param array $args - * @return void - */ - protected function registerOption(string $group, string $key, array $args = []) - { - register_setting($group, $key, $args); - } - - /** - * Add option. - * - * @access protected - * @param string $key - * @param mixed $value - * @return bool - */ - protected function addOption(string $key, $value) : bool - { - return add_option($key, $value); - } - /** * Get option. * - * @access protected + * @access public * @param string $key * @param mixed $default * @return mixed */ - protected function getOption(string $key, $default = false) + public function getOption(string $key, $default = false) { return get_option($key, $default); } /** - * Update option. + * Check option exists. * - * @access protected + * @access public * @param string $key - * @param mixed $value * @return bool */ - protected function updateOption(string $key, $value) : bool + public function isOption(string $key) : bool { - return update_option($key, $value); + $value = $this->getOption($key, 'missing-option'); + return ($value !== 'missing-option'); } /** - * Remove option. + * Check whether page is admin. * - * @access protected - * @param string $key - * @return bool + * @access public + * @inheritdoc */ - protected function removeOption(string $key) : bool + public function isAdmin() : bool { - return delete_option($key); + return Page::isAdmin(); } /** - * Remove all namespace options. + * Check whether page is login. * - * @access protected - * @param string $namespace - * @return bool + * @access public + * @inheritdoc */ - protected function removeOptions(string $namespace) : bool + public function isLogin() : bool { - if ( !$namespace ) { - return false; - } - $db = new Orm(); - $sql = "DELETE FROM {$db->prefix}options WHERE `option_name` LIKE '%{$namespace}_%'"; - return (bool)$db->execute($sql); + return Page::isLogin(); } /** - * Get site version. + * Get site debug status. * - * @access protected - * @return string + * @access public + * @inheritdoc */ - protected function getSiteVersion() : string + public function isDebug() : bool { - return Globals::version(); + return Globals::debug(); } - + /** - * Get site debug status. + * Get site installing status. * - * @access protected + * @access public * @inheritdoc */ - protected function isDebug() : bool + public function isInstalling() : bool { - return Globals::debug(); + return Globals::installing(); } /** - * @access protected + * Check whether multisite is enabled. + * + * @access public * @inheritdoc */ - protected function isMultisite() : bool + public function isMultisite() : bool { return Globals::multisite(); } /** - * @access protected + * Check mobile device. + * + * @access public * @inheritdoc */ - protected function isMobile() : bool + public function isMobile() : bool { return Globals::mobile(); } /** - * @access protected + * Check ajax request. + * + * @access public * @inheritdoc */ - protected function isAjax() : bool + public function isAjax() : bool { return Globals::ajax(); } /** - * @access protected + * Check REST API endpoint. + * + * @access public * @inheritdoc */ - protected function isApi() : bool + public function isApi() : bool { return Globals::api(); } /** - * @access protected + * Get site version. + * + * @access public + * @return string + */ + public function getSiteVersion() : string + { + return Globals::version(); + } + + /** + * Get site roles. + * + * @access public * @inheritdoc */ - protected function getSiteRoles() : array + public function getSiteRoles() : array { return Globals::roles(); } /** - * Get admin url. + * Get admin URL. * - * @access protected + * @access public * @inheritdoc */ - protected function getAdminUrl(?string $path = null, string $scheme = 'admin') : string + public function getAdminUrl(?string $path = null, string $scheme = 'admin') : string { return Globals::adminUrl($path, $scheme); } /** - * Get rest url. + * Get REST URL. * - * @access protected + * @access public * @inheritdoc */ - protected function getRestUrl(?string $path = null) : string + public function getRestUrl(?string $path = null) : string { return Globals::restUrl($path); } /** - * Get ajax url. + * Get Ajax URL. * - * @access protected + * @access public * @inheritdoc */ - protected function getAjaxUrl(string $scheme = 'admin') : string + public function getAjaxUrl(string $scheme = 'admin') : string { return Globals::ajaxUrl($scheme); } /** - * Get front url. + * Get front URL. * - * @access protected + * @access public * @param string $path * @param string $scheme * @return string */ - protected function getFrontUrl(?string $path = null, ?string $scheme = null) : string + public function getFrontUrl(?string $path = null, ?string $scheme = null) : string { return Globals::url($path, $scheme); } /** - * Get site base url. + * Get site base URL. * - * @access protected + * @access public * @inheritdoc */ - protected function geSiteUrl(?string $path = null, string $scheme = 'relative') : string + public function geSiteUrl(?string $path = null, string $scheme = 'relative') : string { return Globals::siteUrl($path, $scheme); } @@ -230,58 +220,146 @@ protected function geSiteUrl(?string $path = null, string $scheme = 'relative') /** * Get site domain name. * - * @access protected + * @access public * @inheritdoc */ - protected function geSiteDomain() : string + public function geSiteDomain() : string { return Globals::siteDomain(); } /** - * @access protected + * Get plugin URL. + * + * @access public * @inheritdoc */ - protected function getPluginUrl(string $path) : string + public function getPluginUrl(string $path) : string { return Plugin::getUrl($path); } /** - * @access protected + * Get plugin directory. + * + * @access public * @inheritdoc */ - protected function getPluginDir(string $path) : string + public function getPluginDir(string $path) : string { return Plugin::getDir($path); } + /** + * Get MU plugin directory. + * + * @access public + * @inheritdoc + */ + public function getPluginMuDir(string $path) : string + { + return Plugin::getMuDir($path); + } + /** * Get plugin header using file. * - * @access protected + * @access public * @inheritdoc */ - protected function getPluginHeader(string $file) : array + public function getPluginHeader(string $file) : array { return Plugin::getHeader($file); } /** - * @access protected + * Get active theme URL. + * + * @access public * @inheritdoc */ - protected function getThemeUrl(?string $path = null) : string + public function getThemeUrl(?string $path = null) : string { return Theme::getUrl($path); } /** - * @access protected + * Get active theme URL. + * + * @access public * @inheritdoc */ - protected function getThemeDir(?string $path = null) : string + public function getThemeDir(?string $path = null) : string { return Theme::getDir($path); } + + /** + * Register settings. + * + * @access protected + * @param string $group + * @param string $key + * @param array $args + * @return void + */ + protected function registerOption(string $group, string $key, array $args = []) + { + register_setting($group, $key, $args); + } + + /** + * Add option. + * + * @access protected + * @param string $key + * @param mixed $value + * @return bool + */ + protected function addOption(string $key, $value) : bool + { + return add_option($key, $value); + } + + /** + * Update option. + * + * @access protected + * @param string $key + * @param mixed $value + * @return bool + */ + protected function updateOption(string $key, $value) : bool + { + return update_option($key, $value); + } + + /** + * Remove option. + * + * @access protected + * @param string $key + * @return bool + */ + protected function removeOption(string $key) : bool + { + return delete_option($key); + } + + /** + * Remove all namespace options. + * + * @access protected + * @param string $namespace + * @return bool + */ + protected function removeOptions(string $namespace) : bool + { + if ( !$namespace ) { + return false; + } + $db = new Orm(); + $sql = "DELETE FROM {$db->prefix}options WHERE `option_name` LIKE '%{$namespace}_%'"; + return (bool)$db->execute($sql); + } } diff --git a/src/tr/TraitDatable.php b/src/tr/TraitDatable.php index 042cf968..1f2923c2 100644 --- a/src/tr/TraitDatable.php +++ b/src/tr/TraitDatable.php @@ -16,15 +16,18 @@ use VanillePlugin\inc\Date; +/** + * Define date and time functions. + */ trait TraitDatable { /** * Get date (Default current). * - * @access protected + * @access public * @inheritdoc */ - protected function getDate(string $date = 'now', string $to = Date::FORMAT, bool $isObject = false) + public function getDate(string $date = 'now', string $to = Date::FORMAT, bool $isObject = false) { return Date::get($date, $to, $isObject); } @@ -32,10 +35,10 @@ protected function getDate(string $date = 'now', string $to = Date::FORMAT, bool /** * Get date difference interval. * - * @access protected + * @access public * @inheritdoc */ - protected function getDateDiff($date, $expire, ?string $i = null, string $to = Date::FORMAT) : int + public function getDateDiff($date, $expire, ?string $i = null, string $to = Date::FORMAT) : int { return Date::difference($date, $expire, $i, $to); } @@ -43,10 +46,10 @@ protected function getDateDiff($date, $expire, ?string $i = null, string $to = D /** * Create date object from string. * - * @access protected + * @access public * @inheritdoc */ - protected function createDate(string $date, string $format, string $to = Date::FORMAT) : object + public function createDate(string $date, string $format, string $to = Date::FORMAT) : object { return Date::create($date, $format, $to); } @@ -54,10 +57,10 @@ protected function createDate(string $date, string $format, string $to = Date::F /** * Convert date format. * - * @access protected + * @access public * @inheritdoc */ - protected function convertDate(string $date, string $format, string $to = Date::FORMAT) : string + public function convertDate(string $date, string $format, string $to = Date::FORMAT) : string { return Date::convert($date, $format, $to); } @@ -65,10 +68,10 @@ protected function convertDate(string $date, string $format, string $to = Date:: /** * Convert date to string format. * - * @access protected + * @access public * @inheritdoc */ - protected function dateToString($date, string $to = Date::FORMAT) : string + public function dateToString($date, string $to = Date::FORMAT) : string { return Date::toString($date, $to); } @@ -76,10 +79,10 @@ protected function dateToString($date, string $to = Date::FORMAT) : string /** * Get current time. * - * @access protected + * @access public * @inheritdoc */ - protected function getTimeNow() : int + public function getTimeNow() : int { return Date::timeNow(); } @@ -87,33 +90,33 @@ protected function getTimeNow() : int /** * Generate new time. * - * @access protected + * @access public * @inheritdoc */ - protected function newTime($h = 0, $m = 0, $s = 0, $mt = 0, $d = 0, $y = 0) : int + public function newTime($h = 0, $m = 0, $s = 0, $mt = 0, $d = 0, $y = 0) : int { return Date::newTime($h, $m, $s, $mt, $d, $y); } - /** - * Set default date timezone. + /** + * Get date timezone. * - * @access protected + * @access public * @inheritdoc - */ - protected function setDefaultTimezone(string $timezone) : bool + */ + public function getDefaultTimezone() : string { - return Date::setDefaultTimezone($timezone); + return Date::getDefaultTimezone(); } - /** - * Get date timezone. + /** + * Set default date timezone. * * @access protected * @inheritdoc - */ - protected function getDefaultTimezone() : string + */ + protected function setDefaultTimezone(string $timezone) : bool { - return Date::getDefaultTimezone(); + return Date::setDefaultTimezone($timezone); } } diff --git a/src/tr/TraitDownloadable.php b/src/tr/TraitDownloadable.php index 30d3123d..ffcb19d7 100644 --- a/src/tr/TraitDownloadable.php +++ b/src/tr/TraitDownloadable.php @@ -16,27 +16,30 @@ use VanillePlugin\lib\Asset; +/** + * Define downloading functions. + */ trait TraitDownloadable { /** * Check whether plugin has asset. - * - * @access protected + * + * @access public * @inheritdoc */ - protected function hasAsset() : bool + public function hasAsset() : bool { return (new Asset())->hasAsset(); } /** * Download plugin remote assets. - * + * * @access protected * @inheritdoc */ protected function download(string $url) { - (new Asset())->setRemote($url)->download(); + return (new Asset())->setRemote($url)->download(); } } diff --git a/src/tr/TraitFormattable.php b/src/tr/TraitFormattable.php index 8e64c928..79383c08 100644 --- a/src/tr/TraitFormattable.php +++ b/src/tr/TraitFormattable.php @@ -19,18 +19,21 @@ Json, Xml, TypeCheck, Validator }; +/** + * Define formatting functions. + */ trait TraitFormattable { use TraitSerializable, - TraitMapable; + TraitMappable; /** * Format path. * - * @access protected + * @access public * @inheritdoc */ - protected function formatPath(string $path, bool $untrailing = false) : string + public function formatPath(string $path, bool $untrailing = false) : string { return Stringify::formatPath($path, $untrailing); } @@ -38,10 +41,10 @@ protected function formatPath(string $path, bool $untrailing = false) : string /** * Format key. * - * @access protected + * @access public * @inheritdoc */ - protected function formatKey(string $key) : string + public function formatKey(string $key) : string { return Stringify::formatKey($key); } @@ -49,10 +52,10 @@ protected function formatKey(string $key) : string /** * Format whitespaces. * - * @access protected + * @access public * @inheritdoc */ - protected function formatSpace(string $string) : string + public function formatSpace(string $string) : string { return Stringify::formatSpace($string); } @@ -60,10 +63,10 @@ protected function formatSpace(string $string) : string /** * Strip spaces in string. * - * @access protected + * @access public * @inheritdoc */ - protected function stripSpace(string $string) : string + public function stripSpace(string $string) : string { return Stringify::stripSpace($string); } @@ -71,10 +74,10 @@ protected function stripSpace(string $string) : string /** * Lowercase string. * - * @access protected + * @access public * @inheritdoc */ - protected function lowercase(string $string) : string + public function lowercase(string $string) : string { return Stringify::lowercase($string); } @@ -82,10 +85,10 @@ protected function lowercase(string $string) : string /** * Uppercase string. * - * @access protected + * @access public * @inheritdoc */ - protected function uppercase(string $string) : string + public function uppercase(string $string) : string { return Stringify::uppercase($string); } @@ -93,10 +96,10 @@ protected function uppercase(string $string) : string /** * Capitalize string. * - * @access protected + * @access public * @inheritdoc */ - protected function capitalize(string $string) : string + public function capitalize(string $string) : string { return Stringify::capitalize($string); } @@ -104,10 +107,10 @@ protected function capitalize(string $string) : string /** * Camelcase string. * - * @access protected + * @access public * @inheritdoc */ - protected function camelcase(string $string) : string + public function camelcase(string $string) : string { return Stringify::camelcase($string); } @@ -115,10 +118,10 @@ protected function camelcase(string $string) : string /** * Slugify string. * - * @access protected + * @access public * @inheritdoc */ - protected function slugify(string $string) : string + public function slugify(string $string) : string { return Stringify::slugify($string); } @@ -126,10 +129,10 @@ protected function slugify(string $string) : string /** * Format dash (hyphen) into underscore. * - * @access protected + * @access public * @inheritdoc */ - protected function undash(string $string, bool $isGlobal = false) : string + public function undash(string $string, bool $isGlobal = false) : string { return Stringify::undash($string, $isGlobal); } @@ -140,7 +143,7 @@ protected function undash(string $string, bool $isGlobal = false) : string * @param mixed $value * @return mixed */ - protected function unSlash($value) + public function unSlash($value) { return Stringify::unSlash($value); } @@ -148,10 +151,10 @@ protected function unSlash($value) /** * Strip slashes in quotes or single quotes. * - * @access protected + * @access public * @inheritdoc */ - protected function stripSlash($value) + public function stripSlash($value) { return Stringify::deepStripSlash($value); } @@ -159,10 +162,10 @@ protected function stripSlash($value) /** * Add slashes to value. * - * @access protected + * @access public * @inheritdoc */ - protected function slash($value) + public function slash($value) { return Stringify::slash($value); } @@ -170,10 +173,10 @@ protected function slash($value) /** * Remove trailing slashes and backslashes if exist. * - * @access protected + * @access public * @inheritdoc */ - protected function untrailingSlash(string $string) : string + public function untrailingSlash(string $string) : string { return Stringify::untrailingSlash($string); } @@ -181,10 +184,10 @@ protected function untrailingSlash(string $string) : string /** * Append trailing slashes. * - * @access protected + * @access public * @inheritdoc */ - protected function trailingSlash(string $string) : string + public function trailingSlash(string $string) : string { return Stringify::trailingSlash($string); } @@ -192,10 +195,10 @@ protected function trailingSlash(string $string) : string /** * Search string. * - * @access protected + * @access public * @inheritdoc */ - protected function hasString($string, $search) : bool + public function hasString($string, $search) : bool { return Stringify::contains($string, $search); } @@ -203,10 +206,10 @@ protected function hasString($string, $search) : bool /** * Remove string in other string. * - * @access protected + * @access public * @inheritdoc */ - protected function removeString(string $search, string $subject, bool $regex = false) : string + public function removeString(string $search, string $subject, bool $regex = false) : string { if ( $regex ) { return Stringify::removeRegex($search, $subject); @@ -215,13 +218,12 @@ protected function removeString(string $search, string $subject, bool $regex = f } /** - * Search replace string(s), - * Accept regex. + * Search replace string(s). * - * @access protected + * @access public * @inheritdoc */ - protected function replaceString($search, $replace, $subject, bool $regex = false) + public function replaceString($search, $replace, $subject, bool $regex = false) { if ( $regex ) { return Stringify::replaceRegex($search, $replace, $subject); @@ -232,10 +234,10 @@ protected function replaceString($search, $replace, $subject, bool $regex = fals /** * Search replace string(s) using array. * - * @access protected + * @access public * @inheritdoc */ - protected function replaceStringArray(array $replace, string $subject) : string + public function replaceStringArray(array $replace, string $subject) : string { return Stringify::replaceArray($replace, $subject); } @@ -243,10 +245,10 @@ protected function replaceStringArray(array $replace, string $subject) : string /** * Match string using regex. * - * @access protected + * @access public * @inheritdoc */ - protected function matchString(string $regex, string $string, int $index = 0, int $flags = 0, int $offset = 0) + public function matchString(string $regex, string $string, int $index = 0, int $flags = 0, int $offset = 0) { return Stringify::match($regex, $string, $index, $flags, $offset); } @@ -254,10 +256,10 @@ protected function matchString(string $regex, string $string, int $index = 0, in /** * Match all strings using regex (g). * - * @access protected + * @access public * @inheritdoc */ - protected function matchEveryString(string $regex, string $string, int $index = 0, int $flags = 0, int $offset = 0) + public function matchEveryString(string $regex, string $string, int $index = 0, int $flags = 0, int $offset = 0) { return Stringify::matchAll($regex, $string, $index, $flags, $offset); } @@ -265,10 +267,10 @@ protected function matchEveryString(string $regex, string $string, int $index = /** * Parse string. * - * @access protected + * @access public * @inheritdoc */ - protected function parseString(string $string, &$result = []) + public function parseString(string $string, &$result = []) { return Stringify::parse($string, $result); } @@ -276,10 +278,10 @@ protected function parseString(string $string, &$result = []) /** * Limit string. * - * @access protected + * @access public * @inheritdoc */ - protected function limitString(?string $string, int $limit = 150) : string + public function limitString(?string $string, int $limit = 150) : string { return Stringify::limit((string)$string, $limit); } @@ -287,10 +289,10 @@ protected function limitString(?string $string, int $limit = 150) : string /** * Get basename with path format. * - * @access protected + * @access public * @inheritdoc */ - protected function basename(string $path, string $suffix = '') : string + public function basename(string $path, string $suffix = '') : string { return Stringify::basename($path, $suffix); } @@ -298,10 +300,10 @@ protected function basename(string $path, string $suffix = '') : string /** * Get break to line. * - * @access protected + * @access public * @inheritdoc */ - protected function breakString() : string + public function breakString() : string { return Stringify::break(); } @@ -309,10 +311,10 @@ protected function breakString() : string /** * Escape HTML. * - * @access protected + * @access public * @inheritdoc */ - protected function escapeHTML(string $string) : string + public function escapeHTML(string $string) : string { return Stringify::escapeHTML($string); } @@ -320,10 +322,10 @@ protected function escapeHTML(string $string) : string /** * Escape HTML attribute. * - * @access protected + * @access public * @inheritdoc */ - protected function escapeAttr(string $string) : string + public function escapeAttr(string $string) : string { return Stringify::escapeAttr($string); } @@ -331,10 +333,10 @@ protected function escapeAttr(string $string) : string /** * Escape textarea. * - * @access protected + * @access public * @inheritdoc */ - protected function escapeTextarea(string $string) : string + public function escapeTextarea(string $string) : string { return Stringify::escapeTextarea($string); } @@ -342,10 +344,10 @@ protected function escapeTextarea(string $string) : string /** * Escape JS. * - * @access protected + * @access public * @inheritdoc */ - protected function escapeJS(string $string) : string + public function escapeJS(string $string) : string { return Stringify::escapeJS($string); } @@ -353,10 +355,10 @@ protected function escapeJS(string $string) : string /** * Escape SQL. * - * @access protected + * @access public * @inheritdoc */ - protected function escapeSQL(string $string) : string + public function escapeSQL(string $string) : string { return Stringify::escapeSQL($string); } @@ -364,10 +366,10 @@ protected function escapeSQL(string $string) : string /** * Escape Url. * - * @access protected + * @access public * @inheritdoc */ - protected function escapeUrl(string $url) : string + public function escapeUrl(string $url) : string { return Stringify::escapeUrl($url); } @@ -375,10 +377,10 @@ protected function escapeUrl(string $url) : string /** * Sanitize text field. * - * @access protected + * @access public * @inheritdoc */ - protected function sanitizeText(string $string) : string + public function sanitizeText(string $string) : string { return Stringify::sanitizeText($string); } @@ -386,10 +388,10 @@ protected function sanitizeText(string $string) : string /** * Sanitize textarea field. * - * @access protected + * @access public * @inheritdoc */ - protected function sanitizeTextarea(string $string) : string + public function sanitizeTextarea(string $string) : string { return Stringify::sanitizeTextarea($string); } @@ -397,10 +399,10 @@ protected function sanitizeTextarea(string $string) : string /** * Sanitize title. * - * @access protected + * @access public * @inheritdoc */ - protected function sanitizeTitle(string $string) : string + public function sanitizeTitle(string $string) : string { return Stringify::sanitizeTitle($string); } @@ -408,10 +410,10 @@ protected function sanitizeTitle(string $string) : string /** * Sanitize email. * - * @access protected + * @access public * @inheritdoc */ - protected function sanitizeEmail(string $string) : string + public function sanitizeEmail(string $string) : string { return Stringify::sanitizeEmail($string); } @@ -419,10 +421,10 @@ protected function sanitizeEmail(string $string) : string /** * Sanitize option value. * - * @access protected + * @access public * @inheritdoc */ - protected function sanitizeOption(string $key, string $value) : string + public function sanitizeOption(string $key, string $value) : string { return Stringify::sanitizeOption($key, $value); } @@ -430,10 +432,10 @@ protected function sanitizeOption(string $key, string $value) : string /** * Sanitize meta value. * - * @access protected + * @access public * @inheritdoc */ - protected function sanitizeMeta(string $key, string $value) : string + public function sanitizeMeta(string $key, string $value) : string { return Stringify::sanitizeMeta($key, $value); } @@ -441,10 +443,10 @@ protected function sanitizeMeta(string $key, string $value) : string /** * Sanitize username. * - * @access protected + * @access public * @inheritdoc */ - protected function sanitizeUsername(string $key, string $value) : string + public function sanitizeUsername(string $key, string $value) : string { return Stringify::sanitizeUsername($key, $value); } @@ -452,10 +454,10 @@ protected function sanitizeUsername(string $key, string $value) : string /** * Sanitize url. * - * @access protected + * @access public * @inheritdoc */ - protected function sanitizeUrl(string $url) : string + public function sanitizeUrl(string $url) : string { return Stringify::sanitizeUrl($url); } @@ -463,10 +465,10 @@ protected function sanitizeUrl(string $url) : string /** * Sanitize HTML content (XSS). * - * @access protected + * @access public * @inheritdoc */ - protected function sanitizeHTML(string $string) : string + public function sanitizeHTML(string $string) : string { return Stringify::sanitizeHTML($string); } @@ -474,10 +476,10 @@ protected function sanitizeHTML(string $string) : string /** * Check array item. * - * @access protected + * @access public * @inheritdoc */ - protected function inArray($value, array $array) : bool + public function inArray($value, array $array) : bool { return Arrayify::inArray($value, $array); } @@ -485,10 +487,10 @@ protected function inArray($value, array $array) : bool /** * Merge arrays. * - * @access protected + * @access public * @inheritdoc */ - protected function mergeArray(array $array, array $arrays) : array + public function mergeArray(array $array, array $arrays) : array { return Arrayify::merge($array, $arrays); } @@ -496,10 +498,10 @@ protected function mergeArray(array $array, array $arrays) : array /** * Filter array. * - * @access protected + * @access public * @inheritdoc */ - protected function filterArray(array $array, $callback = null, $mode = 0) : array + public function filterArray(array $array, $callback = null, $mode = 0) : array { return Arrayify::filter($array, $callback, $mode); } @@ -507,10 +509,10 @@ protected function filterArray(array $array, $callback = null, $mode = 0) : arra /** * Check array key. * - * @access protected + * @access public * @inheritdoc */ - protected function hasArrayKey($key, array $array) : bool + public function hasArrayKey($key, array $array) : bool { return Arrayify::hasKey($key, $array); } @@ -518,21 +520,32 @@ protected function hasArrayKey($key, array $array) : bool /** * Get array keys. * - * @access protected + * @access public * @inheritdoc */ - protected function arrayKeys(array $array, $value = null, bool $search = false) : array + public function arrayKeys(array $array, $value = null, bool $search = false) : array { return Arrayify::keys($array, $value, $search); } + /** + * Get single array key. + * + * @access public + * @inheritdoc + */ + public function arrayKey(array $array) + { + return Arrayify::key($array); + } + /** * Get array values. * - * @access protected + * @access public * @inheritdoc */ - protected function arrayValues(array $array) : array + public function arrayValues(array $array) : array { return Arrayify::values($array); } @@ -540,10 +553,10 @@ protected function arrayValues(array $array) : array /** * Shift array. * - * @access protected + * @access public * @inheritdoc */ - protected function shiftArray(array &$array) : array + public function shiftArray(array &$array) : array { return Arrayify::shift($array); } @@ -551,10 +564,10 @@ protected function shiftArray(array &$array) : array /** * Get array diff. * - * @access protected + * @access public * @inheritdoc */ - protected function diffArray(array $array, array $arrays) : array + public function diffArray(array $array, array $arrays) : array { return Arrayify::diff($array, $arrays); } @@ -562,10 +575,10 @@ protected function diffArray(array $array, array $arrays) : array /** * Sort array. * - * @access protected + * @access public * @inheritdoc */ - protected function sortArray(array $array, $orderby = [], $order = 'ASC', bool $preserve = false) + public function sortArray(array $array, $orderby = [], $order = 'ASC', bool $preserve = false) { return Arrayify::sort($array, $orderby, $order, $preserve); } @@ -573,10 +586,10 @@ protected function sortArray(array $array, $orderby = [], $order = 'ASC', bool $ /** * Slice array. * - * @access protected + * @access public * @inheritdoc */ - protected function sliceArray(array $array, int $offset, ?int $length = null, bool $preserve = false) : array + public function sliceArray(array $array, int $offset, ?int $length = null, bool $preserve = false) : array { return Arrayify::slice($array, $offset, $length, $preserve); } @@ -584,10 +597,10 @@ protected function sliceArray(array $array, int $offset, ?int $length = null, bo /** * Unique array. * - * @access protected + * @access public * @inheritdoc */ - protected function uniqueArray(array $array, $flags = SORT_STRING) : array + public function uniqueArray(array $array, $flags = SORT_STRING) : array { return Arrayify::unique($array, $flags); } @@ -595,10 +608,10 @@ protected function uniqueArray(array $array, $flags = SORT_STRING) : array /** * Unique arrays. * - * @access protected + * @access public * @inheritdoc */ - protected function uniqueMultiArray(array $array) : array + public function uniqueMultiArray(array $array) : array { return Arrayify::uniqueMultiple($array); } @@ -606,32 +619,21 @@ protected function uniqueMultiArray(array $array) : array /** * Format array key case. * - * @access protected + * @access public * @inheritdoc */ - protected function formatKeyCase(array $array, int $case = CASE_LOWER) : array + public function formatKeyCase(array $array, int $case = CASE_LOWER) : array { return Arrayify::formatKeyCase($array, $case); } - /** - * Map array. - * - * @access protected - * @inheritdoc - */ - protected function map($callback, array $array, ?array $arrays = null) - { - return Arrayify::map($callback, $array, $arrays); - } - /** * Push array. * - * @access protected + * @access public * @inheritdoc */ - protected function pushArray(array &$array, $values) : int + public function pushArray(array &$array, $values) : int { return Arrayify::push($array, $values); } @@ -639,10 +641,10 @@ protected function pushArray(array &$array, $values) : int /** * Format array. * - * @access protected + * @access public * @inheritdoc */ - protected function formatArray(array $array) : array + public function formatArray(array $array) : array { return Arrayify::format($array); } @@ -650,10 +652,10 @@ protected function formatArray(array $array) : array /** * Decode JSON. * - * @access protected + * @access public * @inheritdoc */ - protected function decodeJson(string $value, bool $isArray = false) + public function decodeJson(string $value, bool $isArray = false) { return Json::decode($value, $isArray); } @@ -661,10 +663,10 @@ protected function decodeJson(string $value, bool $isArray = false) /** * Encode JSON without flags. * - * @access protected + * @access public * @inheritdoc */ - protected function encodeJson($value) + public function encodeJson($value) { return Json::encode($value); } @@ -672,10 +674,10 @@ protected function encodeJson($value) /** * Encode JSON using flags. * - * @access protected + * @access public * @inheritdoc */ - protected function formatJson($value, int $flags = 64|256, int $depth = 512) + public function formatJson($value, int $flags = 64|256, int $depth = 512) { return Json::format($value, $flags, $depth); } @@ -683,10 +685,10 @@ protected function formatJson($value, int $flags = 64|256, int $depth = 512) /** * Parse XML string. * - * @access protected + * @access public * @inheritdoc */ - protected function parseXml(string $xml, int $args = 16384|20908) + public function parseXml(string $xml, int $args = 16384|20908) { return Xml::parse($xml, $args); } @@ -694,21 +696,32 @@ protected function parseXml(string $xml, int $args = 16384|20908) /** * Validate PHP module. * - * @access protected + * @access public * @inheritdoc */ - protected function isModule(string $extension) : bool + public function isModule(string $module) : bool { - return Validator::isModule($extension); + return Validator::isModule($module); + } + + /** + * Validate server module. + * + * @access public + * @inheritdoc + */ + public function isServerModule(string $module) : bool + { + return Validator::isServerModule($module); } /** * Validate server config. * - * @access protected + * @access public * @inheritdoc */ - protected function isConfig(string $name, $value) : bool + public function isConfig(string $name, $value) : bool { return Validator::isConfig($name, $value); } @@ -716,10 +729,10 @@ protected function isConfig(string $name, $value) : bool /** * Validate version. * - * @access protected + * @access public * @inheritdoc */ - protected function isVersion(string $v1, string $v2, string $operator = '==') : bool + public function isVersion(string $v1, string $v2, string $operator = '==') : bool { return Validator::isVersion($v1, $v2, $operator); } @@ -727,10 +740,10 @@ protected function isVersion(string $v1, string $v2, string $operator = '==') : /** * Validate plugin file. * - * @access protected + * @access public * @inheritdoc */ - protected function isPlugin(string $file) : bool + public function isPlugin(string $file) : bool { return Validator::isPlugin($file); } @@ -738,10 +751,10 @@ protected function isPlugin(string $file) : bool /** * Validate plugin class. * - * @access protected + * @access public * @inheritdoc */ - protected function isPluginClass(string $callable) : bool + public function isPluginClass(string $callable) : bool { return Validator::isPluginClass($callable); } @@ -749,10 +762,10 @@ protected function isPluginClass(string $callable) : bool /** * Validate plugin version. * - * @access protected + * @access public * @inheritdoc */ - protected function isPluginVersion(string $file, string $version, string $operator = '>=') : bool + public function isPluginVersion(string $file, string $version, string $operator = '>=') : bool { return Validator::isPluginVersion($file, $version, $operator); } @@ -760,10 +773,10 @@ protected function isPluginVersion(string $file, string $version, string $operat /** * Check value type. * - * @access protected + * @access public * @inheritdoc */ - protected function isType($type, $value) : bool + public function isType($type, $value) : bool { switch ($this->lowercase($type)) { case 'array': @@ -849,10 +862,10 @@ protected function isType($type, $value) : bool /** * Check object. * - * @access protected + * @access public * @inheritdoc */ - protected function hasObject($type, $object, $item) : bool + public function hasObject($type, $object, $item) : bool { switch ($this->lowercase($type)) { case 'interface': @@ -878,10 +891,10 @@ protected function hasObject($type, $object, $item) : bool /** * Convert array to object. * - * @access protected + * @access public * @inheritdoc */ - protected function toObject(array $array, $strict = false) : object + public function toObject(array $array, $strict = false) : object { return Converter::toObject($array, $strict); } @@ -889,10 +902,10 @@ protected function toObject(array $array, $strict = false) : object /** * Convert object to array. * - * @access protected + * @access public * @inheritdoc */ - protected function toArray(object $object) : array + public function toArray(object $object) : array { return Converter::toArray($object); } @@ -900,10 +913,10 @@ protected function toArray(object $object) : array /** * Convert data to key. * - * @access protected + * @access public * @inheritdoc */ - protected function toKey($data) : string + public function toKey($data) : string { return Converter::toKey($data); } @@ -911,11 +924,31 @@ protected function toKey($data) : string /** * Convert dynamic types. * - * @access protected + * @access public * @inheritdoc */ - protected function toTypes($value) + public function toTypes($value) { return Converter::toTypes($value); } + + /** + * Format credentials. + * + * @access public + * @inheritdoc + */ + public function toCredentials($data) + { + if ( TypeCheck::isArray($data) ) { + foreach ($data as $input => $value) { + $data[$input] = Stringify::stripSpace($value); + } + + } else { + $data = Stringify::stripSpace($data); + } + + return $data; + } } diff --git a/src/tr/TraitHookable.php b/src/tr/TraitHookable.php index 92b124a3..198c5b11 100644 --- a/src/tr/TraitHookable.php +++ b/src/tr/TraitHookable.php @@ -15,14 +15,17 @@ namespace VanillePlugin\tr; use VanillePlugin\inc\{ - Hook, Shortcode + Hook, Shortcode, Globals }; +/** + * Define hooking and shortcoding functions. + */ trait TraitHookable { /** * Register plugin activation hook. - * + * * @access protected * @inheritdoc */ @@ -33,7 +36,7 @@ protected function registerActivation(string $file, $callback) /** * Register plugin uninstall hook. - * + * * @access protected * @inheritdoc */ @@ -44,7 +47,7 @@ protected function registerDeactivation(string $file, $callback) /** * Register plugin uninstall hook. - * + * * @access protected * @inheritdoc */ @@ -55,7 +58,7 @@ protected function registerUninstall(string $file, $callback) /** * Register plugin action links hook. - * + * * @access protected * @inheritdoc */ @@ -77,7 +80,7 @@ protected function addAction(string $hook, $callback, int $priority = 10, int $a /** * Remove hook action. - * + * * @access protected * @inheritdoc */ @@ -88,7 +91,7 @@ protected function removeAction(string $hook, $callback, int $priority = 10) : b /** * Do hook action. - * + * * @access protected * @inheritdoc */ @@ -99,7 +102,7 @@ protected function doAction(string $hook, $args = null) /** * Check hook action. - * + * * @access protected * @inheritdoc */ @@ -110,7 +113,7 @@ protected function hasAction(string $hook, $callback = false) /** * Add hook filter. - * + * * @access protected * @inheritdoc */ @@ -121,7 +124,7 @@ protected function addFilter(string $hook, $callback, int $priority = 10, int $a /** * Remove hook filter. - * + * * @access protected * @inheritdoc */ @@ -132,7 +135,7 @@ protected function removeFilter(string $hook, $callback, int $priority = 10) : b /** * Apply hook filter. - * + * * @access protected * @inheritdoc */ @@ -143,7 +146,7 @@ protected function applyFilter(string $hook, $value, ...$args) /** * Check hook filter. - * + * * @access protected * @inheritdoc */ @@ -154,7 +157,7 @@ protected function hasFilter(string $hook, $callback = false) /** * Add CSS. - * + * * @access protected * @inheritdoc */ @@ -163,9 +166,20 @@ protected function addCSS(string $id, string $path, array $deps = [], $version = Hook::addCSS($id, $path, $deps, $version, $media); } + /** + * Include existing CSS. + * + * @access protected + * @inheritdoc + */ + protected function includeCSS(string $id, string $path, array $deps = [], $version = false, string $media = 'all') + { + $this->addCSS($id, Globals::includesUrl($path), $deps, $version, $media); + } + /** * Add JS. - * + * * @access protected * @inheritdoc */ @@ -173,10 +187,21 @@ protected function addJS(string $id, string $path, array $deps = [], $version = { Hook::addJS($id, $path, $deps, $version, $footer); } - + + /** + * Include existing JS. + * + * @access protected + * @inheritdoc + */ + protected function includeJS(string $id, string $path, array $deps = [], $version = false, bool $footer = false) + { + $this->addJS($id, Globals::includesUrl($path), $deps, $version, $footer); + } + /** * Check enqueued CSS. - * + * * @access protected * @inheritdoc */ @@ -187,7 +212,7 @@ protected function isCSS(string $id, string $list = 'enqueued') : bool /** * Check enqueued JS. - * + * * @access protected * @inheritdoc */ @@ -198,7 +223,7 @@ protected function isJS(string $id, string $list = 'enqueued') : bool /** * Remove CSS. - * + * * @access protected * @inheritdoc */ @@ -209,7 +234,7 @@ protected function removeCSS(string $id) /** * Remove JS. - * + * * @access protected * @inheritdoc */ @@ -220,7 +245,7 @@ protected function removeJS(string $id) /** * Assign enqueued JS data. - * + * * @access protected * @inheritdoc */ @@ -231,7 +256,7 @@ protected function assignJS(string $id, string $object, array $data = []) : bool /** * Check whether script exists. - * + * * @access protected * @inheritdoc */ @@ -242,7 +267,7 @@ protected function hasScript(string $search, $scripts) : bool /** * Remove excluded scripts. - * + * * @access protected * @inheritdoc */ @@ -253,7 +278,7 @@ protected function removeScripts(array $exclude) /** * Add shortcode. - * + * * @access protected * @inheritdoc */ @@ -264,7 +289,7 @@ protected function addShortcode(string $tag, $callback) /** * Assign content to shortcode. - * + * * @access protected * @inheritdoc */ @@ -275,7 +300,7 @@ protected function assignShortcode(string $content, bool $ignore = false) /** * Render shortcode. - * + * * @access protected * @inheritdoc */ @@ -286,7 +311,7 @@ protected function renderShortcode(string $content, bool $ignore = false) /** * Remove shortcode. - * + * * @access protected * @inheritdoc */ @@ -297,7 +322,7 @@ protected function removeShortcode(string $tag) /** * Check whether shortcode registered. - * + * * @access protected * @inheritdoc */ diff --git a/src/tr/TraitIO.php b/src/tr/TraitIO.php index 0cc4302c..b408548e 100644 --- a/src/tr/TraitIO.php +++ b/src/tr/TraitIO.php @@ -15,18 +15,21 @@ namespace VanillePlugin\tr; use VanillePlugin\inc\{ - File, Arrayify, Json, Archive + File, Json, Archive, Stringify, TypeCheck }; +/** + * Define filesystem IO functions. + */ trait TraitIO { /** * Check file. * - * @access protected + * @access public * @inheritdoc */ - protected function isFile(string $path) : bool + public function isFile(string $path) : bool { return File::isFile($path); } @@ -34,10 +37,10 @@ protected function isFile(string $path) : bool /** * Check file readable. * - * @access protected + * @access public * @inheritdoc */ - protected function isReadable(string $path, bool $fileType = false) : bool + public function isReadable(string $path, bool $fileType = false) : bool { if ( $fileType && !$this->isFile($path) ) { return false; @@ -48,10 +51,10 @@ protected function isReadable(string $path, bool $fileType = false) : bool /** * Check file writable. * - * @access protected + * @access public * @inheritdoc */ - protected function isWritable(string $path, bool $fileType = false) : bool + public function isWritable(string $path, bool $fileType = false) : bool { if ( $fileType && !$this->isFile($path) ) { return false; @@ -62,14 +65,69 @@ protected function isWritable(string $path, bool $fileType = false) : bool /** * Read file. * - * @access protected + * @access public * @inheritdoc */ - protected function readFile(string $path, bool $inc = false, $context = null, int $offset = 0) + public function readFile(string $path, bool $inc = false, $context = null, int $offset = 0) { return File::r($path, $inc, $context, $offset); } + /** + * Check directory. + * + * @access public + * @inheritdoc + */ + public function isDir(string $path) : bool + { + return File::isDir($path); + } + + /** + * Scan directory. + * + * @access public + * @inheritdoc + */ + public function scanDir(string $path = '.', int $sort = 0, array $except = []) : array + { + return File::scanDir($path, $sort, $except); + } + + /** + * Get all file lines. + * + * @access public + * @inheritdoc + */ + public function getLines(string $path) : array + { + return File::getLines($path); + } + + /** + * Parse file lines using stream. + * + * @access public + * @inheritdoc + */ + public function parseLines(string $path, int $limit = 10) : array + { + return File::parseLines($path, $limit); + } + + /** + * Parse JSON file. + * + * @access public + * @inheritdoc + */ + public function parseJson(string $file, bool $isArray = false) + { + return Json::parse($file, $isArray); + } + /** * Write file. * @@ -87,22 +145,14 @@ protected function writeFile(string $path, $input = '', bool $append = false) : * @access protected * @inheritdoc */ - protected function removeFile(string $path) + protected function removeFile(string $path, $from = []) { + if ( !$this->secureRemove($path, $from) ) { + return false; + } return File::remove($path); } - /** - * Check directory. - * - * @access protected - * @inheritdoc - */ - protected function isDir(string $path) : bool - { - return File::isDir($path); - } - /** * Add directory. * @@ -114,27 +164,15 @@ protected function addDir(string $path, int $p = 0755, bool $r = true, $c = null return File::addDir($path, $p, $r, $c); } - /** - * Scan directory. - * - * @access protected - * @inheritdoc - */ - protected function scanDir(string $path = '.', int $sort = 0, array $except = []) : array - { - return File::scanDir($path, $sort, $except); - } - /** * Clear directory recursively. * * @access protected - * @param array $secure * @inheritdoc */ - protected function clearDir(string $path, array $secure = []) : bool + protected function clearDir(string $path, $from = []) : bool { - if ( !$this->secureRemove($path, $secure) ) { + if ( !$this->secureRemove($path, $from) ) { return false; } return File::clearDir($path); @@ -144,50 +182,16 @@ protected function clearDir(string $path, array $secure = []) : bool * Remove directory. * * @access protected - * @param array $secure * @inheritdoc */ - protected function removeDir(string $path, bool $clear = false, array $secure = []) : bool + protected function removeDir(string $path, bool $clear = false, $from = []) : bool { - if ( !$this->secureRemove($path, $secure) ) { + if ( !$this->secureRemove($path, $from) ) { return false; } return File::removeDir($path, $clear); } - /** - * Get all file lines. - * - * @access protected - * @inheritdoc - */ - protected function getLines(string $path) : array - { - return File::getLines($path); - } - - /** - * Parse file lines using stream. - * - * @access protected - * @inheritdoc - */ - protected function parseLines(string $path, int $limit = 10) : array - { - return File::parseLines($path, $limit); - } - - /** - * Parse JSON file. - * - * @access protected - * @inheritdoc - */ - protected function parseJson(string $file, bool $isArray = false) - { - return Json::parse($file, $isArray); - } - /** * Compress archive. * @@ -215,18 +219,23 @@ protected function uncompressArchive(string $archive, string $to = '', $remove = * * @access private * @param string $path - * @param array $secure + * @param mixed $secure * @return bool */ - private function secureRemove(string $path, array $secure = []) : bool + private function secureRemove(string $path, $secure = []) : bool { - $paths = explode('/', $path); - $secure = Arrayify::merge(['storage'], $secure); + if ( $secure && !TypeCheck::isArray($secure) ) { + $secure = (string)$secure; + $secure = [$secure]; + } + + $secure = ($secure) ? $secure : ['core/storage']; foreach ($secure as $include) { - if ( !Arrayify::inArray($include, $paths) ) { + if ( !Stringify::contains($path, $include) ) { return false; } } + return true; } } diff --git a/src/tr/TraitInjectable.php b/src/tr/TraitInjectable.php new file mode 100644 index 00000000..a3b9fe15 --- /dev/null +++ b/src/tr/TraitInjectable.php @@ -0,0 +1,67 @@ + + * @link : https://jakiboy.github.io/VanillePlugin/ + * @license : MIT + * + * This file if a part of VanillePlugin Framework. + */ + +declare(strict_types=1); + +namespace VanillePlugin\tr; + +use VanillePlugin\lib\Hook; + +/** + * Define injectable hooks functions. + */ +trait TraitInjectable +{ + /** + * Get hooks values. + * + * @access public + * @inheritdoc + */ + public function getHookables() + { + return (new Hook)->getValues(); + } + + /** + * Register hooks inside option group. + * + * @access protected + * @inheritdoc + */ + protected function registerHooks() + { + (new Hook)->register(); + } + + /** + * Add hooks. + * + * @access protected + * @inheritdoc + */ + protected function addHooks() : bool + { + return (new Hook)->add(); + } + + /** + * Update hooks values. + * + * @access protected + * @inheritdoc + */ + protected function updateHookables(array $data) : bool + { + return (new Hook)->updateValues($data); + } +} diff --git a/src/tr/TraitLoggable.php b/src/tr/TraitLoggable.php index 835da341..e2b45dd2 100644 --- a/src/tr/TraitLoggable.php +++ b/src/tr/TraitLoggable.php @@ -16,6 +16,9 @@ use VanillePlugin\lib\Logger; +/** + * Define logging functions. + */ trait TraitLoggable { /** diff --git a/src/tr/TraitMapable.php b/src/tr/TraitMappable.php similarity index 51% rename from src/tr/TraitMapable.php rename to src/tr/TraitMappable.php index 585a59ce..ca4438c6 100644 --- a/src/tr/TraitMapable.php +++ b/src/tr/TraitMappable.php @@ -16,27 +16,29 @@ use VanillePlugin\inc\Arrayify; -trait TraitMapable +/** + * Define mapping functions. + */ +trait TraitMappable { - /** - * @access protected - * @inheritdoc - */ - protected function mapArray($callback, array $array, ?array $arrays = null) - { - switch ($callback) { - case 'values': - $callback = 'array_values'; - break; - } - return Arrayify::map($callback, $array, $arrays); - } + /** + * Map array. + * + * @access public + * @inheritdoc + */ + public function map($callback, array $array, ?array $arrays = null) : array + { + return Arrayify::map($callback, $array, $arrays); + } /** - * @access protected + * Walk recursive array. + * + * @access public * @inheritdoc */ - protected function recursiveArray(&$array, $callback, $arg = null) : bool + public function recursiveArray(&$array, $callback, $arg = null) : bool { return Arrayify::recursive($array, $callback, $arg); } diff --git a/src/tr/TraitMigratable.php b/src/tr/TraitMigratable.php index 12c511d4..7246a664 100644 --- a/src/tr/TraitMigratable.php +++ b/src/tr/TraitMigratable.php @@ -16,8 +16,22 @@ use VanillePlugin\lib\Migrate; +/** + * Define database migration functions. + */ trait TraitMigratable { + /** + * Check whether plugin has migrate lock. + * + * @access public + * @inheritdoc + */ + public function isMigrated() : bool + { + return (new Migrate())->isMigrated(); + } + /** * Install plugin database tables. * @@ -73,24 +87,13 @@ protected function migrateOptions(array $options) : bool return (new Migrate())->option($options); } - /** - * Check whether plugin has migrate lock. - * - * @access protected - * @inheritdoc - */ - protected function isMigrated() : bool - { - return (new Migrate())->isMigrated(); - } - /** * Export plugin database table. * * @access protected * @inheritdoc */ - protected function exportTable(string $table, $column) + protected function exportTable(string $table, ?string $column = null) { return (new Migrate())->export($table, $column); } diff --git a/src/tr/TraitPermissionable.php b/src/tr/TraitPermissionable.php index 98dfd42f..13ab6b70 100644 --- a/src/tr/TraitPermissionable.php +++ b/src/tr/TraitPermissionable.php @@ -16,87 +16,102 @@ use VanillePlugin\inc\User; +/** + * Define permissions functions. + */ trait TraitPermissionable { /** - * @access protected + * Get user roles. + * + * @access public * @inheritdoc */ - protected function getRoles($id = null) : array + public function getRoles($id = null) : array { return User::getRoles($id); } /** - * @access protected + * Get role object. + * + * @access public * @inheritdoc */ - protected function getRole(string $role) + public function getRole(string $role) { return User::getRole($role); } /** - * @access protected + * Check whether user has role. + * + * @access public * @inheritdoc */ - protected function addRole(string $display, string $role = null, array $cap = []) + public function hasRole(string $role, $id = null) : bool { - return User::addRole($role, $display, $cap); + return User::hasRole($role, $id); } /** - * @access protected + * Check whether user is administrator. + * + * @access public * @inheritdoc */ - protected function removeRole(string $role) + public function isAdministrator($id = null) : bool { - User::removeRole($role); + return $this->hasRole('administrator', $id); } /** - * Check whether user has role. + * Get user capabilities. * - * @access protected + * @access public * @inheritdoc */ - protected function hasRole(string $role, $id = null) : bool + public function getCaps($id = null) : array { - return User::hasRole($role, $id); + return User::getCaps($id); } /** - * Check whether user is administrator. + * Check user capability. * - * @access protected + * @access public * @inheritdoc */ - protected function isAdministrator($id = null) : bool + public function hasCap(string $cap = 'edit-posts', $id = null, ...$args) : bool { - return $this->hasRole('administrator', $id); + return User::hasCap($cap, $id, ...$args); } /** + * Add role. + * * @access protected * @inheritdoc */ - protected function getCaps($id = null) : array + protected function addRole(string $display, string $role = null, array $cap = []) { - return User::getCaps($id); + return User::addRole($role, $display, $cap); } - + /** - * Check user capability. + * Remove role. * * @access protected * @inheritdoc */ - protected function hasCap(string $cap = 'edit-posts', $id = null, ...$args) : bool + protected function removeRole(string $role) { - return User::hasCap($cap, $id, ...$args); + User::removeRole($role); } /** + * Add role capability. + * * @access protected * @inheritdoc */ @@ -106,6 +121,8 @@ protected function addCap(string $role, string $cap, bool $grant = true) : bool } /** + * Remove role capability. + * * @access protected * @inheritdoc */ diff --git a/src/tr/TraitRenderable.php b/src/tr/TraitRenderable.php index efc12c63..f596a56f 100644 --- a/src/tr/TraitRenderable.php +++ b/src/tr/TraitRenderable.php @@ -16,8 +16,44 @@ use VanillePlugin\inc\Page; +/** + * Define admin page functions. + */ trait TraitRenderable { + /** + * Get current screen. + * + * @access public + * @inheritdoc + */ + public function getScreen() + { + return Page::screen(); + } + + /** + * Check is current screen. + * + * @access public + * @inheritdoc + */ + public function isScreen(string $screen) : bool + { + return Page::isScreen($screen); + } + + /** + * Get checkbox attribute. + * + * @access public + * @inheritdoc + */ + public function getCheckbox($data, $value = true) : string + { + return Page::getCheckbox($data, $value); + } + /** * Add options page. * @@ -92,50 +128,6 @@ protected function addMetabox(string $id, string $t, $cb, $s, string $c = 'advan Page::addMetabox($id, $t, $cb, $s, $c, $p, $args); } - /** - * Check whether page is admin. - * - * @access protected - * @inheritdoc - */ - protected function isAdmin() : bool - { - return Page::isAdmin(); - } - - /** - * Check whether page is login. - * - * @access protected - * @inheritdoc - */ - protected function isLogin() : bool - { - return Page::isLogin(); - } - - /** - * Get current screen. - * - * @access protected - * @inheritdoc - */ - protected function getScreen() - { - return Page::screen(); - } - - /** - * Check is current screen. - * - * @access protected - * @inheritdoc - */ - protected function isScreen(string $screen) : bool - { - return Page::isScreen($screen); - } - /** * Add help menu (tab). * @@ -201,15 +193,4 @@ protected function addDashboardWidget(string $id, string $name, $cb, $ctrl = nul { Page::addDashboardWidget($id, $name, $cb, $ctrl, $args, $c, $p); } - - /** - * Get checkbox attribute. - * - * @access protected - * @inheritdoc - */ - protected function getCheckbox($data, $value = true) : string - { - return Page::getCheckbox($data, $value); - } } diff --git a/src/tr/TraitRequestable.php b/src/tr/TraitRequestable.php index b9534164..44ca81eb 100644 --- a/src/tr/TraitRequestable.php +++ b/src/tr/TraitRequestable.php @@ -16,177 +16,220 @@ use VanillePlugin\inc\{ HttpRequest, HttpPost, HttpGet, - Response, Server, Stringify, Converter + Response, Server, Stringify, + Upload }; +/** + * Define HTTP functions. + */ trait TraitRequestable { /** - * @access protected + * Get request value. + * + * @access public * @inheritdoc */ - protected function getRequest(?string $key = null) + public function getRequest(?string $key = null) { return HttpRequest::get($key); } /** - * @access protected + * Check request value. + * + * @access public * @inheritdoc */ - protected function hasRequest(?string $key = null) : bool + public function hasRequest(?string $key = null) : bool { return HttpRequest::isSetted($key); } /** - * @access protected + * Get HTTP POST value. + * + * @access public * @inheritdoc */ - protected function getHttpPost(?string $key = null, bool $type = false) + public function getHttpPost(?string $key = null) { - $data = HttpPost::get($key); - if ( $type ) { - return Converter::toTypes($data); - } - return $data; + return HttpPost::get($key); } /** - * @access protected + * Check HTTP POST value. + * + * @access public * @inheritdoc */ - protected function hasHttpPost(?string $key = null) : bool + public function hasHttpPost(?string $key = null) : bool { return HttpPost::isSetted($key); } /** - * @access protected + * Get HTTP GET value. + * + * @access public * @inheritdoc */ - protected function getHttpGet(?string $key = null, bool $type = false) + public function getHttpGet(?string $key = null) { - $data = HttpGet::get($key); - if ( $type ) { - return Converter::toTypes($data); - } - return $data; + return HttpGet::get($key); } /** - * @access protected + * Get HTTP GET value. + * + * @access public * @inheritdoc */ - protected function hasHttpGet(?string $key = null) : bool + public function hasHttpGet(?string $key = null) : bool { return HttpGet::isSetted($key); } /** - * @access protected + * Get blob value. + * + * @access public * @inheritdoc */ - protected function setHttpResponse(string $message, $content = [], string $status = 'success', int $code = 200) - { - Response::set($message, $content, $status, $code); - } + public function getBlob(?string $key = null) + { + return Upload::get($key); + } /** - * @access protected + * Check blob value. + * + * @access public * @inheritdoc */ - protected function getServer(?string $key = null, $format = true) + public function hasBlob(?string $key = null) : bool { - return Server::get($key, $format); + return Upload::isSetted($key); } /** - * @access protected + * Get server value. + * + * @access public * @inheritdoc */ - protected function getServerBaseUrl() : string + public function getServer(?string $key = null) + { + return Server::get($key); + } + + /** + * Check server value. + * + * @access public + * @inheritdoc + */ + public function hasHttpServer(?string $key = null) : bool + { + return Server::isSetted($key); + } + + /** + * Get base URL. + * + * @access public + * @inheritdoc + */ + public function getServerBaseUrl() : string { return Server::getBaseUrl(); } /** - * @access protected + * Get current URL. + * + * @access public * @inheritdoc */ - protected function getServerCurrentUrl($escape = false) : string + public function getServerCurrentUrl($escape = false) : string { return Server::getCurrentUrl($escape); } /** - * @access protected + * Get protocol. + * + * @access public * @inheritdoc */ - protected function getServerProtocol() : string + public function getServerProtocol() : string { return Server::getProtocol(); } /** - * @access protected + * Get remote IP address. + * + * @access public * @inheritdoc */ - protected function getServerIp(?string $domain = null) + public function getServerIp(?string $domain = null) { return Server::getIp($domain); } /** - * @access protected + * Check basic authentication. + * + * @access public * @inheritdoc */ - protected function isBasicAuth() : bool + public function isBasicAuth() : bool { return Server::isBasicAuth(); } /** - * @access protected + * Get basic authentication user. + * + * @access public * @inheritdoc */ - protected function getBasicAuthUser() : string + public function getBasicAuthUser() : string { return Server::getBasicAuthUser(); } /** - * @access protected + * Get basic authentication password. + * + * @access public * @inheritdoc */ - protected function getBasicAuthPwd() : string + public function getBasicAuthPwd() : string { return Server::getBasicAuthPwd(); } /** - * @access protected + * Get authorization token. + * + * @access public * @inheritdoc */ - protected function getBearerToken() : string + public function getBearerToken() : string { return Server::getBearerToken(); } /** - * @access protected - * @inheritdoc - */ - protected function redirect(string $location, int $status = 301) - { - Server::redirect($location, $status); - } - - /** - * @access protected + * Check whether protocol is HTTPS (SSL). + * + * @access public * @inheritdoc */ - protected function isSsl() : bool + public function isSsl() : bool { return Server::isSsl(); } @@ -194,10 +237,10 @@ protected function isSsl() : bool /** * Check if SSL verify is required (SNI). * - * @access protected + * @access public * @inheritdoc */ - protected function mayRequireSSL(bool $verify = true) : bool + public function mayRequireSSL(bool $verify = true) : bool { return Server::mayRequireSSL($verify); } @@ -205,22 +248,55 @@ protected function mayRequireSSL(bool $verify = true) : bool /** * Get domain name from URL. * - * @access protected + * @access public * @inheritdoc */ - protected function getDomainName(?string $url = null) : string + public function getDomainName(?string $url = null) : string { return Server::getDomain($url); } + /** + * Parse base from URL. + * + * @access public + * @inheritdoc + */ + public function parseBaseUrl(string $url) : string + { + return Server::parseBaseUrl($url); + } + /** * Parse URL. * - * @access protected + * @access public * @inheritdoc */ - protected function parseUrl(string $url, int $component = -1) + public function parseUrl(string $url, int $component = -1) { return Stringify::parseUrl($url, $component); } + + /** + * Set HTTP response. + * + * @access protected + * @inheritdoc + */ + protected function setHttpResponse(string $message, $content = [], string $status = 'success', int $code = 200) + { + Response::set($message, $content, $status, $code); + } + + /** + * Redirect request. + * + * @access protected + * @inheritdoc + */ + protected function redirect(string $location, int $status = 301) + { + Server::redirect($location, $status); + } } diff --git a/src/tr/TraitSecurable.php b/src/tr/TraitSecurable.php index b3674c6f..20b33aa6 100644 --- a/src/tr/TraitSecurable.php +++ b/src/tr/TraitSecurable.php @@ -15,62 +15,32 @@ namespace VanillePlugin\tr; use VanillePlugin\inc\{ - Encryption, Tokenizer + Encryption, Tokenizer, Arrayify }; +/** + * Define security functions. + */ trait TraitSecurable { - /** - * Get token. - * - * @access protected - * @inheritdoc - */ - protected function getToken(string $user, string $pswd, ?string $prefix = null) : array - { - return Tokenizer::get($user, $pswd, $prefix); - } - - /** - * Match token. - * - * @access protected - * @inheritdoc - */ - protected function matchToken(string $token, string $secret, ?string $prefix = null) - { - return Tokenizer::match($token, $secret, $prefix); - } - - /** - * Create nonce. - * - * @access protected - * @inheritdoc - */ - protected function createNonce($action = -1) : string - { - return Tokenizer::createNonce($action); - } - /** * Check nonce. * - * @access protected + * @access public * @inheritdoc */ - protected function checkNonce(string $nonce, $action = -1) : bool + public function checkNonce(string $nonce, $action = -1) : bool { return Tokenizer::checkNonce($nonce, $action); } /** - * Check AJAX nonce. + * Check Ajax nonce. * - * @access protected + * @access public * @inheritdoc */ - protected function checkAjaxNonce($nonce, $action = -1) : bool + public function checkAjaxNonce($nonce, $action = -1) : bool { return Tokenizer::checkAjaxNonce($action, $nonce); } @@ -78,10 +48,10 @@ protected function checkAjaxNonce($nonce, $action = -1) : bool /** * Encode base64. * - * @access protected + * @access public * @inheritdoc */ - protected function base64(string $value, int $loop = 1) : string + public function base64(string $value, int $loop = 1) : string { return Tokenizer::base64($value, $loop); } @@ -89,10 +59,10 @@ protected function base64(string $value, int $loop = 1) : string /** * Decode base64. * - * @access protected + * @access public * @inheritdoc */ - protected function unbase64(string $value, int $loop = 1) : string + public function unbase64(string $value, int $loop = 1) : string { return Tokenizer::unbase64($value, $loop); } @@ -100,10 +70,10 @@ protected function unbase64(string $value, int $loop = 1) : string /** * Get unique Id. * - * @access protected + * @access public * @inheritdoc */ - protected function getUniqueId() : string + public function getUniqueId() : string { return Tokenizer::getUniqueId(); } @@ -111,10 +81,10 @@ protected function getUniqueId() : string /** * Generate token. * - * @access protected + * @access public * @inheritdoc */ - protected function generateToken(int $length = 16, bool $special = false) : string + public function generateToken(int $length = 16, bool $special = false) : string { return Tokenizer::generate($length, $special); } @@ -122,13 +92,42 @@ protected function generateToken(int $length = 16, bool $special = false) : stri /** * Generate hash. * - * @access protected + * @access public * @inheritdoc */ - protected function generateHash($data, string $salt = 'Y3biC') : string + public function generateHash($data, string $salt = 'Y3biC') : string { return Tokenizer::hash($data, $salt); } + /** + * Get access token. + * + * @access public + * @inheritdoc + */ + public function getAccessToken($data, string $secret, ?string $prefix = null) : string + { + $data = Arrayify::merge([ + 'user' => false, + 'pswd' => false + ], $data); + return $this->encrypt($data, $secret, $prefix); + } + + /** + * Get access from token. + * + * @access public + * @inheritdoc + */ + public function getAccess(string $token, string $secret, ?string $prefix = null) : array + { + $access = (array)$this->decrypt($token, $secret, $prefix); + return Arrayify::merge([ + 'user' => false, + 'pswd' => false + ], $access); + } /** * Encrypt data. @@ -136,9 +135,9 @@ protected function generateHash($data, string $salt = 'Y3biC') : string * @access protected * @inheritdoc */ - protected function encrypt($data, ?string $key = null, string $prefix = Encryption::PREFIX) : string + protected function encrypt($data, ?string $secret = null, ?string $prefix = null) : string { - $cryptor = new Encryption($data, $key); + $cryptor = new Encryption($data, $secret); return $cryptor->setPrefix($prefix)->encrypt(); } @@ -148,9 +147,20 @@ protected function encrypt($data, ?string $key = null, string $prefix = Encrypti * @access protected * @inheritdoc */ - protected function decrypt($data, ?string $key = null, string $prefix = Encryption::PREFIX) + protected function decrypt($data, ?string $secret = null, ?string $prefix = null) { - $cryptor = new Encryption($data, $key); + $cryptor = new Encryption($data, $secret); return $cryptor->setPrefix($prefix)->decrypt(); } + + /** + * Create nonce. + * + * @access protected + * @inheritdoc + */ + protected function createNonce($action = -1) : string + { + return Tokenizer::createNonce($action); + } } diff --git a/src/tr/TraitSerializable.php b/src/tr/TraitSerializable.php index c3163944..7524d7fc 100644 --- a/src/tr/TraitSerializable.php +++ b/src/tr/TraitSerializable.php @@ -16,32 +16,52 @@ use VanillePlugin\inc\Stringify; +/** + * Define serializing functions. + */ trait TraitSerializable { /** - * @access protected + * Serialize value if not serialized. + * + * @access public * @inheritdoc */ - protected function serialize($value) + public function serialize($value) { return Stringify::serialize($value); } /** - * @access protected + * Unserialize serialized value. + * + * @access public * @inheritdoc */ - protected function unserialize(string $value) + public function unserialize(string $value) { return Stringify::unserialize($value); } /** - * @access protected + * Check serialized value. + * + * @access public * @inheritdoc */ - protected function isSerialized(string $value) : bool + public function isSerialized(string $value) : bool { return Stringify::isSerialized($value); } + + /** + * Check serialized value. + * + * @access public + * @inheritdoc + */ + public function toString(string $value) : bool + { + return $this->__toString(); + } } diff --git a/src/tr/TraitSessionable.php b/src/tr/TraitSessionable.php index e47dfabf..1e3fc425 100644 --- a/src/tr/TraitSessionable.php +++ b/src/tr/TraitSessionable.php @@ -18,117 +18,146 @@ Session, Cookie }; +/** + * Define session functions. + */ trait TraitSessionable { /** - * @access protected + * Get session value. + * + * @access public * @inheritdoc */ - protected function startSession() + public function getSession(?string $key = null) { - new Session(); + return Session::get($key); } /** - * @access protected + * Check session value. + * + * @access public * @inheritdoc */ - protected function setSession($key, $value = null) + public function hasSession(?string $key = null) : bool { - Session::set($key, $value); + return Session::isSetted($key); } /** - * @access protected + * Check whether session is registered. + * + * @access public * @inheritdoc */ - protected function getSession(?string $key = null) - { - return Session::get($key); - } + public function isSessionRegistered() : bool + { + return Session::isRegistered(); + } /** - * @access protected + * Check whether session is expired. + * + * @access public * @inheritdoc */ - protected function hasSession(?string $key = null) : bool - { - return Session::isSetted($key); - } + public function isSessionExpired() : bool + { + return Session::isExpired(); + } /** - * @access protected + * Get cookie value. + * + * @access public * @inheritdoc */ - protected function registerSession($time = 60) - { - Session::register($time); - } - + public function getCookie(?string $key = null) + { + return Cookie::get($key); + } + /** - * @access protected + * Check cookie value. + * + * @access public * @inheritdoc */ - protected function isSessionRegistered() : bool + public function hasCookie(?string $key = null) { - return Session::isRegistered(); + return Cookie::isSetted($key); } /** + * Start session if not active. + * * @access protected * @inheritdoc */ - protected function isSessionExpired() : bool - { - return Session::isExpired(); - } + protected function startSession() + { + new Session(); + } /** + * Set session value. + * * @access protected * @inheritdoc */ - protected function closeSession() : bool + protected function setSession($key, $value = null) { - return Session::close(); + Session::set($key, $value); } /** + * Register session. + * * @access protected * @inheritdoc */ - protected function endSession() : bool + protected function registerSession($time = 60) { - return Session::end(); + Session::register($time); } /** + * Close session (Read-only). + * * @access protected * @inheritdoc */ - protected function getCookie(?string $key = null) - { - return Cookie::get($key); - } + protected function closeSession() : bool + { + return Session::close(); + } /** + * End session (Destroy). + * * @access protected * @inheritdoc */ - protected function setCookie(string $key, $value = '', $options = []) - { - return Cookie::set($key, $value, $options); - } - + protected function endSession() : bool + { + return Session::end(); + } + /** + * Set cookie value. + * * @access protected * @inheritdoc */ - protected function hasCookie(?string $key = null) + protected function setCookie(string $key, $value = '', $options = []) { - return Cookie::isSetted($key); + return Cookie::set($key, $value, $options); } /** + * Clear session cookie. + * * @access protected * @inheritdoc */ diff --git a/src/tr/TraitThrowable.php b/src/tr/TraitThrowable.php index 46cabe97..5feff249 100644 --- a/src/tr/TraitThrowable.php +++ b/src/tr/TraitThrowable.php @@ -16,72 +16,85 @@ use VanillePlugin\inc\Exception; +/** + * Define error functions. + */ trait TraitThrowable { /** - * @access protected + * Get object error message. + * + * @access public * @inheritdoc */ - protected function handleException($callable) + public function getError($object) { - Exception::handle($callable); + return Exception::getError($object); } /** - * @access protected + * Check object error. + * + * @access public * @inheritdoc */ - protected function getLastError() + public function isError($object) : bool { - Exception::getLastError(); + return Exception::isError($object); } /** - * @access protected + * Get last error. + * + * @access public * @inheritdoc */ - protected function clearLastError() + public function getLastError() { - Exception::clearLastError(); + Exception::getLastError(); } /** - * @access protected + * Trigger user error. + * + * @access public * @inheritdoc */ - protected function triggerError(string $error, int $type = E_USER_NOTICE) : bool + public function triggerError(string $error, int $type = 1024) : bool { return Exception::trigger($error, $type); } - + /** - * @access protected + * Throw error and stop execution. + * + * @access public * @inheritdoc */ - protected function throwError(string $error) + public function throwError(string $error) { Exception::throw($error); } /** - * Check for WordPress error. + * Handle shutdown exception. * * @access protected * @inheritdoc */ - protected function isError($object) : bool + protected function handleException($callable) { - return Exception::isError($object); + Exception::handle($callable); } /** - * Get WordPress error. + * Clear last error. * * @access protected * @inheritdoc */ - protected function getError($object) + protected function clearLastError() { - return Exception::getError($object); + Exception::clearLastError(); } } diff --git a/src/tr/TraitTranslatable.php b/src/tr/TraitTranslatable.php index 1d7ef2ea..a51f0dbd 100644 --- a/src/tr/TraitTranslatable.php +++ b/src/tr/TraitTranslatable.php @@ -17,15 +17,18 @@ use VanillePlugin\inc\Localization; use VanilleThird\Translator; +/** + * Define translation functions. + */ trait TraitTranslatable { /** * Get site locale. * - * @access protected + * @access public * @inheritdoc */ - protected function getLocale($user = null) : string + public function getLocale($user = null) : string { return Localization::getLocale($user); } diff --git a/src/tr/TraitUpdatable.php b/src/tr/TraitUpdatable.php index eacc8cc3..0f53c326 100644 --- a/src/tr/TraitUpdatable.php +++ b/src/tr/TraitUpdatable.php @@ -14,30 +14,34 @@ namespace VanillePlugin\tr; +use VanillePlugin\int\UpgraderInterface; use VanillePlugin\lib\Updater; +/** + * Define updating and upgrading functions. + */ trait TraitUpdatable { /** - * Set update listener. - * - * @access protected + * Get update status. + * + * @access public * @inheritdoc */ - protected function update(array $auth = [], array $urls = []) + public function isUpdated() : bool { - (new Updater($auth, $urls))->listen(); + return (new Updater())->isUpdated(); } /** - * Get update status. - * + * Set update listener. + * * @access protected * @inheritdoc */ - protected function isUpdated() : bool + protected function doUpdate(array $auth = [], array $urls = []) { - return (new Updater())->isUpdated(); + (new Updater($auth, $urls))->listen(); } /** @@ -61,4 +65,17 @@ protected function removeUpdates() : bool { return (new Updater())->remove(); } + + /** + * Set upgrader listener. + * + * @access protected + * @inheritdoc + */ + protected function doUpgrade(UpgraderInterface $upgrader) + { + if ( $this->isUpdated() ) { + $upgrader->upgrade(); + } + } } diff --git a/src/tr/TraitUploadable.php b/src/tr/TraitUploadable.php new file mode 100644 index 00000000..2082356c --- /dev/null +++ b/src/tr/TraitUploadable.php @@ -0,0 +1,88 @@ + + * @link : https://jakiboy.github.io/VanillePlugin/ + * @license : MIT + * + * This file if a part of VanillePlugin Framework. + */ + +declare(strict_types=1); + +namespace VanillePlugin\tr; + +use VanillePlugin\inc\{ + Upload, File +}; + +/** + * Define uploading functions. + */ +trait TraitUploadable +{ + /** + * Get upload directory. + * + * @access public + * @inheritdoc + */ + public function getUploadDir(?string $sub = null) : string + { + return Upload::getDir($sub); + } + + /** + * Get upload URL. + * + * @access public + * @inheritdoc + */ + public function getUploadUrl(?string $sub = null) : string + { + return Upload::getUrl($sub); + } + + /** + * Move uploaded file. + * + * @access protected + * @inheritdoc + */ + protected function moveUpload(string $from, string $to) : bool + { + return Upload::move($from, $to); + } + + /** + * Handle uploaded files. + * + * @access protected + * @inheritdoc + */ + protected function doUpload(array &$files, string $path, ?array $types = []) : bool + { + $count = 0; + $files = Upload::sanitize($files, $types); + + if ( !File::exists($path) ) { + File::addDir($path); + } + + foreach ($files as $key => $file) { + + $temp = $file['temp']; + $path = "{$path}/{$file['path']}"; + + if ( $this->moveUpload($temp, $path) ) { + $files[$key]['path'] = $path; + ++$count; + } + + } + + return (bool)$count; + } +} diff --git a/src/tr/TraitViewable.php b/src/tr/TraitViewable.php index 3c861cb0..f9c93d3d 100644 --- a/src/tr/TraitViewable.php +++ b/src/tr/TraitViewable.php @@ -16,6 +16,9 @@ use VanillePlugin\inc\Template; +/** + * Define template engine functions. + */ trait TraitViewable { /** @@ -30,7 +33,7 @@ protected function getEnvironment(string $path, array $options = []) : object } /** - * Add view callable. + * Extend view callables. * * @access protected * @inheritdoc