From f633b981d9fd08765939fdbacf52ca70947c6819 Mon Sep 17 00:00:00 2001 From: Andrew Male Date: Tue, 15 Feb 2022 05:58:20 -0500 Subject: [PATCH] Release v1.1 - PHP 8.0 Upgrade Version 1.1 of Stoic Core includes the following features: * Upgraded code to 8.0 signatures * Updated configs to specify 8.0+ * Checked code for consistency * Checked comments for consistency * Added EnumBase::tryGet() to utilize new static return type w/o breaking old code * Fixed compatibility problems w/ tests for new 8.0+ signatures --- .travis.yml | 4 +- Chain/ChainHelper.php | 84 +++++++-------- Chain/DispatchBase.php | 141 +++++++++++------------- Chain/NodeBase.php | 48 ++++----- Log/AppenderBase.php | 5 +- Log/Logger.php | 82 +++++++------- Log/Message.php | 75 ++++++------- Log/MessageDispatch.php | 19 ++-- Log/NullAppender.php | 14 +-- Tests/Chain/ChainTest.php | 6 +- Tests/Chain/LoggingTest.php | 4 +- Tests/Chain/ValidityTest.php | 6 +- Tests/Log/LoggerTest.php | 2 +- Tests/Utilities/EnumBaseTest.php | 12 +++ Utilities/EnumBase.php | 178 ++++++++++++++++++------------- Utilities/ReturnHelper.php | 106 +++++++++--------- composer.json | 4 +- 17 files changed, 406 insertions(+), 384 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4cc4e69..bd2379f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: php php: - - '7.1' - - '7.2' + - '8.0' + - '8.1' before_install: - composer install \ No newline at end of file diff --git a/Chain/ChainHelper.php b/Chain/ChainHelper.php index 9e16181..80702aa 100644 --- a/Chain/ChainHelper.php +++ b/Chain/ChainHelper.php @@ -2,32 +2,34 @@ namespace Stoic\Chain; + use JetBrains\PhpStorm\ArrayShape; + use JetBrains\PhpStorm\Pure; + /** - * Class to maintain groups (chains) of nodes - * and send events to them. + * Class to maintain groups (chains) of nodes and send events to them. * * @package Stoic\Chain - * @version 1.0.1 + * @version 1.1.0 */ class ChainHelper { /** * Group of nodes (one or more). * - * @var array + * @var NodeBase[] */ - protected $_nodes = []; + protected array $_nodes = []; /** - * Whether or not instance is an event-chain. + * Whether instance is an event-chain. * - * @var boolean + * @var bool */ - protected $_isEvent = false; + protected bool $_isEvent = false; /** - * Whether or not instance should send debug messages. - * - * @var boolean + * Whether instance should send debug messages. + * + * @var bool */ - protected $_doDebug = false; + protected bool $_doDebug = false; /** * Optional callback that receives debug messages (if enabled). * @@ -37,12 +39,11 @@ class ChainHelper { /** - * Creates new instance of ChainHelper class. If set - * as an event-chain, only one node may be linked to - * chain at any given time. - * - * @param boolean $isEvent Toggle for event-chain. - * @param boolean $doDebug Toggle for sending debug messages. + * Creates new instance of ChainHelper class. If set as an event-chain, only one node may be linked to chain at + * any given time. + * + * @param bool $isEvent Toggle for event-chain. + * @param bool $doDebug Toggle for sending debug messages. */ public function __construct(bool $isEvent = false, bool $doDebug = false) { $this->_isEvent = $isEvent; @@ -54,37 +55,36 @@ public function __construct(bool $isEvent = false, bool $doDebug = false) { /** * Toggles the use of debug messages by this instance. * - * @param boolean $doDebug Toggle for sending debug messages. + * @param bool $doDebug Toggle for sending debug messages. * @return ChainHelper */ public function toggleDebug(bool $doDebug) : ChainHelper { - $this->_doDebug = ($doDebug) ? true : false; + $this->_doDebug = $doDebug; return $this; } /** * Returns the full list of nodes linked to the chain. - * + * * @return array */ - public function getNodeList() { - $ret = array(); + public function getNodeList() : array { + $ret = []; - foreach (array_values($this->_nodes) as $node) { - $ret[] = array( - 'key' => $node->getKey(), + foreach ($this->_nodes as $node) { + $ret[] = [ + 'key' => $node->getKey(), 'version' => $node->getVersion() - ); + ]; } return $ret; } /** - * Attaches the given callback to the chain to - * receive debug messages, if enabled. Callbacks - * should accept a single string argument. + * Attaches the given callback to the chain to receive debug messages, if enabled. Callbacks should accept a + * single string argument. * * @param callable $callback Callable method/function that receives messages. * @return void @@ -96,19 +96,17 @@ public function hookLogger(callable $callback) : void { } /** - * Returns whether or not chain is setup as an - * event-chain. + * Returns whether chain is set up as an event-chain. * - * @return boolean + * @return bool */ public function isEvent() : bool { return $this->_isEvent; } /** - * Registers a NodeBase object with the chain. If - * chain is an event-chain, this will overwrite any - * existing node. If node is invalid, link will fail. + * Registers a NodeBase object with the chain. If chain is an event-chain, this will overwrite any existing node. + * If node is invalid, link will fail. * * @param NodeBase $node NodeBase object to register with chain. * @return ChainHelper @@ -140,17 +138,14 @@ public function linkNode(NodeBase $node) : ChainHelper { } /** - * Triggers distribution of given dispatch to all - * linked nodes in chain. Will return false if no - * nodes are linked, the dispatch is invalid, or - * the dispatch is consumable and has already been - * consumed. + * Triggers distribution of given dispatch to all linked nodes in chain. Will return false if no nodes are linked, + * the dispatch is invalid, or the dispatch is consumable and has already been consumed. * * @param DispatchBase $dispatch DispatchBase object to distribute to linked nodes. * @param mixed $sender Optional sender data to pass to linked nodes. - * @return boolean + * @return bool */ - public function traverse(DispatchBase &$dispatch, $sender = null) : bool { + public function traverse(DispatchBase &$dispatch, mixed $sender = null) : bool { if (count($this->_nodes) < 1) { if ($this->_doDebug) { $this->log("Attempted to traverse chain with no nodes"); @@ -211,8 +206,7 @@ public function traverse(DispatchBase &$dispatch, $sender = null) : bool { } /** - * Conditionally sends debug message to registered - * callback. + * Conditionally sends debug message to registered callback. * * @param string $message Message to send to callback. * @return void diff --git a/Chain/DispatchBase.php b/Chain/DispatchBase.php index f7d3006..4053aea 100644 --- a/Chain/DispatchBase.php +++ b/Chain/DispatchBase.php @@ -3,50 +3,48 @@ namespace Stoic\Chain; /** - * Abstract class to provide contract - * for all dispatches used with the - * chain system. - * + * Abstract class to provide contract for all dispatches used with the chain system. + * * @package Stoic\Chain - * @version 1.0.1 + * @version 1.1.0 */ abstract class DispatchBase { /** - * Whether or not the dispatch is 'consumable'. - * - * @var boolean + * Whether the dispatch is 'consumable'. + * + * @var bool */ - protected $_isConsumable = false; + protected bool $_isConsumable = false; /** - * Whether or not the dispatch should retain results. - * - * @var boolean + * Whether the dispatch should retain results. + * + * @var bool */ - protected $_isStateful = false; + protected bool $_isStateful = false; /** - * Whether or not the dispatch has been consumed by a node. - * - * @var boolean + * Whether the dispatch has been consumed by a node. + * + * @var bool */ - protected $_isConsumed = false; + protected bool $_isConsumed = false; /** * Collection of results from nodes. - * - * @var mixed[] + * + * @var mixed */ - private $_results = []; + private array $_results = []; /** - * Whether or not the dispatch is valid for processing. - * - * @var boolean + * Whether the dispatch is valid for processing. + * + * @var bool */ - protected $_isValid = false; + protected bool $_isValid = false; /** * Date and time the dispatch was made valid. - * - * @var \DateTimeInterface + * + * @var null|\DateTimeInterface */ - private $_calledDateTime = null; + private ?\DateTimeInterface $_calledDateTime = null; /** @@ -64,12 +62,10 @@ public function __toString() : string { } /** - * Marks the dispatch as having been consumed. If - * the dispatch is not consumable or has already - * been marked as consumed, returns false. Otherwise - * returns true. - * - * @return boolean + * Marks the dispatch as having been consumed. If the dispatch is not consumable or has already been marked as + * consumed, returns false. Otherwise, returns true. + * + * @return bool */ public function consume() : bool { if ($this->_isConsumable && !$this->_isConsumed) { @@ -83,7 +79,7 @@ public function consume() : bool { /** * Returns time the dispatch was marked valid. - * + * * @return \DateTimeInterface */ public function getCalledDateTime() : \DateTimeInterface { @@ -91,13 +87,12 @@ public function getCalledDateTime() : \DateTimeInterface { } /** - * Returns any results stored in dispatch. If dispatch - * is stateful, this can be multiple results, otherwise - * it will be null or a single result. - * - * @return mixed[]|mixed|null + * Returns any results stored in dispatch. If dispatch is stateful, this can be multiple results, otherwise it + * will be null or a single result. + * + * @return mixed */ - public function getResults() { + public function getResults() : mixed { if (count($this->_results) < 1) { return null; } @@ -106,51 +101,46 @@ public function getResults() { } /** - * Abstract method that handles initialization. Should - * mark dispatch as valid if successful, otherwise - * dispatch won't be usable with \ChainHelper objects. - * + * Abstract method that handles initialization. Should mark dispatch as valid if successful, otherwise dispatch + * won't be usable with ChainHelper objects. + * * @param mixed $input Initialization data for dispatch. */ - abstract public function initialize($input); + abstract public function initialize(mixed $input); /** - * Returns whether or not dispatch can be marked as - * consumed. If toggled and consumed, a \ChainHelper - * will refuse to further distribute the dispatch. - * - * @return boolean + * Returns whether dispatch can be marked as consumed. If toggled and consumed, a ChainHelper will refuse to + * further distribute the dispatch. + * + * @return bool */ public function isConsumable() : bool { return $this->_isConsumable; } /** - * Returns whether or not dispatch has been marked - * as consumed. If consumed, a \ChainHelper will - * refuse to further distribute the dispatch. - * - * @return boolean + * Returns whether dispatch has been marked as consumed. If consumed, a ChainHelper will refuse to further + * distribute the dispatch. + * + * @return bool */ public function isConsumed() : bool { return $this->_isConsumed; } /** - * Returns whether or not dispatch will hold multiple - * results during processing. - * - * @return boolean + * Returns whether dispatch will hold multiple results during processing. + * + * @return bool */ public function isStateful() : bool { return $this->_isStateful; } /** - * Returns whether or not dispatch is considered valid - * for processing by nodes. - * - * @return boolean + * Returns whether dispatch is considered valid for processing by nodes. + * + * @return bool */ public function isValid() : bool { return $this->_isValid; @@ -158,7 +148,7 @@ public function isValid() : bool { /** * Sets dispatch as consumable. - * + * * @return DispatchBase */ protected function makeConsumable() : DispatchBase { @@ -169,7 +159,7 @@ protected function makeConsumable() : DispatchBase { /** * Sets dispatch as stateful. - * + * * @return DispatchBase */ protected function makeStateful() : DispatchBase { @@ -179,9 +169,9 @@ protected function makeStateful() : DispatchBase { } /** - * Sets dispatch as valid and records the current - * date and time in UTC offset. - * + * Sets dispatch as valid and records the current date and time in UTC offset. + * + * @throws \Exception * @return DispatchBase */ protected function makeValid() : DispatchBase { @@ -193,24 +183,23 @@ protected function makeValid() : DispatchBase { /** * Returns number of results stored in dispatch. - * - * @return integer + * + * @return int */ public function numResults() : int { return count($this->_results); } /** - * Sets a result in dispatch. If dispatch is stateful - * result is added to array, otherwise it replaces any - * existing results. - * + * Sets a result in dispatch. If dispatch is stateful result is added to array, otherwise it replaces any existing + * results. + * * @param mixed $result Result data to store in dispatch. * @return DispatchBase */ - public function setResult($result) : DispatchBase { + public function setResult(mixed $result) : DispatchBase { if (!$this->_isStateful) { - $this->_results = array($result); + $this->_results = [$result]; } else { $this->_results[] = $result; } diff --git a/Chain/NodeBase.php b/Chain/NodeBase.php index c9dea82..1b2386d 100644 --- a/Chain/NodeBase.php +++ b/Chain/NodeBase.php @@ -3,26 +3,24 @@ namespace Stoic\Chain; /** - * Abstract class to provide contract - * for all nodes used with the chain - * system. - * + * Abstract class to provide contract for all nodes used with the chain system. + * * @package Stoic\Chain - * @version 1.0.1 + * @version 1.1.0 */ abstract class NodeBase { /** * Key that identifies the node. - * - * @var string + * + * @var null|string */ - protected $_key = null; + protected ?string $_key = null; /** - * Version number for the node. - * - * @var string + * Version for the node. + * + * @var null|string */ - protected $_version = null; + protected ?string $_version = null; /** @@ -36,7 +34,7 @@ public function __toString() : string { /** * Returns the node key value. - * + * * @return string */ public function getKey() : string { @@ -45,7 +43,7 @@ public function getKey() : string { /** * Returns the node version value. - * + * * @return string */ public function getVersion() : string { @@ -53,29 +51,27 @@ public function getVersion() : string { } /** - * Returns whether or not the node is considered - * valid. By default this means that there are - * non-empty values in both the 'key' and 'version' - * fields of the node. - * - * @return boolean + * Returns whether the node is considered valid. This means that there are non-empty values in both the 'key' and + * 'version' fields of the node by default. + * + * @return bool */ public function isValid() : bool { return !empty($this->_key) && !empty($this->_version); } /** - * Abstract method that handles processing of a - * provided dispatch. + * Abstract method that handles processing of a provided dispatch. * - * @param mixed $sender Sender data, optional and thus can be 'null'. + * @param mixed $sender Sender data, optional and thus can be 'null'. * @param DispatchBase $dispatch Dispatch object to process. + * @return void */ - abstract public function process($sender, DispatchBase &$dispatch); + abstract public function process(mixed $sender, DispatchBase &$dispatch) : void; /** * Sets the node key value. - * + * * @param string $key Value to use for node key. * @return NodeBase */ @@ -87,7 +83,7 @@ protected function setKey(string $key) : NodeBase { /** * Sets the node version value. - * + * * @param string $version Value to use for node version. * @return NodeBase */ diff --git a/Log/AppenderBase.php b/Log/AppenderBase.php index a0c3993..ffe6af8 100644 --- a/Log/AppenderBase.php +++ b/Log/AppenderBase.php @@ -5,10 +5,9 @@ use Stoic\Chain\NodeBase; /** - * Describes a Stoic Log Appender which can - * do many-splendored things with log messages. + * Describes a Stoic Log Appender which can do many-splendored things with log messages. * * @package Stoic\Log - * @version 1.0.1 + * @version 1.1.0 */ abstract class AppenderBase extends NodeBase { } diff --git a/Log/Logger.php b/Log/Logger.php index 9913667..a02d077 100644 --- a/Log/Logger.php +++ b/Log/Logger.php @@ -4,41 +4,42 @@ use Psr\Log\AbstractLogger; use Psr\Log\LogLevel; + use Stoic\Chain\ChainHelper; /** - * PSR-3 compliant logging class which accepts - * multiple appenders for output/handling. - * + * PSR-3 compliant logging class which accepts multiple appenders for output/handling. + * * @package Stoic\Log - * @version 1.0.1 + * @version 1.1.0 */ class Logger extends AbstractLogger { /** * Holds all assigned appenders. - * - * @var ChainHelper + * + * @var null|ChainHelper */ - private $appenders = null; + private ?ChainHelper $appenders = null; /** * Holds all messages for appenders. - * + * * @var Message[] */ - private $messages = []; + private array $messages = []; /** - * The minimum log level to push to appennders. - * + * The minimum log level to push to appenders. + * * @var string */ - private $minLevel = LogLevel::DEBUG; + private string $minLevel = LogLevel::DEBUG; + + /** - * Collection of log levels numerically indexed - * to allow for minimum level comparison. - * + * Collection of log levels numerically indexed to allow for minimum level comparison. + * * @var string[] */ - protected static $levels = [ + protected static array $levels = [ LogLevel::DEBUG, LogLevel::INFO, LogLevel::NOTICE, @@ -52,13 +53,10 @@ class Logger extends AbstractLogger { /** * Instantiates a new Logger object. - * - * Creates a new Logger object. Optionally - * accepts an array of LogAppenderBase objects - * to assign to appender stack. Any objects in - * array that don't implement LogAppenderBase - * are simply ignored. - * + * + * Creates a new Logger object. Optionally accepts an array of LogAppenderBase objects to assign to appender stack. + * Any objects in array that don't implement LogAppenderBase are simply ignored. + * * @param null|string $minimumLevel Optional minimum log level for output; Default is LogLevel::DEBUG * @param null|AppenderBase[] $appenders Optional collection of LogAppenderBase objects to assign. */ @@ -74,7 +72,7 @@ public function __construct(?string $minimumLevel = null, ?array $appenders = nu } if ($appenders !== null && count($appenders) > 0) { - foreach (array_values($appenders) as $appdr) { + foreach ($appenders as $appdr) { if ($appdr instanceof AppenderBase) { $this->appenders->linkNode($appdr); } @@ -86,9 +84,10 @@ public function __construct(?string $minimumLevel = null, ?array $appenders = nu /** * Adds a new appender to the appender stack. - * + * * @param AppenderBase $appender Appender which extends the AppenderBase abstract class. * @throws \Psr\Log\InvalidArgumentException Thrown if invalid appender argument provided. + * @return void */ public function addAppender(AppenderBase $appender) : void { $this->appenders->linkNode($appender); @@ -98,13 +97,13 @@ public function addAppender(AppenderBase $appender) : void { /** * Interpolates context values into message placeholders. - * + * * @param string $message String value of log message w/ potential placeholders. * @param array $context Array of context values to interpolate with placeholers. * @return string */ protected function interpolate(string $message, array $context) : string { - if (strpos($message, '{') === false || strpos($message, '}') === false) { + if (!str_contains($message, '{') || !str_contains($message, '}')) { return $message; } @@ -138,40 +137,41 @@ protected function interpolate(string $message, array $context) : string { /** * Logs with an arbitrary level. - * - * Generates a Stoic\LogMessage object for - * the provided message * - * @param string $level String value of log level for message. + * Generates a Stoic\LogMessage object for the provided message + * + * @param string $level String value of log level for message. * @param string $message String value of log message. - * @param array $context Optional context array for replacing placeholders in message string. + * @param array $context Optional context array for replacing placeholders in message string. + * @throws \Exception + * @return void */ - public function log($level, $message, array $context = array()) { + public function log($level, $message, array $context = []) { $this->messages[] = new Message($level, $this->interpolate($message, $context)); return; } /** - * Determines if the given log level meets the - * configured minimum level. - * + * Determines if the given log level meets the configured minimum level. + * * @param string $level String value of level to check against minimum. - * @return boolean + * @return bool */ protected function meetsMinimumLevel(string $level) : bool { return array_search($level, self::$levels) >= array_search($this->minLevel, self::$levels); } /** - * Generates the level-filtered collection of - * messages to output and traverses them through - * the appender stack. + * Generates the level-filtered collection of messages to output and traverses them through the appender stack. + * + * @throws \Exception + * @return void */ public function output() : void { $messages = array(); - foreach (array_values($this->messages) as $message) { + foreach ($this->messages as $message) { if ($this->meetsMinimumLevel($message->level)) { $messages[] = $message; } diff --git a/Log/Message.php b/Log/Message.php index b902f81..8770451 100644 --- a/Log/Message.php +++ b/Log/Message.php @@ -2,42 +2,43 @@ namespace Stoic\Log; + use JetBrains\PhpStorm\ArrayShape; + use Psr\Log\LogLevel; - use Psr\Log\InvalidArgumentException; /** * Represents a log message. - * + * * @package Stoic\Log - * @version 1.0.1 + * @version 1.1.0 */ class Message implements \JsonSerializable { /** * String value of message level. - * + * * @var string */ - public $level; + public string $level; /** * String value of log message. - * + * * @var string */ - public $message; + public string $message; /** - * Immutable timestamp for log - * message creation time. - * + * Immutable timestamp for log message creation time. + * * @var \DateTimeInterface */ - private $timestamp; + private \DateTimeInterface $timestamp; + + /** - * Static collection of log levels - * to speed checking of level validity. - * + * Static collection of log levels to speed checking of level validity. + * * @var array */ - private static $validLevels = array( + private static array $validLevels = [ LogLevel::DEBUG => true, LogLevel::INFO => true, LogLevel::NOTICE => true, @@ -46,16 +47,15 @@ class Message implements \JsonSerializable { LogLevel::CRITICAL => true, LogLevel::ALERT => true, LogLevel::EMERGENCY => true - ); + ]; /** - * Instantiates a new Message object with - * given level and message. - * + * Instantiates a new Message object with given level and message. + * * @param string $level String value of message level. * @param string $message String value of log message. - * @throws \InvalidArgumentException Thrown if invalid log level provided. + * @throws \Exception|\InvalidArgumentException */ public function __construct(string $level, string $message) { if (array_key_exists($level, self::$validLevels) === false) { @@ -72,9 +72,8 @@ public function __construct(string $level, string $message) { } /** - * Returns the immutable timestamp marking - * message creation. - * + * Returns the immutable timestamp marking message creation. + * * @return \DateTimeInterface */ public function getTimestamp() : \DateTimeInterface { @@ -82,23 +81,21 @@ public function getTimestamp() : \DateTimeInterface { } /** - * Produces an array containing all data - * within the Message object. - * + * Produces an array containing all data within the Message object. + * * @return string[] */ - public function __toArray() { - return array( - 'level' => $this->level, - 'message' => $this->message, + public function __toArray() : array { + return [ + 'level' => $this->level, + 'message' => $this->message, 'timestamp' => $this->timestamp->format('Y-m-d G:i:s.u') - ); + ]; } /** - * Produces a JSON object containing all - * data within the Message object. - * + * Produces a JSON object containing all data within the Message object. + * * @return string */ public function __toJson() : string { @@ -106,12 +103,11 @@ public function __toJson() : string { } /** - * Returns an array of the message data ready to run through - * json_encode(). + * Returns an array of the message data ready to run through json_encode(). * * @return string[] */ - public function jsonSerialize() { + public function jsonSerialize() : array { return [ 'level' => strtoupper($this->level), 'message' => $this->message, @@ -120,9 +116,8 @@ public function jsonSerialize() { } /** - * Produces a basic string containing all - * data within the Message object. - * + * Produces a basic string containing all data within the Message object. + * * @return string */ public function __toString() : string { diff --git a/Log/MessageDispatch.php b/Log/MessageDispatch.php index b64aa2f..210754d 100644 --- a/Log/MessageDispatch.php +++ b/Log/MessageDispatch.php @@ -5,25 +5,26 @@ use Stoic\Chain\DispatchBase; /** - * Describes a collection of messages that - * will be passed to log appenders. - * + * Describes a collection of messages that will be passed to log appenders. + * * @package Stoic\Log - * @version 1.0.1 + * @version 1.1.0 */ class MessageDispatch extends DispatchBase { /** * Collection of Message objects. - * + * * @var Message[] */ - public $messages = []; + public array $messages = []; /** * Initializes the dispatch message collection. - * - * @param Message[] $messages Collection of Message objects to handle. + * + * @param Message|Message[] $input Collection of Message objects to handle. + * @throws \Exception + * @return void */ public function initialize($input) : void { if (!is_array($input) && (!is_object($input) || !($input instanceof Message))) { @@ -35,7 +36,7 @@ public function initialize($input) : void { return; } - foreach (array_values($input) as $msg) { + foreach ($input as $msg) { if ($msg instanceof Message) { $this->messages[] = $msg; } diff --git a/Log/NullAppender.php b/Log/NullAppender.php index 4c8936d..9d1b82b 100644 --- a/Log/NullAppender.php +++ b/Log/NullAppender.php @@ -6,9 +6,9 @@ /** * Null-sink/noop log appender. - * + * * @package Stoic\Log - * @version 1.0.1 + * @version 1.1.0 */ class NullAppender extends AppenderBase { /** @@ -24,14 +24,14 @@ public function __construct() { } /** - * Append method which simply consumes the collection - * of log messages and returns without caring. - * + * Append method which simply consumes the collection of log messages and returns without caring. + * + * @codeCoverageIgnore * @param mixed $sender Sender data, optional and thus can be 'null'. * @param DispatchBase $dispatch Collection of Message objects to handle. - * @codeCoverageIgnore + * @return void */ - public function process($sender, DispatchBase &$dispatch) : void { + public function process(mixed $sender, DispatchBase &$dispatch) : void { return; } } diff --git a/Tests/Chain/ChainTest.php b/Tests/Chain/ChainTest.php index cb835ac..32891a2 100644 --- a/Tests/Chain/ChainTest.php +++ b/Tests/Chain/ChainTest.php @@ -36,7 +36,7 @@ public function __construct() { return; } - public function process($sender, DispatchBase &$dispatch) { + public function process(mixed $sender, DispatchBase &$dispatch) : void { if (!($dispatch instanceof IncrementDispatch)) { return; } @@ -60,7 +60,7 @@ public function __construct() { return; } - public function process($sender, DispatchBase &$dispatch) { + public function process(mixed $sender, DispatchBase &$dispatch) : void { $dispatch->consume(); return; @@ -68,7 +68,7 @@ public function process($sender, DispatchBase &$dispatch) { } class InvalidChainHelperNode extends NodeBase { - public function process($sender, DispatchBase &$dispatch) { + public function process(mixed $sender, DispatchBase &$dispatch) : void { return; } } diff --git a/Tests/Chain/LoggingTest.php b/Tests/Chain/LoggingTest.php index fd1baed..a489ebf 100644 --- a/Tests/Chain/LoggingTest.php +++ b/Tests/Chain/LoggingTest.php @@ -39,7 +39,7 @@ public function __construct() { return; } - public function process($sender, DispatchBase &$dispatch) { + public function process($sender, DispatchBase &$dispatch) : void { return; } } @@ -51,7 +51,7 @@ public function __construct() { return; } - public function process($sender, DispatchBase &$dispatch) { + public function process($sender, DispatchBase &$dispatch) : void { $dispatch->consume(); return; diff --git a/Tests/Chain/ValidityTest.php b/Tests/Chain/ValidityTest.php index f870ced..7237ca0 100644 --- a/Tests/Chain/ValidityTest.php +++ b/Tests/Chain/ValidityTest.php @@ -25,12 +25,14 @@ public function __construct() { $this->_version = '1.0.0'; } - public function process($sender, DispatchBase &$Dispatch) { + public function process(mixed $sender, DispatchBase &$dispatch) : void { + return; } } class InvalidNode extends NodeBase { - public function process($sender, DispatchBase &$Dispatch) { + public function process(mixed $sender, DispatchBase &$dispatch) : void { + return; } } diff --git a/Tests/Log/LoggerTest.php b/Tests/Log/LoggerTest.php index c156fc7..c9b7e76 100644 --- a/Tests/Log/LoggerTest.php +++ b/Tests/Log/LoggerTest.php @@ -20,7 +20,7 @@ public function __construct() { return; } - public function process($sender, DispatchBase &$dispatch) { + public function process(mixed $sender, DispatchBase &$dispatch) : void { $this->messages = array_merge($dispatch->messages, $this->messages); return; diff --git a/Tests/Utilities/EnumBaseTest.php b/Tests/Utilities/EnumBaseTest.php index d348ded..08598f7 100644 --- a/Tests/Utilities/EnumBaseTest.php +++ b/Tests/Utilities/EnumBaseTest.php @@ -70,6 +70,18 @@ public function test_TryGetEnum() { $enum = EnumBase::tryGetEnum(null, AnotherEnum::class); self::assertTrue($enum->getValue() === null); + $enum = AnotherEnum::tryGet(1); + self::assertTrue($enum->is(AnotherEnum::FIRST_VALUE)); + + $enum = AnotherEnum::tryGet(new AnotherEnum(1)); + self::assertTrue($enum->is(AnotherEnum::FIRST_VALUE)); + + $enum = AnotherEnum::tryGet(35); + self::assertTrue($enum->getValue() === null); + + $enum = AnotherEnum::tryGet(null); + self::assertTrue($enum->getValue() === null); + try { $enum = EnumBase::tryGetEnum(1, NotAnEnum::class); self::assertTrue(false); diff --git a/Utilities/EnumBase.php b/Utilities/EnumBase.php index 51c865d..7ddd037 100644 --- a/Utilities/EnumBase.php +++ b/Utilities/EnumBase.php @@ -2,55 +2,55 @@ namespace Stoic\Utilities; + use JetBrains\PhpStorm\Pure; + /** - * Abstract class to provide basic Enum type - * functionality. + * Abstract class to provide basic Enum type functionality. * * @package Stoic\Utilities - * @version 1.0.1 + * @version 1.1.0 */ abstract class EnumBase implements \JsonSerializable { - /** - * Static internal cache of const lookups. - * - * @var array - */ - protected static $constCache = []; - - /** * Internal storage for name. * * @var null|string */ - protected $name = null; + protected ?string $name = null; /** * Internal storage for value. * * @var null|integer */ - protected $value = null; + protected ?int $value = null; + /** + * Determines whether to serialize as the name of the set value. + * + * @var bool + */ + protected bool $serializeAsName = true; + + /** - * Determines whether or not to serialize as the - * name of the set value. + * Static internal cache of const lookups. * - * @var boolean + * @var array[] */ - protected $serializeAsName = true; + protected static array $constCache = []; /** - * Static method to return a new Enum object using - * the name instead of the value for initialization. + * Static method to return a new Enum object using the name instead of the value for initialization. * * @param string $string String to use as name. - * @param boolean $serializeAsName Causes object to serialize into the name of the set value, defaults to true. - * @return object + * @param bool $serializeAsName Causes object to serialize into the name of the set value, defaults to true. + * @throws \ReflectionException + * @return static */ - public static function fromString(string $string, bool $serializeAsName = true) { + public static function fromString(string $string, bool $serializeAsName = true) : static { $class = get_called_class(); - if ($string === null || empty($string) || !static::validName($string)) { + if (empty($string) || !static::validName($string)) { return new $class(); } @@ -63,12 +63,12 @@ public static function fromString(string $string, bool $serializeAsName = true) } /** - * Static method to return the const lookup for the - * called class. + * Static method to return the const lookup for the called class. * - * @return array + * @throws \ReflectionException + * @return array[] */ - public static function getConstList() { + public static function getConstList() : array { $cclass = get_called_class(); if (array_key_exists($cclass, static::$constCache) === false) { @@ -89,19 +89,47 @@ public static function getConstList() { } /** - * Attempts to instantiate an EnumBase class based on the given - * value. If the value is already the requested class, it is - * returned. If the value is a valid value for the class, a new - * instance of the class with the value assigned is returned. In - * all other cases a blank instance of the requested class is - * returned. + * Attempts to instantiate an EnumBase class based on the given value. If value is the requested class, it is + * simply returned. If the value is valid as value, it is used to instantiate a new instance of the class. In all + * other cases a blank instance of the class is returned. * - * @param integer|object $value The value which may or may not be valid as an enum class/value. + * @param int|EnumBase|null $value Value which may be valid for the enum class/value. + * @param bool $serializeAsName Causes object to serialize into the name of the set value, defaults to true. + * @throws \ReflectionException + * @return static + */ + public static function tryGet(null|int|EnumBase $value, bool $serializeAsName = true) : static { + if ($value === null) { + return new static(); + } + + $static = new static(); + + if (is_a($value, static::class)) { + return $value; + } + + if (!self::validValue($value)) { + return $static; + } + + $static->setValue($value); + + return $static; + } + + /** + * Attempts to instantiate an EnumBase class based on the given value. If the value is already the requested + * class, it is returned. If the value is a valid value for the class, a new instance of the class with the value + * assigned is returned. In all other cases a blank instance of the requested class is returned. + * + * @param integer|static|null $value The value which may or may not be valid as an enum class/value. * @param string $className Fully qualified class name to return. - * @throws \InvalidArgumentException + * @param bool $serializeAsName Causes object to serialize into the name of the set value, defaults to true. + * @throws \InvalidArgumentException|\ReflectionException * @return EnumBase */ - public static function tryGetEnum($value, $className) { + public static function tryGetEnum(null|int|EnumBase $value, string $className, bool $serializeAsName = true) : EnumBase { if (!is_a($className, EnumBase::class, true)) { throw new \InvalidArgumentException("Cannot attempt to retrieve an enum from a class that doesn't extend EnumBase"); } @@ -122,47 +150,38 @@ public static function tryGetEnum($value, $className) { } /** - * Static method to validate a name against the Enum - * object's possible constants. + * Static method to validate a name against the Enum object's possible constants. * * @param string $name String to use as name. - * @return boolean + * @throws \ReflectionException + * @return bool */ public static function validName(string $name) : bool { - $consts = static::getConstList(); - - return array_key_exists($name, $consts['name']) !== false; + return array_key_exists($name, static::getConstList()['name']) !== false; } /** - * Static method to validate a value against the Enum - * object's possible constants. + * Static method to validate a value against the Enum object's possible constants. * - * @param integer $value Integer to use as value. - * @return boolean + * @param int $value Integer to use as value. + * @throws \ReflectionException + * @return bool */ public static function validValue(int $value) : bool { - $consts = static::getConstList(); - - return array_key_exists($value, $consts['value']) !== false; + return array_key_exists($value, static::getConstList()['value']) !== false; } /** * Instantiates a new Enum object. * - * @param null|integer $value Integer to use as value, defaults to null. - * @param boolean $serializeAsName Causes object to serialize into the name of the set value, defaults to true. + * @param null|int $value Integer to use as value, defaults to null. + * @param bool $serializeAsName Causes object to serialize into the name of the set value, defaults to true. + * @throws \ReflectionException */ public function __construct(?int $value = null, bool $serializeAsName = true) { $this->serializeAsName = $serializeAsName; - - if ($value !== null && static::validValue($value)) { - $consts = static::getConstList(); - - $this->name = $consts['value'][$value]; - $this->value = $value; - } + $this->setValue($value); return; } @@ -181,8 +200,7 @@ public function __toString() : string { } /** - * Retrieves the string name of the currently - * set value. + * Retrieves the string name of the currently set value. * * @return null|string */ @@ -191,21 +209,19 @@ public function getName() : ?string { } /** - * Retrieves the integer representation of the - * currently set value. + * Retrieves the integer representation of the currently set value. * - * @return null|integer + * @return null|int */ public function getValue() : ?int { return $this->value; } /** - * Determines if the current set value is the same - * as the given value. + * Determines if the current set value is the same as the given value. * - * @param integer $value Integer to test against current value. - * @return boolean + * @param int $value Integer to test against current value. + * @return bool */ public function is(int $value) : bool { if ($this->value === null || $this->value !== $value) { @@ -216,18 +232,17 @@ public function is(int $value) : bool { } /** - * Determines if the current value is equal to any of the - * supplied values. + * Determines if the current value is equal to any of the supplied values. * - * @param integer[] $values Array of integer values to compare against current value. - * @return boolean + * @param int[] $values Array of integer values to compare against current value. + * @return bool */ public function isIn(int ...$values) : bool { if ($this->value === null) { return false; } - foreach (array_values($values) as $val) { + foreach ($values as $val) { if ($this->value === $val) { return true; } @@ -241,7 +256,26 @@ public function isIn(int ...$values) : bool { * * @return string */ + #[Pure] public function jsonSerialize() : string { return $this->__toString(); } + + /** + * Internal method to set the value. + * + * @param int|null $value Integer to use as value, defaults to null, + * @throws \ReflectionException + * @return void + */ + protected function setValue(?int $value = null) : void { + if ($value === null || !static::validValue($value)) { + return; + } + + $this->name = static::getConstList()['value'][$value]; + $this->value = $value; + + return; + } } diff --git a/Utilities/ReturnHelper.php b/Utilities/ReturnHelper.php index 2b9e1c7..487e30d 100644 --- a/Utilities/ReturnHelper.php +++ b/Utilities/ReturnHelper.php @@ -3,31 +3,30 @@ namespace Stoic\Utilities; /** - * Class to provide more data for - * method/function returns. - * + * Class to provide more data for method/function returns. + * * @package Stoic\Utilities - * @version 1.0.1 + * @version 1.1.0 */ class ReturnHelper { /** * Array of messages in this return. - * + * * @var string[] */ - protected $_messages; + protected array $_messages; /** * Array of results in this return. - * - * @var mixed[] + * + * @var array[] */ - protected $_results; + protected array $_results; /** * Current status of this return. - * - * @var integer + * + * @var int */ - protected $_status; + protected int $_status; const STATUS_BAD = 0; @@ -35,21 +34,21 @@ class ReturnHelper { /** - * Instantiates a new ReturnHelper class. Default - * status is STATUS_BAD. + * Instantiates a new ReturnHelper class. Default status is STATUS_BAD. */ public function __construct() { $this->_messages = []; - $this->_results = []; - $this->_status = self::STATUS_BAD; + $this->_results = []; + $this->_status = self::STATUS_BAD; return; } /** * Adds a message onto the internal collection. - * + * * @param string $message String value of message to add to collection. + * @return void */ public function addMessage(string $message) : void { $this->_messages[] = $message; @@ -58,18 +57,18 @@ public function addMessage(string $message) : void { } /** - * Adds a group of messages onto the internal - * collection. - * + * Adds a group of messages onto the internal collection. + * * @param string[] $messages Array of strings to add to collection. - * @throws \InvalidArgumentException Thrown if null or empty array provided. + * @throws \InvalidArgumentException + * @return void */ public function addMessages(array $messages) : void { - if ($messages === null || count($messages) < 1) { + if (count($messages) < 1) { throw new \InvalidArgumentException("Messages array to ReturnHelper::addMessages() must be array with elements"); } - foreach (array_values($messages) as $msg) { + foreach ($messages as $msg) { $this->_messages[] = $msg; } @@ -78,28 +77,29 @@ public function addMessages(array $messages) : void { /** * Adds a result onto the internal collection. - * + * * @param mixed $result Result value to add to collection. + * @return void */ - public function addResult($result) : void { + public function addResult(mixed $result) : void { $this->_results[] = $result; return; } /** - * Adds a group of results onto the internal - * collection. - * - * @param mixed[] $results Array of results to add to collection. - * @throws \InvalidArgumentException Thrown if null or empty array provided. + * Adds a group of results onto the internal collection. + * + * @param array[] $results Array of results to add to collection. + * @throws \InvalidArgumentException + * @return void */ public function addResults(array $results) : void { - if ($results === null || count($results) < 1) { + if (count($results) < 1) { throw new \InvalidArgumentException("Results array to ReturnHelper::addResults() must be array with elements"); } - foreach (array_values($results) as $res) { + foreach ($results as $res) { $this->_results[] = $res; } @@ -107,20 +107,18 @@ public function addResults(array $results) : void { } /** - * Returns TRUE if the current internal status - * is set to STATUS_BAD. - * - * @return boolean + * Returns TRUE if the current internal status is set to STATUS_BAD. + * + * @return bool */ public function isBad() : bool { return $this->_status === self::STATUS_BAD; } /** - * Returns TRUE if the current internal status - * is set to STATUS_GOOD. - * - * @return boolean + * Returns TRUE if the current internal status is set to STATUS_GOOD. + * + * @return bool */ public function isGood() : bool { return $this->_status === self::STATUS_GOOD; @@ -128,37 +126,35 @@ public function isGood() : bool { /** * Returns the internal collection of messages. - * + * * @return string[] */ - public function getMessages() { + public function getMessages() : array { return $this->_messages; } /** * Returns the internal collection of results. - * - * @return mixed[] + * + * @return array[] */ - public function getResults() { + public function getResults() : array { return $this->_results; } /** - * Returns TRUE if there are messages stored in - * the internal collection. - * - * @return boolean + * Returns TRUE if there are messages stored in the internal collection. + * + * @return bool */ public function hasMessages() : bool { return count($this->_messages) > 0; } /** - * Returns TRUE if there are results stored in - * the internal collection. - * - * @return boolean + * Returns TRUE if there are results stored in the internal collection. + * + * @return bool */ public function hasResults() : bool { return count($this->_results) > 0; @@ -166,6 +162,8 @@ public function hasResults() : bool { /** * Sets the internal status as STATUS_BAD. + * + * @return void */ public function makeBad() : void { $this->_status = self::STATUS_BAD; @@ -175,6 +173,8 @@ public function makeBad() : void { /** * Sets the internal status as STATUS_GOOD. + * + * @return void */ public function makeGood() : void { $this->_status = self::STATUS_GOOD; diff --git a/composer.json b/composer.json index b6e9b7c..ed96bd9 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "stoic/stoic", "description": "Stoic framework Core component", - "version": "1.0.2", + "version": "1.1.0", "homepage": "https://stoic-framework.com", "autoload": { "psr-0": { @@ -19,7 +19,7 @@ ] }, "require": { - "php": ">=7.4", + "php": ">=8.0", "psr/log": "^1.0.0" }, "require-dev": {