Compare commits
3 Commits
master
...
rewrite/ma
Author | SHA1 | Date | |
---|---|---|---|
9927be2198 | |||
b5bf0425f3 | |||
0b0f4998b4 |
87
.drone.yml
87
.drone.yml
@ -1,36 +1,53 @@
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: test
|
||||
|
||||
steps:
|
||||
- name: composer
|
||||
image: composer:latest
|
||||
commands:
|
||||
- composer install
|
||||
|
||||
- name: php74test
|
||||
image: registry.i15.nl/i15/fuzephp:7.4-alpine
|
||||
commands:
|
||||
- docker-php-ext-enable xdebug
|
||||
- vendor/bin/phpunit -c test/phpunit.xml
|
||||
|
||||
- name: php80test
|
||||
image: registry.i15.nl/i15/fuzephp:8.0-alpine
|
||||
commands:
|
||||
- docker-php-ext-enable xdebug
|
||||
- vendor/bin/phpunit -c test/phpunit.xml
|
||||
|
||||
- name: php81test
|
||||
image: registry.i15.nl/i15/fuzephp:8.1-alpine
|
||||
commands:
|
||||
- docker-php-ext-enable xdebug
|
||||
- vendor/bin/phpunit -c test/phpunit.xml
|
||||
|
||||
- name: coverage
|
||||
image: registry.i15.nl/i15/fuzephp:8.0-alpine
|
||||
commands:
|
||||
- docker-php-ext-enable xdebug
|
||||
- vendor/bin/phpunit -c test/phpunit.xml --coverage-text
|
||||
|
||||
image_pull_secrets:
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: test
|
||||
|
||||
services:
|
||||
- name: cache
|
||||
image: redis
|
||||
|
||||
steps:
|
||||
- name: composer
|
||||
image: composer:latest
|
||||
commands:
|
||||
- composer install
|
||||
|
||||
- name: PHP81CoreTest
|
||||
image: registry.i15.nl/i15/fuzephp:8.1-alpine
|
||||
commands:
|
||||
- docker-php-ext-enable xdebug
|
||||
- vendor/bin/phpunit -c test/phpunit.xml --testsuite core
|
||||
|
||||
- name: PHP81DummyProviderTest
|
||||
image: registry.i15.nl/i15/fuzephp:8.1-alpine
|
||||
commands:
|
||||
- docker-php-ext-enable xdebug
|
||||
- vendor/bin/phpunit -c test/phpunit.xml --testsuite storage
|
||||
environment:
|
||||
STORAGE_PROVIDER: DummyProvider
|
||||
|
||||
- name: PHP81FileProviderTest
|
||||
image: registry.i15.nl/i15/fuzephp:8.1-alpine
|
||||
commands:
|
||||
- docker-php-ext-enable xdebug
|
||||
- vendor/bin/phpunit -c test/phpunit.xml --testsuite storage
|
||||
environment:
|
||||
STORAGE_PROVIDER: FileProvider
|
||||
|
||||
- name: PHP81RedisProviderTest
|
||||
image: registry.i15.nl/i15/fuzephp:8.1-alpine
|
||||
commands:
|
||||
- docker-php-ext-enable xdebug
|
||||
- vendor/bin/phpunit -c test/phpunit.xml --testsuite storage
|
||||
environment:
|
||||
STORAGE_PROVIDER: RedisProvider
|
||||
STORAGE_REDIS_HOST: cache
|
||||
|
||||
- name: coverage
|
||||
image: registry.i15.nl/i15/fuzephp:8.1-alpine
|
||||
commands:
|
||||
- docker-php-ext-enable xdebug
|
||||
- vendor/bin/phpunit -c test/phpunit.xml --testsuite core --coverage-text
|
||||
|
||||
image_pull_secrets:
|
||||
- dockerconfig
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -17,3 +17,4 @@ build/
|
||||
doc
|
||||
nbproject
|
||||
._*
|
||||
*.cache
|
@ -10,7 +10,8 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.4.0"
|
||||
"php": ">=8.1.0",
|
||||
"psr/simple-cache": "1.0.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9",
|
||||
|
60
src/Config/config.storage.php
Normal file
60
src/Config/config.storage.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/**
|
||||
* FuzeWorks ObjectStorage Component.
|
||||
*
|
||||
* The FuzeWorks PHP FrameWork
|
||||
*
|
||||
* Copyright (C) 2013-2020 i15
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @author i15
|
||||
* @copyright Copyright (c) 2013 - 2020, i15. (https://i15.nl)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
*
|
||||
* @since Version 1.3.0
|
||||
*
|
||||
* @version Version 1.3.0
|
||||
*/
|
||||
|
||||
use FuzeWorks\Core;
|
||||
|
||||
return [
|
||||
// Which provider shall be used
|
||||
// Options: DummyProvider, RedisProvider, FileProvider
|
||||
'StorageProvider' => Core::getEnv('STORAGE_PROVIDER', null),
|
||||
'DummyProvider' => [],
|
||||
'RedisProvider' => [
|
||||
// Type can be 'tcp' or 'unix'
|
||||
'socket_type' => Core::getEnv('STORAGE_REDIS_SOCKET_TYPE', 'tcp'),
|
||||
// If socket_type == 'unix', set the socket here
|
||||
'socket' => Core::getEnv('STORAGE_REDIS_SOCKET', null),
|
||||
// If socket_type == 'tcp', set the host here
|
||||
'host' => Core::getEnv('STORAGE_REDIS_HOST', '127.0.0.1'),
|
||||
// And some standard settings
|
||||
'port' => Core::getEnv('STORAGE_REDIS_PORT', 6379),
|
||||
'password' => Core::getEnv('STORAGE_REDIS_PASSWORD', null),
|
||||
'timeout' => Core::getEnv('STORAGE_REDIS_TIMEOUT', 0),
|
||||
'db_index' => Core::getEnv('STORAGE_REDIS_DBINDEX', 0),
|
||||
],
|
||||
'FileProvider' => [
|
||||
// The directory where objects get stored by the FileProvider
|
||||
'storage_directory' => Core::getEnv('STORAGE_FILE_DIRECTORY', Core::$tempDir)
|
||||
]
|
||||
];
|
@ -52,7 +52,7 @@ trait ComponentPathsTrait
|
||||
*
|
||||
* @param array $componentPaths
|
||||
*/
|
||||
public function setDirectories(array $componentPaths)
|
||||
public function setDirectories(array $componentPaths): void
|
||||
{
|
||||
$this->componentPaths = $componentPaths;
|
||||
}
|
||||
@ -63,7 +63,7 @@ trait ComponentPathsTrait
|
||||
* @param string $componentPath
|
||||
* @param int $priority
|
||||
*/
|
||||
public function addComponentPath(string $componentPath, int $priority = Priority::NORMAL)
|
||||
public function addComponentPath(string $componentPath, int $priority = Priority::NORMAL): void
|
||||
{
|
||||
if (!isset($this->componentPaths[$priority]))
|
||||
$this->componentPaths[$priority] = [];
|
||||
@ -78,7 +78,7 @@ trait ComponentPathsTrait
|
||||
* @param string $componentPath
|
||||
* @param int $priority
|
||||
*/
|
||||
public function removeComponentPath(string $componentPath, int $priority = Priority::NORMAL)
|
||||
public function removeComponentPath(string $componentPath, int $priority = Priority::NORMAL): void
|
||||
{
|
||||
if (!isset($this->componentPaths[$priority]))
|
||||
return;
|
||||
|
@ -124,7 +124,7 @@ class Config
|
||||
/**
|
||||
* Clears all the config files and discards all changes not committed
|
||||
*/
|
||||
public function discardConfigFiles()
|
||||
public function discardConfigFiles(): void
|
||||
{
|
||||
$this->cfg = [];
|
||||
}
|
||||
@ -195,7 +195,7 @@ class Config
|
||||
* @param string $configKey
|
||||
* @param $configValue
|
||||
*/
|
||||
public static function overrideConfig(string $configName, string $configKey, $configValue)
|
||||
public static function overrideConfig(string $configName, string $configKey, $configValue): void
|
||||
{
|
||||
// Convert configName
|
||||
$configName = strtolower($configName);
|
||||
|
@ -122,7 +122,7 @@ abstract class ConfigORMAbstract implements Iterator
|
||||
* @return mixed Value of the requested entry
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function get(string $name)
|
||||
public function get(string $name): mixed
|
||||
{
|
||||
return $this->cfg[$name];
|
||||
}
|
||||
@ -134,7 +134,7 @@ abstract class ConfigORMAbstract implements Iterator
|
||||
* @param mixed $value Value of the entry
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __set(string $name, $value)
|
||||
public function __set(string $name, mixed $value)
|
||||
{
|
||||
$this->cfg[$name] = $value;
|
||||
}
|
||||
@ -146,7 +146,7 @@ abstract class ConfigORMAbstract implements Iterator
|
||||
* @param mixed $value Value of the entry
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function set(string $name, $value)
|
||||
public function set(string $name, mixed $value)
|
||||
{
|
||||
$this->cfg[$name] = $value;
|
||||
}
|
||||
@ -154,10 +154,10 @@ abstract class ConfigORMAbstract implements Iterator
|
||||
/**
|
||||
* Unset a value in a config file.
|
||||
*
|
||||
* @param string Key of the entry
|
||||
* @param string $name Key of the entry
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __unset($name)
|
||||
public function __unset(string $name)
|
||||
{
|
||||
unset($this->cfg[$name]);
|
||||
}
|
||||
@ -166,16 +166,16 @@ abstract class ConfigORMAbstract implements Iterator
|
||||
* Iterator method.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function rewind()
|
||||
public function rewind(): void
|
||||
{
|
||||
return reset($this->cfg);
|
||||
reset($this->cfg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator method.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function current()
|
||||
public function current(): mixed
|
||||
{
|
||||
return current($this->cfg);
|
||||
}
|
||||
@ -184,7 +184,7 @@ abstract class ConfigORMAbstract implements Iterator
|
||||
* Iterator method.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function key()
|
||||
public function key(): string|int|null
|
||||
{
|
||||
return key($this->cfg);
|
||||
}
|
||||
@ -193,9 +193,9 @@ abstract class ConfigORMAbstract implements Iterator
|
||||
* Iterator method.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function next()
|
||||
public function next(): void
|
||||
{
|
||||
return next($this->cfg);
|
||||
next($this->cfg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -224,9 +224,9 @@ class Configurator
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @var string Name of the template file
|
||||
* @var string $templateName of the template file
|
||||
*/
|
||||
public static function setLoggerTemplate($templateName)
|
||||
public static function setLoggerTemplate(string $templateName): void
|
||||
{
|
||||
Logger::setLoggerTemplate($templateName);
|
||||
}
|
||||
@ -283,7 +283,7 @@ class Configurator
|
||||
* @return Configurator
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function setDebugAddress($address = 'NONE'): Configurator
|
||||
public function setDebugAddress(string|array $address = 'NONE'): Configurator
|
||||
{
|
||||
// First we fetch the list
|
||||
if (!is_string($address) && !is_array($address))
|
||||
@ -348,7 +348,7 @@ class Configurator
|
||||
// Then load the framework
|
||||
$container = Core::init();
|
||||
Logger::newLevel("Creating container...");
|
||||
if ($debug == true)
|
||||
if ($debug)
|
||||
{
|
||||
define('ENVIRONMENT', 'DEVELOPMENT');
|
||||
Logger::enable();
|
||||
@ -358,7 +358,7 @@ class Configurator
|
||||
|
||||
|
||||
// Load components
|
||||
foreach ($this->components as $componentSuperClass => $component)
|
||||
foreach ($this->components as $component)
|
||||
{
|
||||
Logger::logInfo("Adding Component: '" . $component->getName() . "'");
|
||||
foreach ($component->getClasses() as $componentName => $componentClass)
|
||||
|
@ -118,7 +118,7 @@ class Core
|
||||
register_shutdown_function(array('\FuzeWorks\Core', 'shutdown'));
|
||||
set_error_handler(array('\FuzeWorks\Core', 'errorHandler'), E_ALL);
|
||||
set_exception_handler(array('\FuzeWorks\Core', 'exceptionHandler'));
|
||||
spl_autoload_register(['\FuzeWorks\Core', 'autoloader'], true,false);
|
||||
spl_autoload_register(['\FuzeWorks\Core', 'autoloader']);
|
||||
|
||||
// Return the Factory
|
||||
return new Factory();
|
||||
@ -130,7 +130,7 @@ class Core
|
||||
* Afterwards run the Logger shutdown function in order to possibly display the log
|
||||
* @throws EventException
|
||||
*/
|
||||
public static function shutdown()
|
||||
public static function shutdown(): void
|
||||
{
|
||||
// Fix Apache bug where CWD is changed upon shutdown
|
||||
chdir(self::$cwd);
|
||||
@ -154,9 +154,9 @@ class Core
|
||||
*
|
||||
* @param string $varName
|
||||
* @param string|null $default
|
||||
* @return array|string|null
|
||||
* @return string|null
|
||||
*/
|
||||
public static function getEnv(string $varName, string $default = null)
|
||||
public static function getEnv(string $varName, string $default = null): string|null
|
||||
{
|
||||
// First retrieve the environment variable
|
||||
$var = getenv($varName);
|
||||
@ -172,10 +172,10 @@ class Core
|
||||
/**
|
||||
* Checks whether the current running version of PHP is equal to the input string.
|
||||
*
|
||||
* @param string
|
||||
* @param string $version
|
||||
* @return bool true if running higher than input string
|
||||
*/
|
||||
public static function isPHP($version): bool
|
||||
public static function isPHP(string $version): bool
|
||||
{
|
||||
static $_is_php;
|
||||
$version = (string) $version;
|
||||
@ -188,7 +188,7 @@ class Core
|
||||
return $_is_php[$version];
|
||||
}
|
||||
|
||||
public static function exceptionHandler()
|
||||
public static function exceptionHandler(): void
|
||||
{
|
||||
for ($i = Priority::getHighestPriority(); $i <= Priority::getLowestPriority(); $i++)
|
||||
{
|
||||
@ -200,7 +200,7 @@ class Core
|
||||
}
|
||||
}
|
||||
|
||||
public static function errorHandler()
|
||||
public static function errorHandler(): void
|
||||
{
|
||||
for ($i = Priority::getHighestPriority(); $i <= Priority::getLowestPriority(); $i++)
|
||||
{
|
||||
@ -218,7 +218,7 @@ class Core
|
||||
* @param callable $callback
|
||||
* @param int $priority
|
||||
*/
|
||||
public static function addExceptionHandler(callable $callback, int $priority = Priority::NORMAL)
|
||||
public static function addExceptionHandler(callable $callback, int $priority = Priority::NORMAL): void
|
||||
{
|
||||
if (!isset(self::$exceptionHandlers[$priority]))
|
||||
self::$exceptionHandlers[$priority] = [];
|
||||
@ -233,7 +233,7 @@ class Core
|
||||
* @param callable $callback
|
||||
* @param int $priority
|
||||
*/
|
||||
public static function removeExceptionHandler(callable $callback, int $priority = Priority::NORMAL)
|
||||
public static function removeExceptionHandler(callable $callback, int $priority = Priority::NORMAL): void
|
||||
{
|
||||
if (isset(self::$exceptionHandlers[$priority]) && in_array($callback, self::$exceptionHandlers[$priority]))
|
||||
{
|
||||
@ -249,7 +249,7 @@ class Core
|
||||
* @param callable $callback
|
||||
* @param int $priority
|
||||
*/
|
||||
public static function addErrorHandler(callable $callback, int $priority = Priority::NORMAL)
|
||||
public static function addErrorHandler(callable $callback, int $priority = Priority::NORMAL): void
|
||||
{
|
||||
if (!isset(self::$errorHandlers[$priority]))
|
||||
self::$errorHandlers[$priority] = [];
|
||||
@ -264,7 +264,7 @@ class Core
|
||||
* @param callable $callback
|
||||
* @param int $priority
|
||||
*/
|
||||
public static function removeErrorHandler(callable $callback, int $priority = Priority::NORMAL)
|
||||
public static function removeErrorHandler(callable $callback, int $priority = Priority::NORMAL): void
|
||||
{
|
||||
if (isset(self::$errorHandlers[$priority]) && in_array($callback, self::$errorHandlers[$priority]))
|
||||
{
|
||||
@ -279,7 +279,7 @@ class Core
|
||||
* @param string $filePath
|
||||
* @throws CoreException
|
||||
*/
|
||||
public static function addAutoloadMap(string $nameSpacePrefix, string $filePath)
|
||||
public static function addAutoloadMap(string $nameSpacePrefix, string $filePath): void
|
||||
{
|
||||
// Remove leading slashes
|
||||
$nameSpacePrefix = ltrim($nameSpacePrefix, '\\');
|
||||
@ -293,7 +293,7 @@ class Core
|
||||
self::$autoloadMap[$nameSpacePrefix] = $filePath;
|
||||
}
|
||||
|
||||
public static function autoloader(string $class)
|
||||
public static function autoloader(string $class): void
|
||||
{
|
||||
// Remove leading slashes
|
||||
$class = ltrim($class, '\\');
|
||||
@ -302,7 +302,7 @@ class Core
|
||||
foreach (self::$autoloadMap as $prefix => $path)
|
||||
{
|
||||
// If not, try next
|
||||
if (strpos($class, $prefix) === false)
|
||||
if (!str_contains($class, $prefix))
|
||||
continue;
|
||||
|
||||
// If it contains the prefix, attempt to find the file
|
||||
@ -319,7 +319,7 @@ class Core
|
||||
* Not intended for use by developer. Only for use during testing
|
||||
* @internal
|
||||
*/
|
||||
public static function clearAutoloader()
|
||||
public static function clearAutoloader(): void
|
||||
{
|
||||
self::$autoloadMap = [];
|
||||
}
|
||||
@ -332,16 +332,14 @@ class Core
|
||||
* on Unix servers if safe_mode is on.
|
||||
*
|
||||
* @link https://bugs.php.net/bug.php?id=54709
|
||||
* @param string
|
||||
* @param string $file
|
||||
* @return bool
|
||||
*/
|
||||
public static function isReallyWritable($file): bool
|
||||
public static function isReallyWritable(string $file): bool
|
||||
{
|
||||
// If we're on a Unix server with safe_mode off we call is_writable
|
||||
if (DIRECTORY_SEPARATOR === '/' && ! ini_get('safe_mode'))
|
||||
{
|
||||
return is_writable($file);
|
||||
}
|
||||
|
||||
/* For Windows servers and safe_mode "on" installations we'll actually
|
||||
* write a file then read it. Bah...
|
||||
@ -360,9 +358,7 @@ class Core
|
||||
return TRUE;
|
||||
}
|
||||
elseif ( ! is_file($file) OR ($fp = @fopen($file, 'ab')) === FALSE)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fclose($fp);
|
||||
return TRUE;
|
||||
|
@ -57,7 +57,7 @@ class DeferredComponentClass
|
||||
/**
|
||||
* @var mixed return from the invoked method
|
||||
*/
|
||||
protected $return;
|
||||
protected mixed $return;
|
||||
|
||||
/**
|
||||
* @var bool Whether the method has been invoked
|
||||
@ -82,7 +82,7 @@ class DeferredComponentClass
|
||||
*
|
||||
* @param $result
|
||||
*/
|
||||
public function invoke($result)
|
||||
public function invoke($result): void
|
||||
{
|
||||
$this->return = $result;
|
||||
$this->invoked = true;
|
||||
@ -97,7 +97,7 @@ class DeferredComponentClass
|
||||
|
||||
public function getResult()
|
||||
{
|
||||
if ($this->invoked == true)
|
||||
if ($this->invoked)
|
||||
return $this->return;
|
||||
else
|
||||
return false;
|
||||
|
@ -59,12 +59,11 @@ class Event
|
||||
/**
|
||||
* @param bool $cancelled True if the event is cancelled, false if the event is not cancelled
|
||||
*/
|
||||
public function setCancelled(bool $cancelled)
|
||||
public function setCancelled(bool $cancelled): void
|
||||
{
|
||||
if ($cancelled == true) {
|
||||
if ($cancelled)
|
||||
$this->cancelled = true;
|
||||
} else {
|
||||
else
|
||||
$this->cancelled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -66,14 +66,14 @@ class Events
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static array $listeners = array();
|
||||
public static array $listeners = [];
|
||||
|
||||
/**
|
||||
* Whether the event system is enabled or not.
|
||||
*
|
||||
* @var array
|
||||
* @var bool
|
||||
*/
|
||||
private static $enabled = true;
|
||||
private static bool $enabled = true;
|
||||
|
||||
/**
|
||||
* Adds a function as listener.
|
||||
@ -87,33 +87,25 @@ class Events
|
||||
*
|
||||
* @throws EventException
|
||||
*/
|
||||
public static function addListener(callable $callback, string $eventName, int $priority = Priority::NORMAL)
|
||||
public static function addListener(callable $callback, string $eventName, int $priority = Priority::NORMAL): void
|
||||
{
|
||||
// Perform multiple checks
|
||||
if (Priority::getPriority($priority) == false) {
|
||||
if (!Priority::getPriority($priority))
|
||||
throw new EventException('Can not add listener: Unknown priority '.$priority, 1);
|
||||
}
|
||||
|
||||
if (empty($eventName))
|
||||
{
|
||||
throw new EventException("Can not add listener: No eventname provided", 1);
|
||||
}
|
||||
throw new EventException("Can not add listener: No event name provided", 1);
|
||||
|
||||
if (!isset(self::$listeners[$eventName])) {
|
||||
if (!isset(self::$listeners[$eventName]))
|
||||
self::$listeners[$eventName] = array();
|
||||
}
|
||||
|
||||
if (!isset(self::$listeners[$eventName][$priority])) {
|
||||
if (!isset(self::$listeners[$eventName][$priority]))
|
||||
self::$listeners[$eventName][$priority] = array();
|
||||
}
|
||||
|
||||
if (func_num_args() > 3) {
|
||||
if (func_num_args() > 3)
|
||||
$args = array_slice(func_get_args(), 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
$args = array();
|
||||
}
|
||||
|
||||
self::$listeners[$eventName][$priority][] = array($callback, $args);
|
||||
}
|
||||
@ -121,7 +113,7 @@ class Events
|
||||
/**
|
||||
* Removes a function as listener.
|
||||
*
|
||||
* @param mixed callback The callback when the events get fired, see {@link http://php.net/manual/en/language.types.callable.php PHP.net}
|
||||
* @param callable $callback The callback when the events get fired, see {@link http://php.net/manual/en/language.types.callable.php PHP.net}
|
||||
* @param string $eventName The name of the event
|
||||
* @param int $priority The priority, even though integers are valid, please use Priority (for example Priority::Lowest)
|
||||
*
|
||||
@ -129,15 +121,13 @@ class Events
|
||||
*
|
||||
* @throws EventException
|
||||
*/
|
||||
public static function removeListener(callable $callback, string $eventName, int $priority = Priority::NORMAL)
|
||||
public static function removeListener(callable $callback, string $eventName, int $priority = Priority::NORMAL): void
|
||||
{
|
||||
if (Priority::getPriority($priority) == false) {
|
||||
if (!Priority::getPriority($priority))
|
||||
throw new EventException('Unknown priority '.$priority);
|
||||
}
|
||||
|
||||
if (!isset(self::$listeners[$eventName]) || !isset(self::$listeners[$eventName][$priority])) {
|
||||
if (!isset(self::$listeners[$eventName]) || !isset(self::$listeners[$eventName][$priority]))
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (self::$listeners[$eventName][$priority] as $i => $_callback) {
|
||||
if ($_callback[0] == $callback) {
|
||||
@ -159,7 +149,7 @@ class Events
|
||||
* @return Event The Event
|
||||
* @throws EventException
|
||||
*/
|
||||
public static function fireEvent($input): Event
|
||||
public static function fireEvent(mixed $input): Event
|
||||
{
|
||||
// First try and see if the object is an Event
|
||||
if (is_object($input))
|
||||
@ -176,13 +166,11 @@ class Events
|
||||
$eventName = $input;
|
||||
|
||||
// Try a direct class
|
||||
if (class_exists($eventClass, true))
|
||||
{
|
||||
if (class_exists($eventClass))
|
||||
$event = new $eventClass();
|
||||
}
|
||||
|
||||
// Try a core event
|
||||
elseif (class_exists("\FuzeWorks\Event\\".$eventClass, true))
|
||||
elseif (class_exists("\FuzeWorks\Event\\".$eventClass))
|
||||
{
|
||||
$class = "\FuzeWorks\Event\\".$eventClass;
|
||||
$event = new $class();
|
||||
@ -190,29 +178,23 @@ class Events
|
||||
|
||||
// Try a notifier event
|
||||
elseif (func_num_args() == 1)
|
||||
{
|
||||
$event = new NotifierEvent();
|
||||
}
|
||||
|
||||
// Or throw an exception on failure
|
||||
else
|
||||
{
|
||||
throw new EventException('Event '.$eventName.' could not be found!', 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new EventException('Event could not be loaded. Invalid variable provided.', 1);
|
||||
}
|
||||
|
||||
if (func_num_args() > 1) {
|
||||
if (func_num_args() > 1)
|
||||
call_user_func_array(array($event, 'init'), array_slice(func_get_args(), 1));
|
||||
}
|
||||
|
||||
// Do not run if the event system is disabled
|
||||
if (!self::$enabled) {
|
||||
if (!self::$enabled)
|
||||
return $event;
|
||||
}
|
||||
|
||||
//There are listeners for this event
|
||||
if (isset(self::$listeners[$eventName])) {
|
||||
@ -257,7 +239,7 @@ class Events
|
||||
/**
|
||||
* Enables the event system.
|
||||
*/
|
||||
public static function enable()
|
||||
public static function enable(): void
|
||||
{
|
||||
Logger::log('Enabled the Event system');
|
||||
self::$enabled = true;
|
||||
@ -266,7 +248,7 @@ class Events
|
||||
/**
|
||||
* Disables the event system.
|
||||
*/
|
||||
public static function disable()
|
||||
public static function disable(): void
|
||||
{
|
||||
Logger::log('Disabled the Event system');
|
||||
self::$enabled = false;
|
||||
|
40
src/FuzeWorks/Exception/StorageException.php
Normal file
40
src/FuzeWorks/Exception/StorageException.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/**
|
||||
* FuzeWorks ObjectStorage Component.
|
||||
*
|
||||
* The FuzeWorks PHP FrameWork
|
||||
*
|
||||
* Copyright (C) 2013-2020 i15
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @author i15
|
||||
* @copyright Copyright (c) 2013 - 2020, i15. (https://i15.nl)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
*
|
||||
* @since Version 1.3.0
|
||||
*
|
||||
* @version Version 1.3.0
|
||||
*/
|
||||
|
||||
namespace FuzeWorks\Exception;
|
||||
|
||||
class StorageException extends CoreException
|
||||
{
|
||||
}
|
@ -1,334 +1,342 @@
|
||||
<?php
|
||||
/**
|
||||
* FuzeWorks Framework Core.
|
||||
*
|
||||
* The FuzeWorks PHP FrameWork
|
||||
*
|
||||
* Copyright (C) 2013-2019 TechFuze
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @author TechFuze
|
||||
* @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
*
|
||||
* @link http://techfuze.net/fuzeworks
|
||||
* @since Version 0.0.1
|
||||
*
|
||||
* @version Version 1.3.0
|
||||
*/
|
||||
|
||||
namespace FuzeWorks;
|
||||
use FuzeWorks\Exception\ConfigException;
|
||||
use FuzeWorks\Exception\CoreException;
|
||||
use FuzeWorks\Exception\EventException;
|
||||
use FuzeWorks\Exception\FactoryException;
|
||||
|
||||
/**
|
||||
* Factory Class.
|
||||
*
|
||||
* The Factory class is the central point for class communication in FuzeWorks.
|
||||
* When someone needs to load, for instance, the layout class, one has to do the following:
|
||||
* $factory = Factory::getInstance();
|
||||
* $layout = $factory->layout;
|
||||
*
|
||||
* The Factory class allows the user to replace dependencies on the fly. It is possible for a class
|
||||
* to replace a dependency, like Logger, on the fly by calling the $factory->newInstance('Logger'); or the
|
||||
* $factory->setInstance('Logger', $object); This allows for creative ways to do dependency injection, or keep classes
|
||||
* separated.
|
||||
*
|
||||
* It is also possible to load a cloned instance of the Factory class, so that all properties are independant as well,
|
||||
* all to suit your very needs.
|
||||
*
|
||||
* The Factory class is also extendible. This allows classes that extend Factory to access all it's properties.
|
||||
*
|
||||
* @author TechFuze <contact@techfuze.net>
|
||||
* @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net)
|
||||
*/
|
||||
class Factory
|
||||
{
|
||||
|
||||
/**
|
||||
* The Factory instance that is shared by default when calling Factory::getInstance();
|
||||
*
|
||||
* @var Factory|null Default shared instance
|
||||
*/
|
||||
private static ?Factory $sharedFactoryInstance = null;
|
||||
|
||||
/**
|
||||
* Whether the Factory has been initialized or not
|
||||
*
|
||||
* @var bool $initialized
|
||||
*/
|
||||
private bool $initialized = false;
|
||||
|
||||
/**
|
||||
* Config Object
|
||||
* @var Config
|
||||
*/
|
||||
public Config $config;
|
||||
|
||||
/**
|
||||
* Logger Object
|
||||
* @var Logger
|
||||
*/
|
||||
public Logger $logger;
|
||||
|
||||
/**
|
||||
* Events Object
|
||||
* @var Events
|
||||
*/
|
||||
public Events $events;
|
||||
|
||||
/**
|
||||
* Libraries Object
|
||||
* @var Libraries
|
||||
*/
|
||||
public Libraries $libraries;
|
||||
|
||||
/**
|
||||
* Helpers Object
|
||||
* @var Helpers
|
||||
*/
|
||||
public Helpers $helpers;
|
||||
|
||||
/**
|
||||
* Plugins Object
|
||||
* @var Plugins
|
||||
*/
|
||||
public Plugins $plugins;
|
||||
|
||||
/**
|
||||
* Factory instance constructor. Should only really be called once
|
||||
* @throws FactoryException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// If there is no sharedFactoryInstance, prepare it
|
||||
if (is_null(self::$sharedFactoryInstance))
|
||||
{
|
||||
// @codeCoverageIgnoreStart
|
||||
self::$sharedFactoryInstance = $this;
|
||||
$this->config = new Config();
|
||||
$this->logger = new Logger();
|
||||
$this->events = new Events();
|
||||
$this->libraries = new Libraries();
|
||||
$this->helpers = new Helpers();
|
||||
$this->plugins = new Plugins();
|
||||
|
||||
return;
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
// Otherwise, copy the existing instances
|
||||
$x = self::getInstance();
|
||||
foreach ($x as $key => $value)
|
||||
$this->{$key} = $value;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalizes the Factory and sends out a coreStartEvent
|
||||
*
|
||||
* @return Factory
|
||||
* @throws CoreException
|
||||
*/
|
||||
public function initFactory(): Factory
|
||||
{
|
||||
// If already initialized, cancel
|
||||
if ($this->initialized)
|
||||
return $this;
|
||||
|
||||
// Load the config file of the FuzeWorks core
|
||||
try {
|
||||
$cfg = $this->config->get('core');
|
||||
} catch (ConfigException $e) {
|
||||
throw new CoreException("Could not initiate Factory. Config 'core' could not be found.");
|
||||
}
|
||||
|
||||
// Disable events if requested to do so
|
||||
if (!$cfg->get('enable_events'))
|
||||
Events::disable();
|
||||
|
||||
// Initialize all components
|
||||
foreach ($this as $component)
|
||||
{
|
||||
if (!is_object($component))
|
||||
continue;
|
||||
|
||||
if (method_exists($component, 'init'))
|
||||
$component->init();
|
||||
}
|
||||
|
||||
// Initialize all plugins
|
||||
$this->plugins->loadHeadersFromPluginPaths();
|
||||
|
||||
// Log actions
|
||||
Logger::logInfo("FuzeWorks initialized. Firing coreStartEvent.");
|
||||
|
||||
// And fire the coreStartEvent
|
||||
try {
|
||||
Events::fireEvent('coreStartEvent');
|
||||
} catch (EventException $e) {
|
||||
throw new CoreException("Could not initiate Factory. coreStartEvent threw exception: ".$e->getMessage());
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of a componentClass.
|
||||
*
|
||||
* @param string|null $instanceName
|
||||
* @return mixed
|
||||
* @throws FactoryException
|
||||
*/
|
||||
public static function getInstance(string $instanceName = null)
|
||||
{
|
||||
if (is_null($instanceName))
|
||||
return self::$sharedFactoryInstance;
|
||||
|
||||
// Determine the instance name
|
||||
$instanceName = strtolower($instanceName);
|
||||
|
||||
if (!isset(self::$sharedFactoryInstance->{$instanceName}))
|
||||
throw new FactoryException("Could not get instance. Instance was not found.");
|
||||
|
||||
return self::$sharedFactoryInstance->{$instanceName};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of one of the loaded classes.
|
||||
* It reloads the class. It does NOT clone it.
|
||||
*
|
||||
* @param string $className The name of the loaded class, WITHOUT the namespace
|
||||
* @param string $namespace Optional namespace. Defaults to 'FuzeWorks\'
|
||||
* @return Factory Instance
|
||||
* @throws FactoryException
|
||||
*/
|
||||
public function newInstance(string $className, string $namespace = 'FuzeWorks\\'): self
|
||||
{
|
||||
// Determine the class to load
|
||||
$instanceName = strtolower($className);
|
||||
$className = $namespace.ucfirst($className);
|
||||
|
||||
if (!isset($this->{$instanceName}))
|
||||
{
|
||||
throw new FactoryException("Could not load new instance of '".$instanceName."'. Instance was not found.", 1);
|
||||
}
|
||||
elseif (!class_exists($className, false))
|
||||
{
|
||||
throw new FactoryException("Could not load new instance of '".$instanceName."'. Class not found.", 1);
|
||||
}
|
||||
|
||||
// Remove the current instance
|
||||
unset($this->{$instanceName});
|
||||
|
||||
// And set the new one
|
||||
$this->{$instanceName} = new $className();
|
||||
|
||||
// Return itself
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone an instance of one of the loaded classes.
|
||||
* It clones the class. It does NOT re-create it.
|
||||
*
|
||||
* If the $onlyReturn = true is provided, the cloned instance will only be returned, and not set to the factory.
|
||||
*
|
||||
* @param string $className The name of the loaded class, WITHOUT the namespace
|
||||
* @param bool $onlyReturn
|
||||
* @return mixed
|
||||
* @throws FactoryException
|
||||
*/
|
||||
public static function cloneInstance(string $className, bool $onlyReturn = false)
|
||||
{
|
||||
// Determine the class to load
|
||||
$instanceName = strtolower($className);
|
||||
|
||||
if (!isset(self::$sharedFactoryInstance->{$instanceName}))
|
||||
throw new FactoryException("Could not clone instance of '".$instanceName."'. Instance was not found.", 1);
|
||||
|
||||
if ($onlyReturn)
|
||||
return clone self::$sharedFactoryInstance->{$instanceName};
|
||||
|
||||
// Clone the instance
|
||||
self::$sharedFactoryInstance->{$instanceName} = clone self::$sharedFactoryInstance->{$instanceName};
|
||||
|
||||
// Return itself
|
||||
return self::$sharedFactoryInstance->{$instanceName};
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an instance of one of the loaded classes with your own $object.
|
||||
* Replace the existing class with one of your own.
|
||||
*
|
||||
* @param string $objectName The name of the loaded class, WITHOUT the namespace
|
||||
* @param mixed $object Object to replace the class with
|
||||
* @return Factory Instance
|
||||
*/
|
||||
public function setInstance(string $objectName, $object): self
|
||||
{
|
||||
// Determine the instance name
|
||||
$instanceName = strtolower($objectName);
|
||||
|
||||
// Unset and set
|
||||
unset($this->{$instanceName});
|
||||
$this->{$instanceName} = $object;
|
||||
|
||||
// Return itself
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an instance of one of the loaded classes.
|
||||
*
|
||||
* @param string $className The name of the loaded class, WITHOUT the namespace
|
||||
* @return Factory Factory Instance
|
||||
* @throws FactoryException
|
||||
*/
|
||||
public function removeInstance(string $className): self
|
||||
{
|
||||
// Determine the instance name
|
||||
$instanceName = strtolower($className);
|
||||
|
||||
if (!isset($this->{$instanceName}))
|
||||
{
|
||||
throw new FactoryException("Could not remove instance of '".$instanceName."'. Instance was not found.", 1);
|
||||
}
|
||||
|
||||
// Unset
|
||||
unset($this->{$instanceName});
|
||||
|
||||
// Return itself
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if component is part of this Factory.
|
||||
*
|
||||
* @param $componentName
|
||||
* @return bool
|
||||
*/
|
||||
public function instanceIsset($componentName): bool
|
||||
{
|
||||
return isset($this->{$componentName});
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* FuzeWorks Framework Core.
|
||||
*
|
||||
* The FuzeWorks PHP FrameWork
|
||||
*
|
||||
* Copyright (C) 2013-2019 TechFuze
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @author TechFuze
|
||||
* @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
*
|
||||
* @link http://techfuze.net/fuzeworks
|
||||
* @since Version 0.0.1
|
||||
*
|
||||
* @version Version 1.3.0
|
||||
*/
|
||||
|
||||
namespace FuzeWorks;
|
||||
use FuzeWorks\Exception\ConfigException;
|
||||
use FuzeWorks\Exception\CoreException;
|
||||
use FuzeWorks\Exception\EventException;
|
||||
use FuzeWorks\Exception\FactoryException;
|
||||
|
||||
/**
|
||||
* Factory Class.
|
||||
*
|
||||
* The Factory class is the central point for class communication in FuzeWorks.
|
||||
* When someone needs to load, for instance, the layout class, one has to do the following:
|
||||
* $factory = Factory::getInstance();
|
||||
* $layout = $factory->layout;
|
||||
*
|
||||
* The Factory class allows the user to replace dependencies on the fly. It is possible for a class
|
||||
* to replace a dependency, like Logger, on the fly by calling the $factory->newInstance('Logger'); or the
|
||||
* $factory->setInstance('Logger', $object); This allows for creative ways to do dependency injection, or keep classes
|
||||
* separated.
|
||||
*
|
||||
* It is also possible to load a cloned instance of the Factory class, so that all properties are independant as well,
|
||||
* all to suit your very needs.
|
||||
*
|
||||
* The Factory class is also extendible. This allows classes that extend Factory to access all it's properties.
|
||||
*
|
||||
* @author TechFuze <contact@techfuze.net>
|
||||
* @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net)
|
||||
*/
|
||||
class Factory
|
||||
{
|
||||
|
||||
/**
|
||||
* The Factory instance that is shared by default when calling Factory::getInstance();
|
||||
*
|
||||
* @var Factory|null Default shared instance
|
||||
*/
|
||||
private static ?Factory $sharedFactoryInstance = null;
|
||||
|
||||
/**
|
||||
* Whether the Factory has been initialized or not
|
||||
*
|
||||
* @var bool $initialized
|
||||
*/
|
||||
private bool $initialized = false;
|
||||
|
||||
/**
|
||||
* Config Object
|
||||
* @var Config
|
||||
*/
|
||||
public Config $config;
|
||||
|
||||
/**
|
||||
* Logger Object
|
||||
* @var Logger
|
||||
*/
|
||||
public Logger $logger;
|
||||
|
||||
/**
|
||||
* Events Object
|
||||
* @var Events
|
||||
*/
|
||||
public Events $events;
|
||||
|
||||
/**
|
||||
* Libraries Object
|
||||
* @var Libraries
|
||||
*/
|
||||
public Libraries $libraries;
|
||||
|
||||
/**
|
||||
* Helpers Object
|
||||
* @var Helpers
|
||||
*/
|
||||
public Helpers $helpers;
|
||||
|
||||
/**
|
||||
* Plugins Object
|
||||
* @var Plugins
|
||||
*/
|
||||
public Plugins $plugins;
|
||||
|
||||
/**
|
||||
* Storage Object
|
||||
*
|
||||
* @var Storage
|
||||
*/
|
||||
public Storage $storage;
|
||||
|
||||
/**
|
||||
* Factory instance constructor. Should only really be called once
|
||||
* @throws FactoryException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// If there is no sharedFactoryInstance, prepare it
|
||||
if (is_null(self::$sharedFactoryInstance))
|
||||
{
|
||||
// @codeCoverageIgnoreStart
|
||||
self::$sharedFactoryInstance = $this;
|
||||
$this->config = new Config();
|
||||
$this->logger = new Logger();
|
||||
$this->events = new Events();
|
||||
$this->libraries = new Libraries();
|
||||
$this->helpers = new Helpers();
|
||||
$this->plugins = new Plugins();
|
||||
$this->storage = new Storage();
|
||||
|
||||
return;
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
// Otherwise, copy the existing instances
|
||||
$x = self::getInstance();
|
||||
foreach ($x as $key => $value)
|
||||
$this->{$key} = $value;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalizes the Factory and sends out a coreStartEvent
|
||||
*
|
||||
* @return Factory
|
||||
* @throws CoreException
|
||||
*/
|
||||
public function initFactory(): Factory
|
||||
{
|
||||
// If already initialized, cancel
|
||||
if ($this->initialized)
|
||||
return $this;
|
||||
|
||||
// Load the config file of the FuzeWorks core
|
||||
try {
|
||||
$cfg = $this->config->get('core');
|
||||
} catch (ConfigException) {
|
||||
throw new CoreException("Could not initiate Factory. Config 'core' could not be found.");
|
||||
}
|
||||
|
||||
// Disable events if requested to do so
|
||||
if (!$cfg->get('enable_events'))
|
||||
Events::disable();
|
||||
|
||||
// Initialize all components
|
||||
foreach ($this as $component)
|
||||
{
|
||||
if (!is_object($component))
|
||||
continue;
|
||||
|
||||
if (method_exists($component, 'init'))
|
||||
$component->init();
|
||||
}
|
||||
|
||||
// Initialize all plugins
|
||||
$this->plugins->loadHeadersFromPluginPaths();
|
||||
|
||||
// Log actions
|
||||
Logger::logInfo("FuzeWorks initialized. Firing coreStartEvent.");
|
||||
|
||||
// And fire the coreStartEvent
|
||||
try {
|
||||
Events::fireEvent('coreStartEvent');
|
||||
} catch (EventException $e) {
|
||||
throw new CoreException("Could not initiate Factory. coreStartEvent threw exception: ".$e->getMessage());
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of a componentClass.
|
||||
*
|
||||
* @param string|null $instanceName
|
||||
* @return mixed
|
||||
* @throws FactoryException
|
||||
*/
|
||||
public static function getInstance(string $instanceName = null): mixed
|
||||
{
|
||||
if (is_null($instanceName))
|
||||
return self::$sharedFactoryInstance;
|
||||
|
||||
// Determine the instance name
|
||||
$instanceName = strtolower($instanceName);
|
||||
|
||||
if (!isset(self::$sharedFactoryInstance->{$instanceName}))
|
||||
throw new FactoryException("Could not get instance. Instance was not found.");
|
||||
|
||||
return self::$sharedFactoryInstance->{$instanceName};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of one of the loaded classes.
|
||||
* It reloads the class. It does NOT clone it.
|
||||
*
|
||||
* @param string $className The name of the loaded class, WITHOUT the namespace
|
||||
* @param string $namespace Optional namespace. Defaults to 'FuzeWorks\'
|
||||
* @return Factory Instance
|
||||
* @throws FactoryException
|
||||
*/
|
||||
public function newInstance(string $className, string $namespace = 'FuzeWorks\\'): self
|
||||
{
|
||||
// Determine the class to load
|
||||
$instanceName = strtolower($className);
|
||||
$className = $namespace.ucfirst($className);
|
||||
|
||||
if (!isset($this->{$instanceName}))
|
||||
{
|
||||
throw new FactoryException("Could not load new instance of '".$instanceName."'. Instance was not found.", 1);
|
||||
}
|
||||
elseif (!class_exists($className, false))
|
||||
{
|
||||
throw new FactoryException("Could not load new instance of '".$instanceName."'. Class not found.", 1);
|
||||
}
|
||||
|
||||
// Remove the current instance
|
||||
unset($this->{$instanceName});
|
||||
|
||||
// And set the new one
|
||||
$this->{$instanceName} = new $className();
|
||||
|
||||
// Return itself
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone an instance of one of the loaded classes.
|
||||
* It clones the class. It does NOT re-create it.
|
||||
*
|
||||
* If the $onlyReturn = true is provided, the cloned instance will only be returned, and not set to the factory.
|
||||
*
|
||||
* @param string $className The name of the loaded class, WITHOUT the namespace
|
||||
* @param bool $onlyReturn
|
||||
* @return mixed
|
||||
* @throws FactoryException
|
||||
*/
|
||||
public static function cloneInstance(string $className, bool $onlyReturn = false): mixed
|
||||
{
|
||||
// Determine the class to load
|
||||
$instanceName = strtolower($className);
|
||||
|
||||
if (!isset(self::$sharedFactoryInstance->{$instanceName}))
|
||||
throw new FactoryException("Could not clone instance of '".$instanceName."'. Instance was not found.", 1);
|
||||
|
||||
if ($onlyReturn)
|
||||
return clone self::$sharedFactoryInstance->{$instanceName};
|
||||
|
||||
// Clone the instance
|
||||
self::$sharedFactoryInstance->{$instanceName} = clone self::$sharedFactoryInstance->{$instanceName};
|
||||
|
||||
// Return itself
|
||||
return self::$sharedFactoryInstance->{$instanceName};
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an instance of one of the loaded classes with your own $object.
|
||||
* Replace the existing class with one of your own.
|
||||
*
|
||||
* @param string $objectName The name of the loaded class, WITHOUT the namespace
|
||||
* @param mixed $object Object to replace the class with
|
||||
* @return Factory Instance
|
||||
*/
|
||||
public function setInstance(string $objectName, mixed $object): self
|
||||
{
|
||||
// Determine the instance name
|
||||
$instanceName = strtolower($objectName);
|
||||
|
||||
// Unset and set
|
||||
unset($this->{$instanceName});
|
||||
$this->{$instanceName} = $object;
|
||||
|
||||
// Return itself
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an instance of one of the loaded classes.
|
||||
*
|
||||
* @param string $className The name of the loaded class, WITHOUT the namespace
|
||||
* @return Factory Factory Instance
|
||||
* @throws FactoryException
|
||||
*/
|
||||
public function removeInstance(string $className): self
|
||||
{
|
||||
// Determine the instance name
|
||||
$instanceName = strtolower($className);
|
||||
|
||||
if (!isset($this->{$instanceName}))
|
||||
{
|
||||
throw new FactoryException("Could not remove instance of '".$instanceName."'. Instance was not found.", 1);
|
||||
}
|
||||
|
||||
// Unset
|
||||
unset($this->{$instanceName});
|
||||
|
||||
// Return itself
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if component is part of this Factory.
|
||||
*
|
||||
* @param $componentName
|
||||
* @return bool
|
||||
*/
|
||||
public function instanceIsset($componentName): bool
|
||||
{
|
||||
return isset($this->{$componentName});
|
||||
}
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ class Libraries
|
||||
*
|
||||
* @var Factory
|
||||
*/
|
||||
protected $factory;
|
||||
protected Factory $factory;
|
||||
|
||||
/**
|
||||
* Libraries constructor.
|
||||
@ -80,9 +80,9 @@ class Libraries
|
||||
* Add a library to FuzeWorks by adding an object.
|
||||
*
|
||||
* @param string $libraryName
|
||||
* @param object $libraryObject
|
||||
* @param iLibrary $libraryObject
|
||||
*/
|
||||
public function addLibraryObject(string $libraryName, object $libraryObject)
|
||||
public function addLibraryObject(string $libraryName, iLibrary $libraryObject): void
|
||||
{
|
||||
$this->libraryObjects[strtolower($libraryName)] = $libraryObject;
|
||||
}
|
||||
@ -94,9 +94,9 @@ class Libraries
|
||||
* @param string $libraryClass
|
||||
* @throws LibraryException
|
||||
*/
|
||||
public function addLibraryClass(string $libraryName, string $libraryClass)
|
||||
public function addLibraryClass(string $libraryName, string $libraryClass): void
|
||||
{
|
||||
if (!class_exists($libraryClass, true))
|
||||
if (!class_exists($libraryClass))
|
||||
throw new LibraryException("Could not add library class. '" . $libraryClass . "' could not be loaded.", 1);
|
||||
|
||||
$this->libraryClasses[strtolower($libraryName)] = $libraryClass;
|
||||
@ -114,10 +114,10 @@ class Libraries
|
||||
* @param string $libraryName
|
||||
* @param array $parameters
|
||||
* @param array $libraryPaths
|
||||
* @return object
|
||||
* @return iLibrary
|
||||
* @throws LibraryException
|
||||
*/
|
||||
public function get(string $libraryName, array $parameters = [], array $libraryPaths = [])
|
||||
public function get(string $libraryName, array $parameters = [], array $libraryPaths = []): iLibrary
|
||||
{
|
||||
// Test for empty string
|
||||
if (empty($libraryName))
|
||||
@ -178,12 +178,12 @@ class Libraries
|
||||
* @param string $libraryClass
|
||||
* @param array $parameters
|
||||
* @throws LibraryException
|
||||
* @return object
|
||||
* @return iLibrary
|
||||
*/
|
||||
protected function initLibrary(string $libraryName, string $libraryClass, array $parameters = [])
|
||||
protected function initLibrary(string $libraryName, string $libraryClass, array $parameters = []): iLibrary
|
||||
{
|
||||
// First check to see if the library is already loaded
|
||||
if (!class_exists($libraryClass, true))
|
||||
if (!class_exists($libraryClass))
|
||||
throw new LibraryException("Could not initiate library. Class not found", 1);
|
||||
|
||||
// Determine what parameters to use
|
||||
@ -191,7 +191,7 @@ class Libraries
|
||||
{
|
||||
try {
|
||||
$parameters = $this->factory->config->getConfig(strtolower($libraryName))->toArray();
|
||||
} catch (ConfigException $e) {
|
||||
} catch (ConfigException) {
|
||||
// No problem, just use an empty array instead
|
||||
$parameters = array();
|
||||
}
|
||||
@ -210,9 +210,9 @@ class Libraries
|
||||
$headerReflection = new ReflectionClass(get_class($classObject));
|
||||
$filePath = dirname($headerReflection->getFileName()) . (!is_null($classObject->getSourceDirectory()) ? DS . $classObject->getSourceDirectory() : '' );
|
||||
$prefix = $classObject->getClassesPrefix();
|
||||
if (!is_null($filePath) && !is_null($prefix))
|
||||
if (!is_null($prefix))
|
||||
Core::addAutoloadMap($prefix, $filePath);
|
||||
} catch (CoreException $e) {
|
||||
} catch (CoreException) {
|
||||
throw new LibraryException("Could not initiate library. Failed to add to autoloader.");
|
||||
}
|
||||
|
||||
|
@ -68,25 +68,25 @@ class Logger {
|
||||
private static bool $print_to_screen = false;
|
||||
|
||||
/**
|
||||
* Whether the Logger has been enabled or not
|
||||
* Whether currently the error and exception handlers are enabled or not.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private static bool $isEnabled = false;
|
||||
private static bool $handlers_enabled = false;
|
||||
|
||||
/**
|
||||
* whether to output the log of the last entire request to a file after FuzeWorks has run.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private static $log_last_request = false;
|
||||
private static bool $log_last_request = false;
|
||||
|
||||
/**
|
||||
* Whether to output the log of all errors to a file after FuzeWorks has run
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private static $log_errors_to_file = false;
|
||||
private static bool $log_errors_to_file = false;
|
||||
|
||||
/**
|
||||
* The template to use when parsing the debug log
|
||||
@ -102,13 +102,6 @@ class Logger {
|
||||
*/
|
||||
public static bool $debug = false;
|
||||
|
||||
/**
|
||||
* List of all benchmark markpoints.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static array $markPoints = [];
|
||||
|
||||
/**
|
||||
* Initiates the Logger.
|
||||
*
|
||||
@ -122,10 +115,8 @@ class Logger {
|
||||
|
||||
// Register the error handler, Untestable
|
||||
// @codeCoverageIgnoreStart
|
||||
if ($cfg_error->get('fuzeworks_error_reporting') == true)
|
||||
{
|
||||
if ($cfg_error->get('fuzeworks_error_reporting'))
|
||||
self::enableHandlers();
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
// Set PHP error reporting
|
||||
@ -143,17 +134,17 @@ class Logger {
|
||||
/**
|
||||
* Enable error to screen logging.
|
||||
*/
|
||||
public static function enable()
|
||||
public static function enable(): void
|
||||
{
|
||||
self::$isEnabled = true;
|
||||
self::$print_to_screen = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable error to screen logging.
|
||||
*/
|
||||
public static function disable()
|
||||
public static function disable(): void
|
||||
{
|
||||
self::$isEnabled = false;
|
||||
self::$print_to_screen = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -161,24 +152,7 @@ class Logger {
|
||||
*/
|
||||
public static function isEnabled(): bool
|
||||
{
|
||||
return self::$isEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable outputting the debugger after the request has been processed
|
||||
*/
|
||||
public static function enableScreenLog()
|
||||
{
|
||||
if (!Core::isProduction())
|
||||
self::$print_to_screen = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable outputting the debugger after the request has been processed
|
||||
*/
|
||||
public static function disableScreenLog()
|
||||
{
|
||||
self::$print_to_screen = false;
|
||||
return self::$print_to_screen;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -187,8 +161,9 @@ class Logger {
|
||||
* Registers errorHandler() and exceptionHandler() as the respective handlers for PHP
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function enableHandlers()
|
||||
public static function enableHandlers(): void
|
||||
{
|
||||
self::$handlers_enabled = true;
|
||||
Core::addErrorHandler(['\FuzeWorks\Logger', 'errorHandler']);
|
||||
Core::addExceptionHandler(['\FuzeWorks\Logger', 'exceptionHandler']);
|
||||
}
|
||||
@ -199,8 +174,9 @@ class Logger {
|
||||
* Unregisters errorHandler() and exceptionHandler() as the respective handlers for PHP
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function disableHandlers()
|
||||
public static function disableHandlers(): void
|
||||
{
|
||||
self::$handlers_enabled = false;
|
||||
Core::removeErrorHandler(['\FuzeWorks\Logger', 'errorHandler']);
|
||||
Core::removeExceptionHandler(['\FuzeWorks\Logger', 'exceptionHandler']);
|
||||
}
|
||||
@ -213,7 +189,7 @@ class Logger {
|
||||
* Logs data to screen when requested to do so
|
||||
* @throws EventException
|
||||
*/
|
||||
public static function shutdown()
|
||||
public static function shutdown(): void
|
||||
{
|
||||
// And finally stop the Logging
|
||||
self::stopLevel();
|
||||
@ -223,10 +199,10 @@ class Logger {
|
||||
self::logToScreen();
|
||||
}
|
||||
|
||||
if (self::$log_last_request == true)
|
||||
if (self::$log_last_request)
|
||||
self::logLastRequest();
|
||||
|
||||
if (self::$log_errors_to_file == true)
|
||||
if (self::$log_errors_to_file)
|
||||
self::logErrorsToFile();
|
||||
}
|
||||
|
||||
@ -237,13 +213,13 @@ class Logger {
|
||||
*
|
||||
* Logs a fatal error and outputs the log when configured or requested to do so
|
||||
*/
|
||||
public static function shutdownError()
|
||||
public static function shutdownError(): void
|
||||
{
|
||||
$error = error_get_last();
|
||||
if ($error !== null) {
|
||||
if ($error !== null && self::$handlers_enabled) {
|
||||
// Log it!
|
||||
$thisType = self::getType($error['type']);
|
||||
$LOG = array('type' => (!is_null($thisType) ? $thisType : 'ERROR'),
|
||||
$LOG = array('type' => $thisType,
|
||||
'message' => $error['message'],
|
||||
'logFile' => $error['file'],
|
||||
'logLine' => $error['line'],
|
||||
@ -251,9 +227,7 @@ class Logger {
|
||||
self::$logs[] = $LOG;
|
||||
|
||||
if ($thisType == 'ERROR')
|
||||
{
|
||||
self::haltExecution($LOG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -261,20 +235,19 @@ class Logger {
|
||||
* System that redirects the errors to the appropriate logging method.
|
||||
*
|
||||
* @param int $type Error-type, Pre defined PHP Constant
|
||||
* @param string error. The error itself
|
||||
* @param string File. The absolute path of the file
|
||||
* @param int Line. The line on which the error occured.
|
||||
* @param array context. Some of the error's relevant variables
|
||||
* @param string $error . The error itself
|
||||
* @param string|null $errFile . The absolute path of the file
|
||||
* @param int|null $errLine . The line on which the error occurred.
|
||||
*/
|
||||
public static function errorHandler(int $type = E_USER_NOTICE, $error = 'Undefined Error', $errFile = null, $errLine = null)
|
||||
public static function errorHandler(int $type = E_USER_NOTICE, string $error = 'Undefined Error', string $errFile = null, int $errLine = null): void
|
||||
{
|
||||
// Check type
|
||||
$thisType = self::getType($type);
|
||||
$LOG = array('type' => (!is_null($thisType) ? $thisType : 'ERROR'),
|
||||
$LOG = array('type' => $thisType,
|
||||
'message' => (!is_null($error) ? $error : ''),
|
||||
'logFile' => (!is_null($errFile) ? $errFile : ''),
|
||||
'logLine' => (!is_null($errLine) ? $errLine : ''),
|
||||
'runtime' => round(self::getRelativeTime(), 4),);
|
||||
'runtime' => round(self::getRelativeTime(), 4));
|
||||
self::$logs[] = $LOG;
|
||||
}
|
||||
|
||||
@ -286,7 +259,7 @@ class Logger {
|
||||
* @param Throwable $exception The occurred exception.
|
||||
* @param bool $haltExecution. Defaults to true
|
||||
*/
|
||||
public static function exceptionHandler(Throwable $exception, bool $haltExecution = true)
|
||||
public static function exceptionHandler(Throwable $exception, bool $haltExecution = true): void
|
||||
{
|
||||
$LOG = [
|
||||
'type' => $exception instanceof Exception ? "EXCEPTION" : "ERROR",
|
||||
@ -307,9 +280,9 @@ class Logger {
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @var string Name of the template file
|
||||
* @var string $templateName of the template file
|
||||
*/
|
||||
public static function setLoggerTemplate($templateName)
|
||||
public static function setLoggerTemplate(string $templateName): void
|
||||
{
|
||||
self::$logger_template = $templateName;
|
||||
}
|
||||
@ -319,7 +292,7 @@ class Logger {
|
||||
* @codeCoverageIgnore
|
||||
* @throws EventException
|
||||
*/
|
||||
public static function logToScreen()
|
||||
public static function logToScreen(): void
|
||||
{
|
||||
// Send a screenLogEvent, allows for new screen log designs
|
||||
$event = Events::fireEvent('screenLogEvent');
|
||||
@ -335,7 +308,7 @@ class Logger {
|
||||
* Output the entire log to a file. Used for debugging problems with your code.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function logLastRequest()
|
||||
public static function logLastRequest(): void
|
||||
{
|
||||
ob_start(function () {});
|
||||
$logs = self::$logs;
|
||||
@ -350,15 +323,14 @@ class Logger {
|
||||
* Output all errors to a file. Used for tracking all errors in FuzeWorks and associated code
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function logErrorsToFile()
|
||||
public static function logErrorsToFile(): void
|
||||
{
|
||||
ob_start(function() {});
|
||||
$logs = [];
|
||||
foreach (self::$logs as $log)
|
||||
{
|
||||
if ($log['type'] === 'ERROR' || $log['type'] === 'EXCEPTION')
|
||||
$logs[] = $log;
|
||||
}
|
||||
|
||||
require(dirname(__DIR__) . DS . 'Layout' . DS . 'layout.logger_file.php');
|
||||
$contents = ob_get_clean();
|
||||
$file = Core::$logDir . DS . 'fwlog_errors.log';
|
||||
@ -377,10 +349,10 @@ class Logger {
|
||||
* @param string $name Marker name
|
||||
* @return void
|
||||
*/
|
||||
public static function mark(string $name)
|
||||
public static function mark(string $name): void
|
||||
{
|
||||
$LOG = array('type' => 'BMARK',
|
||||
'message' => (!is_null($name) ? $name : ''),
|
||||
'message' => $name,
|
||||
'logFile' => '',
|
||||
'logLine' => '',
|
||||
'context' => '',
|
||||
@ -397,7 +369,7 @@ class Logger {
|
||||
* @param string|null $file The file where the log occurred
|
||||
* @param int|null $line The line where the log occurred
|
||||
*/
|
||||
public static function log(string $msg, string $mod = null, string $file = null, int $line = null)
|
||||
public static function log(string $msg, string $mod = null, string $file = null, int $line = null): void
|
||||
{
|
||||
self::logInfo($msg, $mod, $file, $line);
|
||||
}
|
||||
@ -410,7 +382,7 @@ class Logger {
|
||||
* @param string|null $file The file where the log occurred
|
||||
* @param int|null $line The line where the log occurred
|
||||
*/
|
||||
public static function logInfo(string $msg, string $mod = null, string $file = null, int $line = null)
|
||||
public static function logInfo(string $msg, string $mod = null, string $file = null, int $line = null): void
|
||||
{
|
||||
$LOG = array('type' => 'INFO',
|
||||
'message' => ($msg),
|
||||
@ -430,7 +402,7 @@ class Logger {
|
||||
* @param string|null $file The file where the log occurred
|
||||
* @param int|null $line The line where the log occurred
|
||||
*/
|
||||
public static function logDebug(string $msg, string $mod = null, string $file = null, int $line = null)
|
||||
public static function logDebug(string $msg, string $mod = null, string $file = null, int $line = null): void
|
||||
{
|
||||
$LOG = array('type' => 'DEBUG',
|
||||
'message' => ($msg),
|
||||
@ -450,7 +422,7 @@ class Logger {
|
||||
* @param string|null $file The file where the log occurred
|
||||
* @param int|null $line The line where the log occurred
|
||||
*/
|
||||
public static function logError(string $msg, string $mod = null, string $file = null, int $line = null)
|
||||
public static function logError(string $msg, string $mod = null, string $file = null, int $line = null): void
|
||||
{
|
||||
$LOG = array('type' => 'ERROR',
|
||||
'message' => ($msg),
|
||||
@ -470,7 +442,7 @@ class Logger {
|
||||
* @param string|null $file The file where the log occurred
|
||||
* @param int|null $line The line where the log occurred
|
||||
*/
|
||||
public static function logWarning(string $msg, string $mod = null, string $file = null, int $line = null)
|
||||
public static function logWarning(string $msg, string $mod = null, string $file = null, int $line = null): void
|
||||
{
|
||||
$LOG = array('type' => 'WARNING',
|
||||
'message' => ($msg),
|
||||
@ -490,7 +462,7 @@ class Logger {
|
||||
* @param string|null $file The file where the log occurred
|
||||
* @param int|null $line The line where the log occurred
|
||||
*/
|
||||
public static function newLevel(string $msg, string $mod = null, string $file = null, int $line = null)
|
||||
public static function newLevel(string $msg, string $mod = null, string $file = null, int $line = null): void
|
||||
{
|
||||
$LOG = array('type' => 'LEVEL_START',
|
||||
'message' => ($msg),
|
||||
@ -510,7 +482,7 @@ class Logger {
|
||||
* @param string|null $file The file where the log occurred
|
||||
* @param int|null $line The line where the log occurred
|
||||
*/
|
||||
public static function stopLevel(string $msg = null, string $mod = null, string $file = null, int $line = null)
|
||||
public static function stopLevel(string $msg = null, string $mod = null, string $file = null, int $line = null): void
|
||||
{
|
||||
$LOG = array('type' => 'LEVEL_STOP',
|
||||
'message' => (!is_null($msg) ? $msg : ''),
|
||||
@ -534,27 +506,12 @@ class Logger {
|
||||
*/
|
||||
public static function getType(int $type): string
|
||||
{
|
||||
switch ($type) {
|
||||
case E_PARSE:
|
||||
case E_CORE_ERROR:
|
||||
case E_COMPILE_ERROR:
|
||||
case E_USER_ERROR:
|
||||
case E_STRICT:
|
||||
case E_RECOVERABLE_ERROR:
|
||||
case E_ERROR:
|
||||
return 'ERROR';
|
||||
case E_NOTICE:
|
||||
case E_CORE_WARNING:
|
||||
case E_COMPILE_WARNING:
|
||||
case E_USER_WARNING:
|
||||
case E_USER_NOTICE:
|
||||
case E_USER_DEPRECATED:
|
||||
case E_DEPRECATED:
|
||||
case E_WARNING:
|
||||
return 'WARNING';
|
||||
}
|
||||
return match ($type) {
|
||||
E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR, E_STRICT, E_RECOVERABLE_ERROR, E_ERROR => 'ERROR',
|
||||
E_NOTICE, E_CORE_WARNING, E_COMPILE_WARNING, E_USER_WARNING, E_USER_NOTICE, E_USER_DEPRECATED, E_DEPRECATED, E_WARNING => 'WARNING',
|
||||
default => 'Unknown error: ' . $type,
|
||||
};
|
||||
|
||||
return 'Unknown error: ' . $type;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -564,7 +521,7 @@ class Logger {
|
||||
* @param array $log
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function haltExecution(array $log)
|
||||
public static function haltExecution(array $log): void
|
||||
{
|
||||
self::logError("Halting execution...");
|
||||
try {
|
||||
@ -573,7 +530,7 @@ class Logger {
|
||||
self::logError("Can't fire haltExecutionEvent: '".$e->getMessage()."'");
|
||||
die(PHP_EOL . "FuzeWorks execution halted. See error log for more information");
|
||||
}
|
||||
if ($event->isCancelled() == true)
|
||||
if ($event->isCancelled())
|
||||
return;
|
||||
|
||||
die(PHP_EOL . "FuzeWorks execution halted. See error log for more information");
|
||||
|
@ -94,16 +94,16 @@ class Plugins
|
||||
* @throws FactoryException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
public function init(): void
|
||||
{
|
||||
$this->cfg = Factory::getInstance()->config->getConfig('plugins');
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the header files of all plugins.
|
||||
*/
|
||||
public function loadHeadersFromPluginPaths()
|
||||
{
|
||||
public function loadHeadersFromPluginPaths(): void
|
||||
{
|
||||
// Cycle through all pluginPaths
|
||||
for ($i=Priority::getHighestPriority(); $i<=Priority::getLowestPriority(); $i++)
|
||||
{
|
||||
@ -197,7 +197,7 @@ class Plugins
|
||||
* @throws Exception\EventException
|
||||
* @throws PluginException
|
||||
*/
|
||||
public function get(string $pluginName, array $parameters = null)
|
||||
public function get(string $pluginName, array $parameters = null): mixed
|
||||
{
|
||||
if (empty($pluginName))
|
||||
throw new PluginException("Could not load plugin. No name provided", 1);
|
||||
@ -237,7 +237,7 @@ class Plugins
|
||||
$prefix = $header->getClassesPrefix();
|
||||
$filePath = dirname($headerReflection->getFileName()) . (!empty($header->getSourceDirectory()) ? DS . $header->getSourceDirectory() : '');
|
||||
$pluginClass = $header->getPluginClass();
|
||||
if (!is_null($prefix) && !is_null($filePath))
|
||||
if (!is_null($prefix))
|
||||
{
|
||||
try {
|
||||
Core::addAutoloadMap($prefix, $filePath);
|
||||
@ -255,7 +255,7 @@ class Plugins
|
||||
}
|
||||
|
||||
// Attempt to load the plugin
|
||||
if (!class_exists($pluginClass, true))
|
||||
if (!class_exists($pluginClass))
|
||||
throw new PluginException("Could not load plugin. Class does not exist", 1);
|
||||
|
||||
$this->plugins[$pluginName] = new $pluginClass($parameters);
|
||||
|
@ -64,28 +64,21 @@ abstract class Priority
|
||||
/**
|
||||
* Returns the string of the priority based on the integer.
|
||||
*
|
||||
* @param $intPriorty
|
||||
* @param int $priority
|
||||
*
|
||||
* @return bool|string A bool when the integer isn't a priority. If the integer is a priority, the name is returned
|
||||
*/
|
||||
public static function getPriority($intPriorty)
|
||||
public static function getPriority(int $priority): bool|string
|
||||
{
|
||||
switch ($intPriorty) {
|
||||
case 5:
|
||||
return 'Priority::LOWEST';
|
||||
case 4:
|
||||
return 'Priority::LOW';
|
||||
case 3:
|
||||
return 'Priority::NORMAL';
|
||||
case 2:
|
||||
return 'Priority::HIGH';
|
||||
case 1:
|
||||
return 'Priority::HIGHEST';
|
||||
case 0:
|
||||
return 'Priority::MONITOR';
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return match ($priority) {
|
||||
5 => 'Priority::LOWEST',
|
||||
4 => 'Priority::LOW',
|
||||
3 => 'Priority::NORMAL',
|
||||
2 => 'Priority::HIGH',
|
||||
1 => 'Priority::HIGHEST',
|
||||
0 => 'Priority::MONITOR',
|
||||
default => false,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
140
src/FuzeWorks/Storage.php
Normal file
140
src/FuzeWorks/Storage.php
Normal file
@ -0,0 +1,140 @@
|
||||
<?php
|
||||
/**
|
||||
* FuzeWorks Storage Component.
|
||||
*
|
||||
* The FuzeWorks PHP FrameWork
|
||||
*
|
||||
* Copyright (C) 2013-2020 i15
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @author i15
|
||||
* @copyright Copyright (c) 2013 - 2020, i15. (https://i15.nl)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
*
|
||||
* @since Version 1.3.0
|
||||
*
|
||||
* @version Version 1.4.0
|
||||
*/
|
||||
|
||||
namespace FuzeWorks;
|
||||
use FuzeWorks\Exception\ConfigException;
|
||||
use FuzeWorks\Exception\FactoryException;
|
||||
use FuzeWorks\Exception\StorageException;
|
||||
use FuzeWorks\Storage\iStorageProvider;
|
||||
use FuzeWorks\Storage\StorageCache;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
|
||||
/**
|
||||
* Storage Class.
|
||||
*
|
||||
* This class doesn't do very much, except show the FuzeWorks\Configurator that this dependency has been loaded.
|
||||
*
|
||||
* @author i15
|
||||
* @copyright Copyright (c) 2013 - 2020, i15. (https://i15.nl)
|
||||
*/
|
||||
class Storage
|
||||
{
|
||||
|
||||
/**
|
||||
* The configuration file for Storage
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private array $cfg;
|
||||
|
||||
/**
|
||||
* The currently selected StorageProvider
|
||||
*
|
||||
* @var iStorageProvider
|
||||
*/
|
||||
private iStorageProvider $provider;
|
||||
|
||||
/**
|
||||
* The currently used CacheInterface
|
||||
*
|
||||
* @var CacheInterface
|
||||
*/
|
||||
private CacheInterface $cache;
|
||||
|
||||
/**
|
||||
* Fetches and returns the currently selected StorageProvider
|
||||
*
|
||||
* @return iStorageProvider
|
||||
*@throws StorageException
|
||||
*/
|
||||
public function getStorage(): iStorageProvider
|
||||
{
|
||||
// If the provider is already loaded, return that one
|
||||
if (isset($this->provider))
|
||||
return $this->provider;
|
||||
|
||||
// Load the config, if it isn't loaded yet
|
||||
if (!isset($this->cfg))
|
||||
{
|
||||
try {
|
||||
/** @var Config $configs */
|
||||
$configs = Factory::getInstance('config');
|
||||
$this->cfg = $configs->getConfig('storage')->toArray();
|
||||
} catch (ConfigException | FactoryException $e) {
|
||||
throw new StorageException("Could not get StorageProvider. No config file named 'config.storage.php' could be found.");
|
||||
}
|
||||
}
|
||||
|
||||
// Get the currently selected StorageProvider
|
||||
$selected = $this->cfg['StorageProvider'];
|
||||
if (is_null($selected))
|
||||
throw new StorageException("Could not get StorageProvider. Selected provider is null!");
|
||||
|
||||
// Try and load the StorageProvider
|
||||
$class = '\FuzeWorks\Storage\Provider\\' . $selected;
|
||||
if (!class_exists($class, true))
|
||||
throw new StorageException("Could not get StorageProvider. Selected provider '".$selected."' is not recognized.");
|
||||
|
||||
/** @var iStorageProvider $provider */
|
||||
$provider = new $class();
|
||||
if (!$provider instanceof iStorageProvider)
|
||||
throw new StorageException("Could not get StorageProvider. Selected provider '".$selected."' is not an instance of iStorageProvider'.");
|
||||
|
||||
// Fetch the parameters
|
||||
$params = isset($this->cfg[$selected]) && is_array($this->cfg[$selected]) ? $this->cfg[$selected] : [];
|
||||
if (!$provider->init($params))
|
||||
throw new StorageException("Could not get StorageProvider. Selected provider '".$selected."' failed to load.");
|
||||
|
||||
$this->provider = $provider;
|
||||
return $this->provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a PSR compatible Cache object
|
||||
*
|
||||
* @return CacheInterface
|
||||
* @throws StorageException
|
||||
*/
|
||||
public function getCache(): CacheInterface
|
||||
{
|
||||
if (isset($this->cache))
|
||||
return $this->cache;
|
||||
|
||||
$storageProvider = $this->getStorage();
|
||||
$this->cache = new StorageCache($storageProvider);
|
||||
|
||||
return $this->cache;
|
||||
}
|
||||
}
|
117
src/FuzeWorks/Storage/Provider/DummyProvider.php
Normal file
117
src/FuzeWorks/Storage/Provider/DummyProvider.php
Normal file
@ -0,0 +1,117 @@
|
||||
<?php
|
||||
/**
|
||||
* FuzeWorks ObjectStorage Component.
|
||||
*
|
||||
* The FuzeWorks PHP FrameWork
|
||||
*
|
||||
* Copyright (C) 2013-2020 i15
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @author i15
|
||||
* @copyright Copyright (c) 2013 - 2020, i15. (https://i15.nl)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
*
|
||||
* @since Version 1.3.0
|
||||
*
|
||||
* @version Version 1.3.0
|
||||
*/
|
||||
|
||||
namespace FuzeWorks\Storage\Provider;
|
||||
use FuzeWorks\Storage\iStorageProvider;
|
||||
|
||||
class DummyProvider implements iStorageProvider
|
||||
{
|
||||
|
||||
private array $data = ['index' => [], 'data' => []];
|
||||
|
||||
public function init(array $providerConfig): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getIndex(): array
|
||||
{
|
||||
return $this->data['index'];
|
||||
}
|
||||
|
||||
public function getItem(string $key)
|
||||
{
|
||||
if (!in_array($key, $this->data['index']))
|
||||
return null;
|
||||
|
||||
return $this->data['data'][$key]['data'];
|
||||
}
|
||||
|
||||
public function getItemMeta(string $key): ?array
|
||||
{
|
||||
if (!in_array($key, $this->data['index']))
|
||||
return null;
|
||||
|
||||
return $this->data['data'][$key]['meta'];
|
||||
}
|
||||
|
||||
public function getItems(array $keys = []): array
|
||||
{
|
||||
$output = [];
|
||||
foreach ($keys as $key)
|
||||
$output[$key] = $this->getItem($key);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function hasItem(string $key): bool
|
||||
{
|
||||
return in_array($key, $this->data['index']);
|
||||
}
|
||||
|
||||
public function clear(): bool
|
||||
{
|
||||
return $this->deleteItems($this->getIndex());
|
||||
}
|
||||
|
||||
public function deleteItem(string $key): bool
|
||||
{
|
||||
// Remove the index
|
||||
if (($k = array_search($key, $this->data['index'])) !== false) {
|
||||
unset($this->data['index'][$k]);
|
||||
}
|
||||
|
||||
// And remove the data
|
||||
unset($this->data['data'][$key]);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function deleteItems(array $keys): bool
|
||||
{
|
||||
foreach ($keys as $key)
|
||||
$this->deleteItem($key);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function save(string $key, $value, array $metaData = []): bool
|
||||
{
|
||||
if (!in_array($key, $this->data['index']))
|
||||
$this->data['index'][] = $key;
|
||||
|
||||
$this->data['data'][$key] = ['data' => $value, 'meta' => $metaData];
|
||||
return true;
|
||||
}
|
||||
}
|
256
src/FuzeWorks/Storage/Provider/FileProvider.php
Normal file
256
src/FuzeWorks/Storage/Provider/FileProvider.php
Normal file
@ -0,0 +1,256 @@
|
||||
<?php
|
||||
/**
|
||||
* FuzeWorks ObjectStorage Component.
|
||||
*
|
||||
* The FuzeWorks PHP FrameWork
|
||||
*
|
||||
* Copyright (C) 2013-2020 i15
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @author i15
|
||||
* @copyright Copyright (c) 2013 - 2020, i15. (https://i15.nl)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
*
|
||||
* @since Version 1.3.0
|
||||
*
|
||||
* @version Version 1.3.0
|
||||
*/
|
||||
|
||||
namespace FuzeWorks\Storage\Provider;
|
||||
use FuzeWorks\Core;
|
||||
use FuzeWorks\Exception\StorageException;
|
||||
use FuzeWorks\Storage\iStorageProvider;
|
||||
|
||||
/**
|
||||
* FileProvider
|
||||
*
|
||||
* An ObjectStorage provider which saves objects in files using the serialize() and unserialize() functions.
|
||||
* The easiest to use StorageProvider, though with its caveats. It's nimble and works on nearly everything, but
|
||||
* not particularly fast, and has some risks when multiple processes use the data at the same time.
|
||||
*
|
||||
* @todo Figure out a way to prevent indexes from clashing in multiple threads
|
||||
* @todo Find a better way to sanitize key names other than hashing them using crc32
|
||||
* @author i15
|
||||
* @copyright Copyright (c) 2013 - 2020, i15. (https://i15.nl)
|
||||
*/
|
||||
class FileProvider implements iStorageProvider
|
||||
{
|
||||
|
||||
/**
|
||||
* The directory where all objects are saved
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected string $directory;
|
||||
|
||||
/**
|
||||
* The file where the index for this provider is saved
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected string $indexFile;
|
||||
|
||||
/**
|
||||
* The index of all objects stored
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected array $index;
|
||||
|
||||
/**
|
||||
* @param array $providerConfig
|
||||
* @return bool
|
||||
* @throws StorageException
|
||||
*/
|
||||
public function init(array $providerConfig): bool
|
||||
{
|
||||
// First load the directory from the providerConfig
|
||||
$directory = $providerConfig['storage_directory'] ?? null;
|
||||
|
||||
// Check if the directory exists
|
||||
if (!file_exists($directory) || !is_dir($directory))
|
||||
throw new StorageException("Could not load FileProvider Storage. Provided storageDirectory is not a directory.");
|
||||
|
||||
// Check if that directory also is writeable
|
||||
if (!Core::isReallyWritable($directory))
|
||||
throw new StorageException("Could not load FileProvider Storage. Provided storageDirectory is not writeable.");
|
||||
|
||||
// Save the directory and indexFile, and load or initialize the indexFile
|
||||
$this->directory = rtrim($directory);
|
||||
$this->indexFile = $this->directory . DS . 'index.fwstorage';
|
||||
|
||||
// If the index does not exist yet, load it
|
||||
if (!file_exists($this->indexFile))
|
||||
{
|
||||
if (!$this->write_file($this->indexFile, serialize(['index' => []])))
|
||||
throw new StorageException("Could not load FileProvider Storage. Could not write index.");
|
||||
|
||||
chmod($this->indexFile, 0640);
|
||||
}
|
||||
|
||||
// And finally, load the index
|
||||
$this->index = unserialize(file_get_contents($this->indexFile))['index'];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getIndex(): array
|
||||
{
|
||||
$out = [];
|
||||
foreach ($this->index as $key => $val)
|
||||
$out[] = $key;
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function getItem(string $key)
|
||||
{
|
||||
// Convert the key
|
||||
$file = $this->directory . DS . crc32($key) . '.fwstorage';
|
||||
|
||||
// If the key could not be found in the index, return null
|
||||
if (!isset($this->index[$key]))
|
||||
return null;
|
||||
|
||||
// Check if the file exists. If not, delete the indexed value
|
||||
if (!file_exists($file))
|
||||
{
|
||||
$this->deleteItem($key);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Otherwise try and load the metaData and contents
|
||||
return unserialize(file_get_contents($file));
|
||||
}
|
||||
|
||||
public function getItemMeta(string $key): ?array
|
||||
{
|
||||
// If the key could not be found in the index, return null
|
||||
if (!isset($this->index[$key]))
|
||||
return null;
|
||||
|
||||
// Otherwise return the meta data
|
||||
return $this->index[$key]['meta'];
|
||||
}
|
||||
|
||||
public function getItems(array $keys = []): array
|
||||
{
|
||||
$output = [];
|
||||
foreach ($keys as $key)
|
||||
$output[$key] = $this->getItem($key);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function hasItem(string $key): bool
|
||||
{
|
||||
return isset($this->index[$key]);
|
||||
}
|
||||
|
||||
public function clear(): bool
|
||||
{
|
||||
$keys = array_keys($this->index);
|
||||
return $this->deleteItems($keys);
|
||||
}
|
||||
|
||||
public function deleteItem(string $key): bool
|
||||
{
|
||||
// Convert the key
|
||||
$file = $this->directory . DS . crc32($key) . '.fwstorage';
|
||||
|
||||
// Remove the file first
|
||||
if (file_exists($file))
|
||||
unlink($file);
|
||||
|
||||
// And remove it from the index
|
||||
if (isset($this->index[$key]))
|
||||
unset($this->index[$key]);
|
||||
|
||||
// And commit the index
|
||||
return $this->commitIndex();
|
||||
}
|
||||
|
||||
public function deleteItems(array $keys): bool
|
||||
{
|
||||
foreach ($keys as $key)
|
||||
$this->deleteItem($key);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function save(string $key, $value, array $metaData = []): bool
|
||||
{
|
||||
// Convert the key
|
||||
$file = $this->directory . DS . crc32($key) . '.fwstorage';
|
||||
|
||||
// Remove the file if it already exists
|
||||
if (file_exists($file))
|
||||
unlink($file);
|
||||
|
||||
// Write everything to the index
|
||||
$this->index[$key] = ['meta' => $metaData];
|
||||
$this->commitIndex();
|
||||
|
||||
// And write the contents
|
||||
if ($this->write_file($file, serialize($value))) {
|
||||
chmod($file, 0640);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function commitIndex(): bool
|
||||
{
|
||||
if ($this->write_file($this->indexFile, serialize(['index' => $this->index]))) {
|
||||
chmod($this->indexFile, 0640);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write File
|
||||
*
|
||||
* Writes data to the file specified in the path.
|
||||
* Creates a new file if non-existent.
|
||||
*
|
||||
* @param string $path File path
|
||||
* @param string $data Data to write
|
||||
* @return bool
|
||||
*/
|
||||
private function write_file(string $path, string $data): bool
|
||||
{
|
||||
if ( ! $fp = @fopen($path, 'wb'))
|
||||
return false;
|
||||
|
||||
flock($fp, LOCK_EX);
|
||||
|
||||
for ($result = $written = 0, $length = strlen($data); $written < $length; $written += $result)
|
||||
if (($result = fwrite($fp, substr($data, $written))) === false)
|
||||
break;
|
||||
|
||||
flock($fp, LOCK_UN);
|
||||
fclose($fp);
|
||||
|
||||
return is_int($result);
|
||||
}
|
||||
}
|
188
src/FuzeWorks/Storage/Provider/RedisProvider.php
Normal file
188
src/FuzeWorks/Storage/Provider/RedisProvider.php
Normal file
@ -0,0 +1,188 @@
|
||||
<?php
|
||||
/**
|
||||
* FuzeWorks ObjectStorage Component.
|
||||
*
|
||||
* The FuzeWorks PHP FrameWork
|
||||
*
|
||||
* Copyright (C) 2013-2020 i15
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @author i15
|
||||
* @copyright Copyright (c) 2013 - 2020, i15. (https://i15.nl)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
*
|
||||
* @since Version 1.3.0
|
||||
*
|
||||
* @version Version 1.3.0
|
||||
*/
|
||||
|
||||
namespace FuzeWorks\Storage\Provider;
|
||||
use FuzeWorks\Exception\StorageException;
|
||||
use FuzeWorks\Storage\iStorageProvider;
|
||||
use Redis;
|
||||
use RedisException;
|
||||
|
||||
class RedisProvider implements iStorageProvider
|
||||
{
|
||||
|
||||
/**
|
||||
* @var Redis
|
||||
*/
|
||||
protected Redis $conn;
|
||||
|
||||
/**
|
||||
* Initializes the RedisProvider, by connecting to the Redis Server.
|
||||
*
|
||||
* $providerConfig can contain the following keys:
|
||||
* 'socket_type', being either 'socket' or 'tcp'
|
||||
* 'socket', when socket_type is socket, contains a handle for the socket
|
||||
* 'host', when socket_type is tcp, contains the hostname or ip of the server
|
||||
* 'port', when socket_type is tcp, contains the port of the server
|
||||
* 'timeout', when socket_type is tcp, contains the amount of time to attempt connecting before failure
|
||||
* 'db_index', the specific database number to use on the Redis Server
|
||||
*
|
||||
* Throws any StorageException on failure.
|
||||
*
|
||||
* @param array $providerConfig
|
||||
* @return bool
|
||||
* @throws StorageException
|
||||
*/
|
||||
public function init(array $providerConfig): bool
|
||||
{
|
||||
try {
|
||||
$this->conn = new Redis();
|
||||
|
||||
// Afterwards we attempt to connect to the server
|
||||
$socketType = $providerConfig['socket_type'];
|
||||
if ($socketType === 'unix')
|
||||
$success = $this->conn->connect($providerConfig['socket']);
|
||||
elseif ($socketType === 'tcp')
|
||||
$success = $this->conn->connect($providerConfig['host'], $providerConfig['port'], $providerConfig['timeout']);
|
||||
else
|
||||
$success = false;
|
||||
|
||||
// If failed, throw an exception informing so
|
||||
if (!$success)
|
||||
throw new StorageException("Could not load RedisProvider Storage. Unable to connect to server.");
|
||||
|
||||
// If authentication is required, attempt to do so with the provided password
|
||||
if (isset($providerConfig['password']) && !$this->conn->auth($providerConfig['password']))
|
||||
throw new StorageException("Could not load RedisProvider Storage. Authentication failure.");
|
||||
|
||||
// If a db_index is provided, use that one accordingly
|
||||
if (isset($providerConfig['db_index']) && is_int($providerConfig['db_index']))
|
||||
$this->conn->select($providerConfig['db_index']);
|
||||
|
||||
// And if all goes well, report a true
|
||||
return true;
|
||||
|
||||
// If any sort of failure has occurred along the way,
|
||||
} catch (RedisException $e) {
|
||||
throw new StorageException("Could not load RedisProvider Storage. RedisException thrown: '" . $e->getMessage() . "'");
|
||||
}
|
||||
}
|
||||
|
||||
public function getIndex(): array
|
||||
{
|
||||
return $this->conn->sMembers('StorageIndex');
|
||||
}
|
||||
|
||||
public function getItem(string $key)
|
||||
{
|
||||
// If the requested key is not part of the index, this item is not tracked and should therefore
|
||||
// return null.
|
||||
if (!$this->conn->sIsMember('StorageIndex', $key))
|
||||
return null;
|
||||
|
||||
// If the data doesn't exist, return null
|
||||
if (!$this->conn->hExists('fwstorage_' . $key, 'data'))
|
||||
return null;
|
||||
|
||||
return unserialize($this->conn->hGet('fwstorage_' . $key, 'data'));
|
||||
}
|
||||
|
||||
public function getItemMeta(string $key): ?array
|
||||
{
|
||||
// If the requested key is not part of the index, this item is not tracked and should therefore
|
||||
// return null.
|
||||
if (!$this->conn->sIsMember('StorageIndex', $key))
|
||||
return null;
|
||||
|
||||
// If the data doesn't exist, return null
|
||||
if (!$this->conn->hExists('fwstorage_' . $key, 'meta'))
|
||||
return null;
|
||||
|
||||
return unserialize($this->conn->hGet('fwstorage_' . $key, 'meta'));
|
||||
}
|
||||
|
||||
public function getItems(array $keys = []): array
|
||||
{
|
||||
$output = [];
|
||||
foreach ($keys as $key)
|
||||
$output[$key] = $this->getItem($key);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function hasItem(string $key): bool
|
||||
{
|
||||
return $this->conn->sIsMember('StorageIndex', $key);
|
||||
}
|
||||
|
||||
public function clear(): bool
|
||||
{
|
||||
return $this->deleteItems($this->getIndex());
|
||||
}
|
||||
|
||||
public function deleteItem(string $key): bool
|
||||
{
|
||||
// If the requested key is not part of the index, this item is not tracked and should therefore
|
||||
// return null.
|
||||
if ($this->conn->sIsMember('StorageIndex', $key))
|
||||
$this->conn->sRem('StorageIndex', $key);
|
||||
|
||||
if ($this->conn->exists('fwstorage_' . $key))
|
||||
$this->conn->del('fwstorage_' . $key);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function deleteItems(array $keys): bool
|
||||
{
|
||||
foreach ($keys as $key)
|
||||
$this->deleteItem($key);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function save(string $key, $value, array $metaData = []): bool
|
||||
{
|
||||
// If the requested key is not part of the index, this item is not tracked and should therefore
|
||||
// return null.
|
||||
if (!$this->conn->sIsMember('StorageIndex', $key))
|
||||
$this->conn->sAdd('StorageIndex', $key);
|
||||
|
||||
// Write to the hash
|
||||
$this->conn->hSet('fwstorage_' . $key, 'data', serialize($value));
|
||||
$this->conn->hSet('fwstorage_' . $key, 'meta', serialize($metaData));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
128
src/FuzeWorks/Storage/StorageCache.php
Normal file
128
src/FuzeWorks/Storage/StorageCache.php
Normal file
@ -0,0 +1,128 @@
|
||||
<?php
|
||||
/**
|
||||
* FuzeWorks ObjectStorage Component.
|
||||
*
|
||||
* The FuzeWorks PHP FrameWork
|
||||
*
|
||||
* Copyright (C) 2013-2020 i15
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @author i15
|
||||
* @copyright Copyright (c) 2013 - 2020, i15. (https://i15.nl)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
*
|
||||
* @since Version 1.3.0
|
||||
*
|
||||
* @version Version 1.3.0
|
||||
*/
|
||||
|
||||
namespace FuzeWorks\Storage;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
|
||||
class StorageCache implements CacheInterface
|
||||
{
|
||||
|
||||
private iStorageProvider $provider;
|
||||
|
||||
public function __construct(iStorageProvider $provider)
|
||||
{
|
||||
$this->provider = $provider;
|
||||
}
|
||||
|
||||
private function testTTL(string $key)
|
||||
{
|
||||
$meta = $this->provider->getItemMeta('fwcache_' . $key);
|
||||
if (!is_null($meta) && $meta['ttl'] > 0 && time() > $meta['time'] + $meta['ttl'])
|
||||
$this->provider->deleteItem('fwcache_' . $key);
|
||||
}
|
||||
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
// Remove the item if its TTL has expired
|
||||
$this->testTTL($key);
|
||||
|
||||
// Fetch the value
|
||||
$res = $this->provider->getItem('fwcache_' . $key);
|
||||
|
||||
// If there is no value, return the default
|
||||
return is_null($res) ? $default : $res;
|
||||
}
|
||||
|
||||
public function set($key, $value, $ttl = null): bool
|
||||
{
|
||||
$meta = [
|
||||
'time' => time(),
|
||||
'ttl' => is_int($ttl) ? $ttl : 0
|
||||
];
|
||||
|
||||
return $this->provider->save('fwcache_' . $key, $value, $meta);
|
||||
}
|
||||
|
||||
public function delete($key): bool
|
||||
{
|
||||
return $this->provider->deleteItem('fwcache_' . $key);
|
||||
}
|
||||
|
||||
public function clear(): bool
|
||||
{
|
||||
// Fetch the index set
|
||||
$index = $this->provider->getIndex();
|
||||
foreach ($index as $entry)
|
||||
{
|
||||
if (substr($entry, 0, 8) === 'fwcache_')
|
||||
$this->provider->deleteItem($entry);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getMultiple($keys, $default = null): array
|
||||
{
|
||||
$out = [];
|
||||
foreach ($keys as $key)
|
||||
{
|
||||
$out[$key] = $this->get($key, $default);
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function setMultiple($values, $ttl = null): bool
|
||||
{
|
||||
foreach ($values as $key => $value)
|
||||
$this->set($key, $value, $ttl);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function deleteMultiple($keys): bool
|
||||
{
|
||||
foreach ($keys as $key)
|
||||
$this->delete($key);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function has($key): bool
|
||||
{
|
||||
$this->testTTL($key);
|
||||
return $this->provider->hasItem('fwcache_' . $key);
|
||||
}
|
||||
}
|
52
src/FuzeWorks/Storage/iStorageProvider.php
Normal file
52
src/FuzeWorks/Storage/iStorageProvider.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/**
|
||||
* FuzeWorks ObjectStorage Component.
|
||||
*
|
||||
* The FuzeWorks PHP FrameWork
|
||||
*
|
||||
* Copyright (C) 2013-2020 i15
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @author i15
|
||||
* @copyright Copyright (c) 2013 - 2020, i15. (https://i15.nl)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
*
|
||||
* @since Version 1.3.0
|
||||
*
|
||||
* @version Version 1.3.0
|
||||
*/
|
||||
|
||||
namespace FuzeWorks\Storage;
|
||||
|
||||
interface iStorageProvider
|
||||
{
|
||||
|
||||
public function init(array $providerConfig): bool;
|
||||
public function getIndex(): array;
|
||||
public function getItem(string $key);
|
||||
public function getItemMeta(string $key): ?array;
|
||||
public function getItems(array $keys = []): array;
|
||||
public function hasItem(string $key): bool;
|
||||
public function clear(): bool;
|
||||
public function deleteItem(string $key): bool;
|
||||
public function deleteItems(array $keys): bool;
|
||||
public function save(string $key, $value, array $metaData = []): bool;
|
||||
|
||||
}
|
@ -38,7 +38,7 @@ $mask = "|%5s |%5s |%-90s |\n";
|
||||
$id = 1;
|
||||
|
||||
if (!empty($logs))
|
||||
printf($mask, $id, 'REQUEST', ' ' . date('Y-m-d H:i') . '-'.substr(sha1(uniqid()), 0, 8).'');
|
||||
printf($mask, $id, 'REQUEST', ' ' . date('Y-m-d H:i') . '-'.substr(sha1(uniqid()), 0, 8));
|
||||
|
||||
foreach ($logs as $log) {
|
||||
$id++;
|
||||
|
@ -401,7 +401,7 @@ class configuratorTest extends CoreTestAbstract
|
||||
$this->assertTrue($this->configurator->isDebugMode());
|
||||
|
||||
// Set a debug address, all in this case; also verify return type
|
||||
$this->assertInstanceOf('FuzeWorks\Configurator', $this->configurator->setDebugAddress('NONE'));
|
||||
$this->assertInstanceOf('FuzeWorks\Configurator', $this->configurator->setDebugAddress());
|
||||
|
||||
// No match should be found. Verify that debug has been deactivated
|
||||
$this->assertFalse($this->configurator->isDebugMode());
|
||||
@ -470,16 +470,6 @@ class configuratorTest extends CoreTestAbstract
|
||||
// Unset
|
||||
unset($_COOKIE[Configurator::COOKIE_SECRET], $_SERVER['REMOTE_ADDR']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testEnableDebugMode
|
||||
* @covers ::setDebugAddress
|
||||
*/
|
||||
public function testSetDebugAddressInvalidArgument()
|
||||
{
|
||||
$this->expectException(\FuzeWorks\Exception\InvalidArgumentException::class);
|
||||
$this->configurator->setDebugAddress(null);
|
||||
}
|
||||
}
|
||||
|
||||
class MockComponent implements iComponent
|
||||
@ -492,6 +482,7 @@ class MockComponent implements iComponent
|
||||
|
||||
public function getClasses(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function onAddComponent(Configurator $configurator): Configurator
|
||||
|
@ -174,10 +174,10 @@ class eventsTest extends CoreTestAbstract
|
||||
// First add the listener, expect it to be never called
|
||||
$listener = $this->getMockBuilder(Observer::class)->setMethods(['mockListener'])->getMock();
|
||||
$listener->expects($this->never())->method('mockListener');
|
||||
Events::addListener(array($listener, 'mockListener'), 'mockEvent', Priority::NORMAL);
|
||||
Events::addListener(array($listener, 'mockListener'), 'mockEvent');
|
||||
|
||||
// Now try and remove it
|
||||
Events::removeListener(array($listener, 'mockListener'), 'mockEvent', Priority::NORMAL);
|
||||
Events::removeListener(array($listener, 'mockListener'), 'mockEvent');
|
||||
|
||||
// And now fire the event
|
||||
Events::fireEvent('mockEvent');
|
||||
@ -219,7 +219,7 @@ class eventsTest extends CoreTestAbstract
|
||||
*/
|
||||
public function testRemoveUnsetEventListener()
|
||||
{
|
||||
$this->assertNull(Events::removeListener(function($event){}, 'emptyListenerArray', Priority::NORMAL));
|
||||
$this->assertNull(Events::removeListener(function($event){}, 'emptyListenerArray'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -229,7 +229,7 @@ class eventsTest extends CoreTestAbstract
|
||||
public function testRemoveUnsetListener()
|
||||
{
|
||||
Events::addListener(function($e) {}, 'mockEvent', Priority::NORMAL);
|
||||
$this->assertNull(Events::removeListener(function() {echo "Called"; }, 'mockEvent', Priority::NORMAL));
|
||||
$this->assertNull(Events::removeListener(function() {echo "Called"; }, 'mockEvent'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -298,8 +298,8 @@ class eventsTest extends CoreTestAbstract
|
||||
|
||||
class Observer
|
||||
{
|
||||
public function mockMethod() {}
|
||||
public function mockListener($event) {}
|
||||
public function mockMethod(): void {}
|
||||
public function mockListener($event): void {}
|
||||
}
|
||||
|
||||
class MockEvent extends Event
|
||||
|
@ -1,328 +1,329 @@
|
||||
<?php
|
||||
/**
|
||||
* FuzeWorks Framework Core.
|
||||
*
|
||||
* The FuzeWorks PHP FrameWork
|
||||
*
|
||||
* Copyright (C) 2013-2019 TechFuze
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @author TechFuze
|
||||
* @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
*
|
||||
* @link http://techfuze.net/fuzeworks
|
||||
* @since Version 0.0.1
|
||||
*
|
||||
* @version Version 1.3.0
|
||||
*/
|
||||
|
||||
use FuzeWorks\Factory;
|
||||
use FuzeWorks\Exception\FactoryException;
|
||||
|
||||
/**
|
||||
* Class FactoryTest.
|
||||
*
|
||||
* Will test the FuzeWorks Factory.
|
||||
* @coversDefaultClass \FuzeWorks\Factory
|
||||
*/
|
||||
class factoryTest extends CoreTestAbstract
|
||||
{
|
||||
|
||||
/**
|
||||
* @covers ::getInstance
|
||||
*/
|
||||
public function testCanLoadFactory()
|
||||
{
|
||||
$this->assertInstanceOf('FuzeWorks\Factory', Factory::getInstance());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::getInstance
|
||||
*/
|
||||
public function testGetInstance()
|
||||
{
|
||||
// Add the mock
|
||||
$mock = $this->getMockBuilder(MockFactory::class)->getMock();
|
||||
Factory::getInstance()->setInstance('Mock', $mock);
|
||||
|
||||
// First test a global getInstance Factory
|
||||
$this->assertInstanceOf('\FuzeWorks\Factory', Factory::getInstance());
|
||||
|
||||
// Second, test retrieving a component
|
||||
$this->assertInstanceOf(get_class($mock), Factory::getInstance('Mock'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testGetInstance
|
||||
* @covers ::getInstance
|
||||
*/
|
||||
public function testGetInstanceNotFound()
|
||||
{
|
||||
$this->expectException(FactoryException::class);
|
||||
Factory::getInstance('NotFound');
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCanLoadFactory
|
||||
* @covers ::getInstance
|
||||
*/
|
||||
public function testLoadSameInstance()
|
||||
{
|
||||
$this->assertSame(Factory::getInstance(), Factory::getInstance());
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCanLoadFactory
|
||||
* @covers ::getInstance
|
||||
* @covers ::cloneInstance
|
||||
*/
|
||||
public function testLoadDifferentInstance()
|
||||
{
|
||||
// Add the mock
|
||||
$mock = $this->getMockBuilder(MockFactory::class)->getMock();
|
||||
Factory::getInstance()->setInstance('Mock', $mock);
|
||||
|
||||
// First a situation where one is the shared instance and one is a cloned instance
|
||||
$a = Factory::getInstance('Mock');
|
||||
$b = Factory::cloneInstance('Mock');
|
||||
$this->assertInstanceOf(get_class($mock), $a);
|
||||
$this->assertInstanceOf(get_class($mock), $b);
|
||||
$this->assertNotSame($a,$b);
|
||||
|
||||
// And a situation where both are cloned instances
|
||||
$a = Factory::cloneInstance('Mock');
|
||||
$b = Factory::cloneInstance('Mock');
|
||||
$this->assertInstanceOf(get_class($mock), $a);
|
||||
$this->assertInstanceOf(get_class($mock), $b);
|
||||
$this->assertNotSame($a,$b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCanLoadFactory
|
||||
* @covers ::getInstance
|
||||
* @covers ::setInstance
|
||||
*/
|
||||
public function testObjectsSameInstance()
|
||||
{
|
||||
// Create mock
|
||||
$mock = $this->getMockBuilder(MockFactory::class)->setMethods(['mockListener'])->getMock();
|
||||
|
||||
// Test not set
|
||||
$this->assertFalse(isset(Factory::getInstance()->mock));
|
||||
|
||||
// Same instance factories
|
||||
/** @var Factory $factory1 */
|
||||
/** @var Factory $factory2 */
|
||||
$factory1 = Factory::getInstance()->setInstance('Mock', $mock);
|
||||
$factory2 = Factory::getInstance()->setInstance('Mock', $mock);
|
||||
|
||||
// Return the mocks
|
||||
$this->assertSame($factory1->mock, $factory2->mock);
|
||||
|
||||
// Different instance factories
|
||||
$factory3 = Factory::getInstance()->setInstance('Mock', $mock);
|
||||
$factory4 = Factory::getInstance()->setInstance('Mock', $mock);
|
||||
|
||||
// Return the mocks
|
||||
$this->assertSame($factory3->mock, $factory4->mock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testObjectsSameInstance
|
||||
* @covers ::getInstance
|
||||
* @covers ::setInstance
|
||||
* @covers ::cloneInstance
|
||||
*/
|
||||
public function testObjectsDifferentInstance()
|
||||
{
|
||||
// Create mock
|
||||
$mock = $this->getMockBuilder(MockFactory::class)->getMock();
|
||||
|
||||
// Same instance factories
|
||||
$factory1 = Factory::getInstance()->setInstance('Mock', $mock);
|
||||
$factory2 = Factory::getInstance()->setInstance('Mock', $mock);
|
||||
|
||||
// Clone the instance in factory2
|
||||
$factory2mock = $factory2->cloneInstance('Mock');
|
||||
|
||||
// Should be true, since both Factories use the same Mock instance
|
||||
$this->assertSame($factory1->mock, $factory2mock);
|
||||
|
||||
// Different instance factories
|
||||
$factory3 = Factory::getInstance()->setInstance('Mock', $mock);
|
||||
$factory4 = Factory::getInstance()->setInstance('Mock', $mock);
|
||||
|
||||
// Should be same for now
|
||||
$this->assertSame($factory3->mock, $factory4->mock);
|
||||
|
||||
// Clone the instance in factory4
|
||||
$factory4mock = $factory4->cloneInstance('Mock', true);
|
||||
|
||||
// Should be false, since both Factories use a different Mock instance
|
||||
$this->assertNotSame($factory3->mock, $factory4mock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCanLoadFactory
|
||||
* @covers ::cloneInstance
|
||||
*/
|
||||
public function testCloneInstanceWrongClassname()
|
||||
{
|
||||
// Get factory
|
||||
$factory = new Factory;
|
||||
|
||||
// Attempt
|
||||
$this->expectException(FactoryException::class);
|
||||
$factory->cloneInstance('fake');
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCanLoadFactory
|
||||
* @covers ::getInstance
|
||||
* @covers ::newInstance
|
||||
*/
|
||||
public function testNewFactoryInstance()
|
||||
{
|
||||
// Load the different factories
|
||||
$factory = new Factory();
|
||||
$factory2 = Factory::getInstance();
|
||||
|
||||
// Test if the objects are different factory instances
|
||||
$this->assertNotSame($factory, $factory2);
|
||||
|
||||
// And test if all ClassInstances are the same
|
||||
$this->assertSame($factory->config, $factory2->config);
|
||||
$this->assertSame($factory->logger, $factory2->logger);
|
||||
$this->assertSame($factory->events, $factory2->events);
|
||||
$this->assertSame($factory->libraries, $factory2->libraries);
|
||||
$this->assertSame($factory->helpers, $factory2->helpers);
|
||||
|
||||
// And test when changing one classInstance
|
||||
$factory->newInstance('Helpers');
|
||||
$this->assertNotSame($factory->helpers, $factory2->helpers);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testNewFactoryInstance
|
||||
* @covers ::newInstance
|
||||
*/
|
||||
public function testFactoryNewInstanceNotExist()
|
||||
{
|
||||
// Load the factory
|
||||
$factory = new Factory;
|
||||
|
||||
// First, it does not exist
|
||||
$this->expectException(FactoryException::class);
|
||||
$factory->newInstance('fake');
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testNewFactoryInstance
|
||||
* @covers ::newInstance
|
||||
*/
|
||||
public function testFactoryNewInstanceWrongNamespace()
|
||||
{
|
||||
// Load the factory
|
||||
$factory = new Factory;
|
||||
|
||||
// Second, it just fails
|
||||
$this->expectException(FactoryException::class);
|
||||
$factory->newInstance('helpers', 'Test\\');
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testNewFactoryInstance
|
||||
* @covers ::setInstance
|
||||
* @covers ::removeInstance
|
||||
*/
|
||||
public function testRemoveInstance()
|
||||
{
|
||||
// Load the factory
|
||||
$factory = new Factory;
|
||||
|
||||
// Create the object
|
||||
$object = new MockObject;
|
||||
|
||||
// Add it to the factory
|
||||
$factory->setInstance('test', $object);
|
||||
|
||||
// Test if it is there
|
||||
$this->assertObjectHasAttribute('test', $factory);
|
||||
$this->assertSame($object, $factory->test);
|
||||
|
||||
// Now remove it
|
||||
$factory->removeInstance('test');
|
||||
|
||||
// Assert that it's gone
|
||||
$this->assertObjectNotHasAttribute('test', $factory);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testRemoveInstance
|
||||
* @covers ::removeInstance
|
||||
*/
|
||||
public function testRemoveInstanceNotExist()
|
||||
{
|
||||
// Load the factory
|
||||
$factory = new Factory;
|
||||
|
||||
// Test
|
||||
$this->expectException(FactoryException::class);
|
||||
$factory->removeInstance('fake');
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCanLoadFactory
|
||||
* @covers ::instanceIsset
|
||||
* @covers ::setInstance
|
||||
*/
|
||||
public function testInstanceIsset()
|
||||
{
|
||||
// Load the factory
|
||||
$factory = new Factory;
|
||||
|
||||
// Test if not set and add instance
|
||||
$this->assertFalse($factory->instanceIsset('test'));
|
||||
$factory->setInstance('test', 5);
|
||||
|
||||
// Test if isset and value
|
||||
$this->assertTrue($factory->instanceIsset('test'));
|
||||
$this->assertEquals(5, $factory->test);
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
$factory = Factory::getInstance();
|
||||
if (isset($factory->mock))
|
||||
$factory->removeInstance('mock');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class MockFactory {
|
||||
|
||||
}
|
||||
|
||||
class MockObject {
|
||||
|
||||
<?php
|
||||
/**
|
||||
* FuzeWorks Framework Core.
|
||||
*
|
||||
* The FuzeWorks PHP FrameWork
|
||||
*
|
||||
* Copyright (C) 2013-2019 TechFuze
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @author TechFuze
|
||||
* @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
*
|
||||
* @link http://techfuze.net/fuzeworks
|
||||
* @since Version 0.0.1
|
||||
*
|
||||
* @version Version 1.3.0
|
||||
*/
|
||||
|
||||
use FuzeWorks\Factory;
|
||||
use FuzeWorks\Exception\FactoryException;
|
||||
|
||||
/**
|
||||
* Class FactoryTest.
|
||||
*
|
||||
* Will test the FuzeWorks Factory.
|
||||
* @coversDefaultClass \FuzeWorks\Factory
|
||||
*/
|
||||
class factoryTest extends CoreTestAbstract
|
||||
{
|
||||
|
||||
/**
|
||||
* @covers ::getInstance
|
||||
*/
|
||||
public function testCanLoadFactory()
|
||||
{
|
||||
$this->assertInstanceOf('FuzeWorks\Factory', Factory::getInstance());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::getInstance
|
||||
*/
|
||||
public function testGetInstance()
|
||||
{
|
||||
// Add the mock
|
||||
$mock = $this->getMockBuilder(MockFactory::class)->getMock();
|
||||
Factory::getInstance()->setInstance('Mock', $mock);
|
||||
|
||||
// First test a global getInstance Factory
|
||||
$this->assertInstanceOf('\FuzeWorks\Factory', Factory::getInstance());
|
||||
|
||||
// Second, test retrieving a component
|
||||
$this->assertInstanceOf(get_class($mock), Factory::getInstance('Mock'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testGetInstance
|
||||
* @covers ::getInstance
|
||||
*/
|
||||
public function testGetInstanceNotFound()
|
||||
{
|
||||
$this->expectException(FactoryException::class);
|
||||
Factory::getInstance('NotFound');
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCanLoadFactory
|
||||
* @covers ::getInstance
|
||||
*/
|
||||
public function testLoadSameInstance()
|
||||
{
|
||||
$this->assertSame(Factory::getInstance(), Factory::getInstance());
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCanLoadFactory
|
||||
* @covers ::getInstance
|
||||
* @covers ::cloneInstance
|
||||
*/
|
||||
public function testLoadDifferentInstance()
|
||||
{
|
||||
// Add the mock
|
||||
$mock = $this->getMockBuilder(MockFactory::class)->getMock();
|
||||
Factory::getInstance()->setInstance('Mock', $mock);
|
||||
|
||||
// First a situation where one is the shared instance and one is a cloned instance
|
||||
$a = Factory::getInstance('Mock');
|
||||
$b = Factory::cloneInstance('Mock');
|
||||
$this->assertInstanceOf(get_class($mock), $a);
|
||||
$this->assertInstanceOf(get_class($mock), $b);
|
||||
$this->assertNotSame($a,$b);
|
||||
|
||||
// And a situation where both are cloned instances
|
||||
$a = Factory::cloneInstance('Mock');
|
||||
$b = Factory::cloneInstance('Mock');
|
||||
$this->assertInstanceOf(get_class($mock), $a);
|
||||
$this->assertInstanceOf(get_class($mock), $b);
|
||||
$this->assertNotSame($a,$b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCanLoadFactory
|
||||
* @covers ::getInstance
|
||||
* @covers ::setInstance
|
||||
*/
|
||||
public function testObjectsSameInstance()
|
||||
{
|
||||
// Create mock
|
||||
$mock = $this->getMockBuilder(MockFactory::class)->setMethods(['mockListener'])->getMock();
|
||||
|
||||
// Test not set
|
||||
$this->assertFalse(isset(Factory::getInstance()->mock));
|
||||
|
||||
// Same instance factories
|
||||
/** @var Factory $factory1 */
|
||||
/** @var Factory $factory2 */
|
||||
$factory1 = Factory::getInstance()->setInstance('Mock', $mock);
|
||||
$factory2 = Factory::getInstance()->setInstance('Mock', $mock);
|
||||
|
||||
// Return the mocks
|
||||
$this->assertSame($factory1->mock, $factory2->mock);
|
||||
|
||||
// Different instance factories
|
||||
$factory3 = Factory::getInstance()->setInstance('Mock', $mock);
|
||||
$factory4 = Factory::getInstance()->setInstance('Mock', $mock);
|
||||
|
||||
// Return the mocks
|
||||
$this->assertSame($factory3->mock, $factory4->mock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testObjectsSameInstance
|
||||
* @covers ::getInstance
|
||||
* @covers ::setInstance
|
||||
* @covers ::cloneInstance
|
||||
*/
|
||||
public function testObjectsDifferentInstance()
|
||||
{
|
||||
// Create mock
|
||||
$mock = $this->getMockBuilder(MockFactory::class)->getMock();
|
||||
|
||||
// Same instance factories
|
||||
$factory1 = Factory::getInstance()->setInstance('Mock', $mock);
|
||||
$factory2 = Factory::getInstance()->setInstance('Mock', $mock);
|
||||
|
||||
// Clone the instance in factory2
|
||||
$factory2mock = $factory2->cloneInstance('Mock');
|
||||
|
||||
// Should be true, since both Factories use the same Mock instance
|
||||
$this->assertSame($factory1->mock, $factory2mock);
|
||||
|
||||
// Different instance factories
|
||||
$factory3 = Factory::getInstance()->setInstance('Mock', $mock);
|
||||
$factory4 = Factory::getInstance()->setInstance('Mock', $mock);
|
||||
|
||||
// Should be same for now
|
||||
$this->assertSame($factory3->mock, $factory4->mock);
|
||||
|
||||
// Clone the instance in factory4
|
||||
$factory4mock = $factory4->cloneInstance('Mock', true);
|
||||
|
||||
// Should be false, since both Factories use a different Mock instance
|
||||
$this->assertNotSame($factory3->mock, $factory4mock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCanLoadFactory
|
||||
* @covers ::cloneInstance
|
||||
*/
|
||||
public function testCloneInstanceWrongClassname()
|
||||
{
|
||||
// Get factory
|
||||
$factory = new Factory;
|
||||
|
||||
// Attempt
|
||||
$this->expectException(FactoryException::class);
|
||||
$factory->cloneInstance('fake');
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCanLoadFactory
|
||||
* @covers ::getInstance
|
||||
* @covers ::newInstance
|
||||
*/
|
||||
public function testNewFactoryInstance()
|
||||
{
|
||||
// Load the different factories
|
||||
$factory = new Factory();
|
||||
$factory2 = Factory::getInstance();
|
||||
|
||||
// Test if the objects are different factory instances
|
||||
$this->assertNotSame($factory, $factory2);
|
||||
|
||||
// And test if all ClassInstances are the same
|
||||
$this->assertSame($factory->config, $factory2->config);
|
||||
$this->assertSame($factory->logger, $factory2->logger);
|
||||
$this->assertSame($factory->events, $factory2->events);
|
||||
$this->assertSame($factory->libraries, $factory2->libraries);
|
||||
$this->assertSame($factory->helpers, $factory2->helpers);
|
||||
$this->assertSame($factory->storage, $factory2->storage);
|
||||
|
||||
// And test when changing one classInstance
|
||||
$factory->newInstance('Helpers');
|
||||
$this->assertNotSame($factory->helpers, $factory2->helpers);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testNewFactoryInstance
|
||||
* @covers ::newInstance
|
||||
*/
|
||||
public function testFactoryNewInstanceNotExist()
|
||||
{
|
||||
// Load the factory
|
||||
$factory = new Factory;
|
||||
|
||||
// First, it does not exist
|
||||
$this->expectException(FactoryException::class);
|
||||
$factory->newInstance('fake');
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testNewFactoryInstance
|
||||
* @covers ::newInstance
|
||||
*/
|
||||
public function testFactoryNewInstanceWrongNamespace()
|
||||
{
|
||||
// Load the factory
|
||||
$factory = new Factory;
|
||||
|
||||
// Second, it just fails
|
||||
$this->expectException(FactoryException::class);
|
||||
$factory->newInstance('helpers', 'Test\\');
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testNewFactoryInstance
|
||||
* @covers ::setInstance
|
||||
* @covers ::removeInstance
|
||||
*/
|
||||
public function testRemoveInstance()
|
||||
{
|
||||
// Load the factory
|
||||
$factory = new Factory;
|
||||
|
||||
// Create the object
|
||||
$object = new MockObject;
|
||||
|
||||
// Add it to the factory
|
||||
$factory->setInstance('test', $object);
|
||||
|
||||
// Test if it is there
|
||||
$this->assertObjectHasAttribute('test', $factory);
|
||||
$this->assertSame($object, $factory->test);
|
||||
|
||||
// Now remove it
|
||||
$factory->removeInstance('test');
|
||||
|
||||
// Assert that it's gone
|
||||
$this->assertObjectNotHasAttribute('test', $factory);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testRemoveInstance
|
||||
* @covers ::removeInstance
|
||||
*/
|
||||
public function testRemoveInstanceNotExist()
|
||||
{
|
||||
// Load the factory
|
||||
$factory = new Factory;
|
||||
|
||||
// Test
|
||||
$this->expectException(FactoryException::class);
|
||||
$factory->removeInstance('fake');
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCanLoadFactory
|
||||
* @covers ::instanceIsset
|
||||
* @covers ::setInstance
|
||||
*/
|
||||
public function testInstanceIsset()
|
||||
{
|
||||
// Load the factory
|
||||
$factory = new Factory;
|
||||
|
||||
// Test if not set and add instance
|
||||
$this->assertFalse($factory->instanceIsset('test'));
|
||||
$factory->setInstance('test', 5);
|
||||
|
||||
// Test if isset and value
|
||||
$this->assertTrue($factory->instanceIsset('test'));
|
||||
$this->assertEquals(5, $factory->test);
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
$factory = Factory::getInstance();
|
||||
if (isset($factory->mock))
|
||||
$factory->removeInstance('mock');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class MockFactory {
|
||||
|
||||
}
|
||||
|
||||
class MockObject {
|
||||
|
||||
}
|
@ -36,6 +36,7 @@
|
||||
|
||||
use FuzeWorks\Exception\LibraryException;
|
||||
use FuzeWorks\Factory;
|
||||
use FuzeWorks\iLibrary;
|
||||
use FuzeWorks\Libraries;
|
||||
|
||||
/**
|
||||
@ -167,10 +168,10 @@ class libraryTest extends CoreTestAbstract
|
||||
*/
|
||||
public function testAddLibraryObject()
|
||||
{
|
||||
$z = new stdClass();
|
||||
$this->libraries->addLibraryObject('TestAddLibraryObject', $z);
|
||||
$lib = $this->getMockForAbstractClass(iLibrary::class);
|
||||
$this->libraries->addLibraryObject('TestAddLibraryObject', $lib);
|
||||
|
||||
$this->assertEquals($z, $this->libraries->get('TestAddLibraryObject'));
|
||||
$this->assertEquals($lib, $this->libraries->get('TestAddLibraryObject'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -203,13 +204,13 @@ class libraryTest extends CoreTestAbstract
|
||||
public function testAddLibraryWithAutoloader()
|
||||
{
|
||||
// First assert the extra class can't be autoloaded
|
||||
$this->assertFalse(class_exists('FuzeWorks\Test\TestAddLibraryWithAutoloader\SomeExtraClass', true));
|
||||
$this->assertFalse(class_exists('FuzeWorks\Test\TestAddLibraryWithAutoloader\SomeExtraClass'));
|
||||
|
||||
// Load the library and test the instance type
|
||||
$this->assertInstanceOf('Application\Library\TestAddLibraryWithAutoloader', $this->libraries->get('TestAddLibraryWithAutoloader'));
|
||||
|
||||
// Afterwards test if the loader has been correctly added
|
||||
$this->assertTrue(class_exists('FuzeWorks\Test\TestAddLibraryWithAutoloader\SomeExtraClass', true));
|
||||
$this->assertTrue(class_exists('FuzeWorks\Test\TestAddLibraryWithAutoloader\SomeExtraClass'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,5 +57,5 @@ class coreStartEventTest extends CoreTestAbstract
|
||||
}
|
||||
|
||||
class MockStartEvent {
|
||||
public function mockMethod() {}
|
||||
public function mockMethod(): void {}
|
||||
}
|
@ -38,7 +38,7 @@ use FuzeWorks\iLibrary;
|
||||
|
||||
class TestGetLibraryParametersFromConfig implements iLibrary {
|
||||
|
||||
public $parameters;
|
||||
public mixed $parameters;
|
||||
|
||||
public function __construct($parameters)
|
||||
{
|
||||
|
@ -1,19 +1,23 @@
|
||||
<?xml version="1.0"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd" bootstrap="autoload.php" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" stopOnError="false" stopOnFailure="false" stopOnIncomplete="false" stopOnSkipped="false" colors="false">
|
||||
<coverage processUncoveredFiles="false">
|
||||
<include>
|
||||
<directory suffix=".php">../</directory>
|
||||
</include>
|
||||
<exclude>
|
||||
<directory suffix=".php">../vendor/</directory>
|
||||
<directory suffix=".php">../test/</directory>
|
||||
<directory suffix=".php">../src/Layout/</directory>
|
||||
<directory suffix=".php">../src/Config/</directory>
|
||||
</exclude>
|
||||
</coverage>
|
||||
<testsuites>
|
||||
<testsuite name="Core Suite">
|
||||
<directory>./</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<?xml version="1.0"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd" bootstrap="autoload.php" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" stopOnError="false" stopOnFailure="false" stopOnIncomplete="false" stopOnSkipped="false" colors="false">
|
||||
<coverage processUncoveredFiles="false">
|
||||
<include>
|
||||
<directory suffix=".php">../</directory>
|
||||
</include>
|
||||
<exclude>
|
||||
<directory suffix=".php">../vendor/</directory>
|
||||
<directory suffix=".php">../test/</directory>
|
||||
<directory suffix=".php">../src/Layout/</directory>
|
||||
<directory suffix=".php">../src/Config/</directory>
|
||||
</exclude>
|
||||
</coverage>
|
||||
<testsuites>
|
||||
<testsuite name="core">
|
||||
<directory>./core</directory>
|
||||
<directory>./events</directory>
|
||||
</testsuite>
|
||||
<testsuite name="storage">
|
||||
<directory>./storage</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
</phpunit>
|
@ -58,7 +58,7 @@ class TestLoadHeaderNotIPluginHeaderHeader
|
||||
return '\FuzeWorks\UnitTest\Plugins\TestLoadHeaderNotIPluginHeader\TestLoadPlugin';
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
public function init(): void
|
||||
{
|
||||
}
|
||||
}
|
200
test/storage/StorageCacheTest.php
Normal file
200
test/storage/StorageCacheTest.php
Normal file
@ -0,0 +1,200 @@
|
||||
<?php
|
||||
/**
|
||||
* FuzeWorks ObjectStorage Component.
|
||||
*
|
||||
* The FuzeWorks PHP FrameWork
|
||||
*
|
||||
* Copyright (C) 2013-2020 i15
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @author i15
|
||||
* @copyright Copyright (c) 2013 - 2020, i15. (https://i15.nl)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
*
|
||||
* @since Version 1.3.0
|
||||
*
|
||||
* @version Version 1.3.0
|
||||
*/
|
||||
|
||||
namespace storage;
|
||||
|
||||
use FuzeWorks\Factory;
|
||||
use FuzeWorks\Storage;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
|
||||
class StorageCacheTest extends TestCase
|
||||
{
|
||||
|
||||
private CacheInterface $cache;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->loadProvider();
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
// Always clear the cache after every test
|
||||
$this->cache->clear();
|
||||
}
|
||||
|
||||
private function loadProvider()
|
||||
{
|
||||
/** @var Storage $objectStorageComponent */
|
||||
$objectStorageComponent = Factory::getInstance('storage');
|
||||
$this->cache = $objectStorageComponent->getCache();
|
||||
}
|
||||
|
||||
public function testFoundation()
|
||||
{
|
||||
$this->assertInstanceOf('\Psr\SimpleCache\CacheInterface', $this->cache);
|
||||
$this->assertInstanceOf('\FuzeWorks\Storage\StorageCache', $this->cache);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testFoundation
|
||||
*/
|
||||
public function testSetGetAndHas()
|
||||
{
|
||||
$testData = ['hello', 'world'];
|
||||
|
||||
// First check the data isn't there
|
||||
$this->assertFalse($this->cache->has('testData'));
|
||||
|
||||
// Then write it
|
||||
$this->assertTrue($this->cache->set('testData', $testData));
|
||||
|
||||
// Assert it is there and check its contents
|
||||
$this->assertTrue($this->cache->has('testData'));
|
||||
$this->assertEquals(['hello', 'world'], $this->cache->get('testData'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testSetGetAndHas
|
||||
*/
|
||||
public function testGetDefaultValue()
|
||||
{
|
||||
// Verify that no value exists
|
||||
$this->assertFalse($this->cache->has('testData'));
|
||||
$this->assertNull($this->cache->get('testData'));
|
||||
|
||||
// And check if the default value is returned
|
||||
$this->assertEquals('default!', $this->cache->get('testData', 'default!'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testSetGetAndHas
|
||||
*/
|
||||
public function testDeleteValue()
|
||||
{
|
||||
// Verify that none exist
|
||||
$this->assertFalse($this->cache->has('testData'));
|
||||
|
||||
// Write some data
|
||||
$this->assertTrue($this->cache->set('testData', 'someValue'));
|
||||
$this->assertEquals('someValue', $this->cache->get('testData'));
|
||||
$this->assertTrue($this->cache->has('testData'));
|
||||
|
||||
// Delete it
|
||||
$this->assertTrue($this->cache->delete('testData'));
|
||||
$this->assertFalse($this->cache->has('testData'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testDeleteValue
|
||||
*/
|
||||
public function testClear()
|
||||
{
|
||||
// Write some data
|
||||
$this->assertTrue($this->cache->set('testData1', 'value1'));
|
||||
$this->assertTrue($this->cache->set('testData2', 'value2'));
|
||||
|
||||
// Then clear it off
|
||||
$this->assertTrue($this->cache->clear());
|
||||
$this->assertFalse($this->cache->has('testData1'));
|
||||
$this->assertFalse($this->cache->has('testData2'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testDeleteValue
|
||||
*/
|
||||
public function testMultiple()
|
||||
{
|
||||
// First check that none of the variables exist
|
||||
$this->assertFalse($this->cache->has('testData1'));
|
||||
$this->assertFalse($this->cache->has('testData2'));
|
||||
$this->assertFalse($this->cache->has('testData3'));
|
||||
|
||||
// With a get multiple, and default
|
||||
$this->assertEquals([
|
||||
'testData1' => 'default',
|
||||
'testData2' => 'default',
|
||||
'testData3' => 'default'
|
||||
], $this->cache->getMultiple(['testData1', 'testData2', 'testData3'], 'default'));
|
||||
|
||||
// Write multiple
|
||||
$this->assertTrue($this->cache->setMultiple([
|
||||
'testData1' => 'value1',
|
||||
'testData2' => 'value2',
|
||||
'testData3' => 'value3'
|
||||
]));
|
||||
|
||||
// Test the contents
|
||||
$this->assertEquals([
|
||||
'testData1' => 'value1',
|
||||
'testData2' => 'value2',
|
||||
'testData3' => 'value3'
|
||||
], $this->cache->getMultiple(['testData1', 'testData2', 'testData3'], 'default'));
|
||||
|
||||
// And also delete them all
|
||||
$this->assertTrue($this->cache->deleteMultiple(['testData1', 'testData2', 'testData3']));
|
||||
$this->assertFalse($this->cache->has('testData1'));
|
||||
$this->assertFalse($this->cache->has('testData2'));
|
||||
$this->assertFalse($this->cache->has('testData3'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testSetGetAndHas
|
||||
*/
|
||||
public function testTTL()
|
||||
{
|
||||
$testData = ['hello', 'world'];
|
||||
|
||||
// First check the data isn't there
|
||||
$this->assertFalse($this->cache->has('testData'));
|
||||
|
||||
// Then write it
|
||||
$this->assertTrue($this->cache->set('testData', $testData, 1));
|
||||
|
||||
// Assert it is there and check its contents
|
||||
$this->assertTrue($this->cache->has('testData'));
|
||||
$this->assertEquals(['hello', 'world'], $this->cache->get('testData'));
|
||||
|
||||
// Then wait 2 secs
|
||||
sleep(2);
|
||||
|
||||
// And check again
|
||||
$this->assertFalse($this->cache->has('testData'));
|
||||
}
|
||||
}
|
218
test/storage/StorageProviderTest.php
Normal file
218
test/storage/StorageProviderTest.php
Normal file
@ -0,0 +1,218 @@
|
||||
<?php
|
||||
/**
|
||||
* FuzeWorks ObjectStorage Component.
|
||||
*
|
||||
* The FuzeWorks PHP FrameWork
|
||||
*
|
||||
* Copyright (C) 2013-2020 i15
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @author i15
|
||||
* @copyright Copyright (c) 2013 - 2020, i15. (https://i15.nl)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
*
|
||||
* @since Version 1.3.0
|
||||
*
|
||||
* @version Version 1.3.0
|
||||
*/
|
||||
|
||||
namespace storage;
|
||||
|
||||
use FuzeWorks\Factory;
|
||||
use FuzeWorks\Storage\iStorageProvider;
|
||||
use FuzeWorks\Storage;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* Class ObjectStorageProviderTest
|
||||
*
|
||||
* @todo getIndex() method
|
||||
*/
|
||||
class StorageProviderTest extends TestCase
|
||||
{
|
||||
|
||||
private iStorageProvider $provider;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->loadProvider();
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
// Always clear the provider at the end
|
||||
$this->provider->clear();
|
||||
}
|
||||
|
||||
private function loadProvider()
|
||||
{
|
||||
/** @var Storage $objectStorageComponent */
|
||||
$objectStorageComponent = Factory::getInstance('storage');
|
||||
$this->provider = $objectStorageComponent->getStorage();
|
||||
}
|
||||
|
||||
public function testFoundation()
|
||||
{
|
||||
$this->assertInstanceOf('\FuzeWorks\Storage\iStorageProvider', $this->provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testFoundation
|
||||
*/
|
||||
public function testSave()
|
||||
{
|
||||
$testData = ['hello', 'world', 'foo' => 'bar'];
|
||||
|
||||
// First assert it does not exist yet
|
||||
$this->assertNull($this->provider->getItem('testData'));
|
||||
$this->assertFalse($this->provider->hasItem('testData'));
|
||||
|
||||
// Write the data
|
||||
$this->assertTrue($this->provider->save('testData', $testData));
|
||||
|
||||
// Read the data
|
||||
$this->assertTrue($this->provider->hasItem('testData'));
|
||||
$this->assertEquals(['hello', 'world', 'foo' => 'bar'], $this->provider->getItem('testData'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testSave
|
||||
*/
|
||||
public function testDeleteItem()
|
||||
{
|
||||
$testData = ['o', 'm', 'g'];
|
||||
|
||||
// First assert that the data does not exist yet
|
||||
$this->assertNull($this->provider->getItem('testDeleteData'));
|
||||
|
||||
// Write the data
|
||||
$this->assertTrue($this->provider->save('testDeleteData', $testData));
|
||||
|
||||
// Read the data
|
||||
$this->assertEquals(['o', 'm', 'g'], $this->provider->getItem('testDeleteData'));
|
||||
|
||||
// Delete the data
|
||||
$this->assertTrue($this->provider->deleteItem('testDeleteData'));
|
||||
|
||||
// And test that it is truly gone
|
||||
$this->assertNull($this->provider->getItem('testDeleteData'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testDeleteItem
|
||||
*/
|
||||
public function testDeleteItems()
|
||||
{
|
||||
$testData = 'lord';
|
||||
$testData2 = 'almighty';
|
||||
|
||||
// First assert that the data does not exist yet
|
||||
$this->assertNull($this->provider->getItem('testDeleteData1'));
|
||||
$this->assertNull($this->provider->getItem('testDeleteData2'));
|
||||
|
||||
// Write the data
|
||||
$this->assertTrue($this->provider->save('testDeleteData1', $testData));
|
||||
$this->assertTrue($this->provider->save('testDeleteData2', $testData2));
|
||||
|
||||
// Read the data
|
||||
$this->assertEquals(
|
||||
['testDeleteData1' => 'lord', 'testDeleteData2' => 'almighty'],
|
||||
$this->provider->getItems(['testDeleteData1', 'testDeleteData2'])
|
||||
);
|
||||
|
||||
// Delete the data
|
||||
$this->assertTrue($this->provider->deleteItems(['testDeleteData1', 'testDeleteData2']));
|
||||
|
||||
// And test that it is truly gone
|
||||
$this->assertNull($this->provider->getItem('testDeleteData1'));
|
||||
$this->assertNull($this->provider->getItem('testDeleteData2'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testDeleteItems
|
||||
*/
|
||||
public function testClear()
|
||||
{
|
||||
$testData = ['not', 'my', 'department'];
|
||||
|
||||
// First assert it does not exist yet
|
||||
$this->assertNull($this->provider->getItem('testClearData'));
|
||||
|
||||
$this->provider->save('testClearData', $testData);
|
||||
|
||||
// Test that it can be read
|
||||
$this->assertEquals(['not', 'my', 'department'], $this->provider->getItem('testClearData'));
|
||||
|
||||
// Then attempt to clean it
|
||||
$this->assertTrue($this->provider->clear());
|
||||
|
||||
// And check that it cannot be read
|
||||
$this->assertNull($this->provider->getItem('testClearData'));
|
||||
}
|
||||
|
||||
public function testItemNotExist()
|
||||
{
|
||||
$this->assertNull($this->provider->getItem('doesNotExist'));
|
||||
}
|
||||
|
||||
public function testGetMultipleItems()
|
||||
{
|
||||
$testData1 = ['tao', 'te', 'ching'];
|
||||
$testData2 = ['plato', 'aristotle'];
|
||||
|
||||
// First assert they do not exist
|
||||
$this->assertNull($this->provider->getItem('philo1'));
|
||||
$this->assertNull($this->provider->getItem('philo2'));
|
||||
$this->assertEquals(['philo1' => null, 'philo2' => null], $this->provider->getItems(['philo1', 'philo2']));
|
||||
|
||||
// Then write both
|
||||
$this->assertTrue($this->provider->save('philo1', $testData1));
|
||||
$this->assertTrue($this->provider->save('philo2', $testData2));
|
||||
|
||||
// Then read
|
||||
$this->assertEquals([
|
||||
'philo1' => ['tao', 'te', 'ching'],
|
||||
'philo2' => ['plato', 'aristotle']
|
||||
], $this->provider->getItems(['philo1', 'philo2']));
|
||||
}
|
||||
|
||||
public function testItemMetaData()
|
||||
{
|
||||
$testData = ['meine', 'gute'];
|
||||
$metaData = ['someKey' => 'someValue'];
|
||||
|
||||
// First assert that the data does not exist
|
||||
$this->assertNull($this->provider->getItem('testData'));
|
||||
$this->assertNull($this->provider->getItemMeta('testData'));
|
||||
|
||||
// Then save the data
|
||||
$this->assertTrue($this->provider->save('testData', $testData, $metaData));
|
||||
|
||||
// Check the metaData
|
||||
$this->assertEquals(['someKey' => 'someValue'], $this->provider->getItemMeta('testData'));
|
||||
|
||||
// Remove the key
|
||||
$this->provider->deleteItem('testData');
|
||||
$this->assertNull($this->provider->getItemMeta('testData'));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user