diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..c9389d0 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "src/ARTulloss/FilterX/libs/pasvl"] + path = src/ARTulloss/FilterX/libs/pasvl + url = https://github.com/lezhnev74/pasvl diff --git a/.poggit.yml b/.poggit.yml index 45c274d..116317a 100644 --- a/.poggit.yml +++ b/.poggit.yml @@ -6,5 +6,6 @@ projects: path: "" libs: - src: poggit/libasynql/libasynql - version: ^3.2.0 + version: ^3.3.0 + branch: "4.0" ... diff --git a/plugin.yml b/plugin.yml index 1fc8658..d1e5df2 100644 --- a/plugin.yml +++ b/plugin.yml @@ -1,7 +1,7 @@ name: FilterX main: ARTulloss\FilterX\Main version: 1.0.0 -api: 3.0.0 +api: 4.0.0 author: ARTulloss description: The next generation chat filter website: https://github.com/artulloss diff --git a/src/ARTulloss/FilterX/Autoloader.php b/src/ARTulloss/FilterX/Autoloader.php new file mode 100644 index 0000000..b6b7f04 --- /dev/null +++ b/src/ARTulloss/FilterX/Autoloader.php @@ -0,0 +1,41 @@ + ':bool' ], 'Infraction' => [ - 'Mode' => ':int :between(1,2)', - 'Reset Every' => ':int', # seconds + 'Mode' => ':number :int :between(1,2)', + 'Reset Every' => ':number :int', # seconds 'Punishments' => [ - '*' => ':string :regexp(/^(?:[0-9]+ \)(?:seconds?|minutes?|hours?|days?|weeks?|months?|years?\)$/i)' + // '*' => ':string :regexp(\'^([0-9]+ )(seconds?|minutes?|hours?|days?|weeks?|months?|years?)$\i\')', + // ':number :int' => ':string :regexp(\'^[0-9]+ seconds?|minutes?|hours?|days?|weeks?|months?|years?$\')', + '*' => ':string', ] ] ]; - + private const DATABASE_PATTERN = [ - 'type' => ':string :regexp(/^(sqlite|mysql\)$/)', - 'sqlite' => [ - 'file' => ':string :regexp(/^.*\.sqlite$/)' + 'type' => ':string :in("sqlite","mysql")', + 'sqlite?' => [ + 'file' => ':string :ends(".sqlite")' ], 'mysql' => [ - 'host' => ':string :regexp(/^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?\)\.\){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?\)$/)', + 'host' => ':string', 'username' => ':string', 'password' => ':string', 'schema' => ':string' ], - 'worker-limit' => ':int :min(1)' + 'worker-limit' => ':number :int :min(1)' ]; /** * @throws \Exception */ public function onEnable(): void{ + new Autoloader(); $this->saveDefaultConfigs(); $this->startDatabase(); $this->checkConfigsValid(); @@ -80,7 +86,6 @@ public function onEnable(): void{ } $this->timer = new Timer($resetEverySeconds); } - } public function onDisable(): void{ if(isset($this->database)) @@ -97,15 +102,15 @@ public function saveDefaultConfigs(): void{ * Check if the config is valid */ public function checkConfigsValid(): void{ - $traverser = new Traverser(new ValidatorLocator()); + $cfgBuilder = ValidatorBuilder::forArray(self::CONFIG_PATTERN); + $dbBuilder = ValidatorBuilder::forArray(self::DATABASE_PATTERN); try { # TODO Maybe do this by file so it's easier to know which file is broken- but the configs are rather small... - $traverser->match(self::CONFIG_PATTERN, $this->getConfig()->getAll()); - $traverser->match(self::DATABASE_PATTERN, $this->databaseConfig->getAll()); - } catch (FailReport $report) { + $cfgBuilder->build()->validate($this->getConfig()->getAll()); + $dbBuilder->build()->validate($this->databaseConfig->getAll()); + } catch (ArrayFailedValidation $e) { $logger = $this->getLogger(); - $logger->error('Invalid config detected! Reason:'); - Utils::outputFailReasons($this, $report); + $logger->error('Invalid config detected! Reason: ' . $e->getMessage()); $logger->error('Disabling...'); $this->getServer()->getPluginManager()->disablePlugin($this); } diff --git a/src/ARTulloss/FilterX/Session/Session.php b/src/ARTulloss/FilterX/Session/Session.php index a86470f..385d17b 100644 --- a/src/ARTulloss/FilterX/Session/Session.php +++ b/src/ARTulloss/FilterX/Session/Session.php @@ -10,7 +10,7 @@ namespace ARTulloss\FilterX\Session; use Exception; -use pocketmine\Player; +use pocketmine\Player\Player; use function time; /** diff --git a/src/ARTulloss/FilterX/Session/SessionHandler.php b/src/ARTulloss/FilterX/Session/SessionHandler.php index 965e55a..f7972b5 100644 --- a/src/ARTulloss/FilterX/Session/SessionHandler.php +++ b/src/ARTulloss/FilterX/Session/SessionHandler.php @@ -12,7 +12,7 @@ use ARTulloss\FilterX\Main; use ARTulloss\FilterX\Queries\Queries; use ARTulloss\FilterX\Utils; -use pocketmine\Player; +use pocketmine\Player\Player; use pocketmine\utils\Utils as PMUtils; use Closure; use function time; @@ -66,7 +66,7 @@ public function passToNewSession(Closure $passTo, Player $player, string $lastMe // var_dump($result); if($result !== []) $session->setSoftMutedFor($result[0]['until'] > time() ? $result[0]['until'] : null); - $this->sessions[$player->getLowerCaseName()] = $session; + $this->sessions[$player->getName()] = $session; $passTo($session); }, $onError); }; @@ -112,7 +112,7 @@ public function deleteSession(Player $player): void{ * @return Session|null */ public function getSession(Player $player): ?Session{ - return $this->sessions[$player->getLowerCaseName()] ?? null; + return $this->sessions[$player->getName()] ?? null; } /** * @return Session[]|null diff --git a/src/ARTulloss/FilterX/Utils.php b/src/ARTulloss/FilterX/Utils.php index d239669..498de61 100644 --- a/src/ARTulloss/FilterX/Utils.php +++ b/src/ARTulloss/FilterX/Utils.php @@ -9,12 +9,11 @@ namespace ARTulloss\FilterX; -use ARTulloss\FilterX\libs\PASVL\Traverser\FailReport; use pocketmine\plugin\Plugin; use pocketmine\Server; -use function strtolower; use Throwable; use Closure; +use function strtolower; /** * Class Utils @@ -93,14 +92,4 @@ static function getOnError(Plugin $plugin = null): Closure{ $hasLogger->getLogger()->logException($error); }; } - static function outputFailReasons(Plugin $plugin, FailReport $report): void{ - $logger = $plugin->getLogger(); - $reason = $report->getReason(); - if($reason->isKeyQuantityType()) - $logger->error('Invalid key quantity found!'); - if($reason->isKeyType()) - $logger->error('Invalid key type found!'); - if($reason->isValueType()) - $logger->error('Invalid value type found!'); - } } \ No newline at end of file diff --git a/src/ARTulloss/FilterX/libs/PASVL/Pattern/InvalidPattern.php b/src/ARTulloss/FilterX/libs/PASVL/Pattern/InvalidPattern.php deleted file mode 100644 index e63b971..0000000 --- a/src/ARTulloss/FilterX/libs/PASVL/Pattern/InvalidPattern.php +++ /dev/null @@ -1,13 +0,0 @@ - - * Date: 01/01/2018 - */ - -namespace ARTulloss\FilterX\libs\PASVL\Pattern; - - -class InvalidPattern extends \Exception -{ - -} \ No newline at end of file diff --git a/src/ARTulloss/FilterX/libs/PASVL/Pattern/Pattern.php b/src/ARTulloss/FilterX/libs/PASVL/Pattern/Pattern.php deleted file mode 100644 index 79489fe..0000000 --- a/src/ARTulloss/FilterX/libs/PASVL/Pattern/Pattern.php +++ /dev/null @@ -1,249 +0,0 @@ - - * Date: 01/01/2018 - */ - -namespace ARTulloss\FilterX\libs\PASVL\Pattern; - - -use ARTulloss\FilterX\libs\PASVL\Pattern\VO\Quantifier; -use ARTulloss\FilterX\libs\PASVL\Pattern\VO\Validator; - -class Pattern -{ - /** @var string */ - protected $original_pattern; - /** @var bool */ - protected $throw_on_invalid_pattern; - /** - * The point is to pass any data that can be used inside validators to recognize specific conditions of validation. - * For example, "production" or "local". - * @var mixed - */ - protected $context; - - /** @var array */ - protected $validators = []; - /** @var Quantifier */ - protected $quantifier; - - /** - * Pattern constructor. - * @param string|int $original_pattern - * @param mixed $context - * @param bool $throw_on_invalid_pattern - * @throws InvalidPattern - */ - public function __construct($original_pattern, $context = null, $throw_on_invalid_pattern = false) - { - $this->original_pattern = is_int($original_pattern) ? $original_pattern : trim($original_pattern); - $this->context = $context; - $this->throw_on_invalid_pattern = $throw_on_invalid_pattern; - - $this->parse($original_pattern); - } - - /** - * @return string - */ - public function getOriginalPattern(): string - { - return $this->original_pattern; - } - - /** - * @return mixed - */ - public function getContext() - { - return $this->context; - } - - public function getMainValidator(): ?Validator - { - return count($this->validators) ? $this->validators[0] : null; - } - - public function getSubValidators(): array - { - return array_slice($this->validators, 1); - } - - /** - * @return Quantifier - */ - public function getQuantifier(): Quantifier - { - return $this->quantifier; - } - - - /** - * Analyze given pattern and populate internal values - * - * @param string $user_pattern - * @throws InvalidPattern - */ - protected function parse(string $user_pattern) - { - $label_regexp_pattern = "[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*"; - $quantifier_regexp_pattern = "(?'quantifier'(?'single_quantifier'[\*|\?|!])|(?'interval_quantifier'{(?'quantifier_min_boundary'\d+)(?'quantifier_max_boundary',\d*)?}))"; - $validator_arguments_pattern = "(\((?'arguments'.+?,?)(?fillQuantifierFromRegexpMatches($matches); - if ($this->isUserPatternHasValidLabels($user_pattern, $matches)) { - $this->fillValidatorsFromRegexpMatches($matches); - } else { - $this->fillDefaultValidatorFromRegexpMatches($matches); - } - - // Final checks - - // Explicit key name cannot be with multiple quantifier, unless the name is empty - if ($this->quantifier->isMultiple() && - $this->getMainValidator()->getName() == "key" && - $this->getMainValidator()->getArguments() != [''] - ) { - throw new InvalidPattern("Direct name cannot be used along with * quantifier"); - } - } - - /** - * If string starts with a ":" - that means validator labels are used. - * Make sure pattern is valid, otherwise throw an exception or just return boolean result - * - * @param string $user_pattern - * @param array $matches - * @return bool - * @throws InvalidPattern - */ - protected function isUserPatternHasValidLabels(string $user_pattern, array $matches): bool - { - $starts_with_colon = strpos($user_pattern, ":") === 0; - - if (!$starts_with_colon) { - return false; - } - - foreach ($matches as $match) { - $user_pattern = str_replace($match[0], "", $user_pattern); - } - $remaining_labels = trim($user_pattern); - - if ( - $starts_with_colon && - strlen($remaining_labels) && - $this->throw_on_invalid_pattern - ) { - throw new InvalidPattern("Pattern has invalid labels. Remaining labels: $remaining_labels"); - } - - return !strlen($remaining_labels); - } - - /** - * Populate internal value with Validator objects from pattern parsing matches - * - * @param array $matches - */ - protected function fillValidatorsFromRegexpMatches(array $matches): void - { - $this->validators = array_values( - array_map(function ($match) { - $arguments = array_map( - function ($argumentsString) { - // remove escaped closing parenthesis - return strtr($argumentsString, ['\)' => ')']); - }, - array_filter(explode(",", $match['arguments'] ?? ""), 'strlen') - ); - return new Validator($match['name'], $arguments); - }, array_filter($matches, function ($match) { - return isset($match['validator']) && strlen($match['validator']); - })) - ); - } - - /** - * @param array $matches - */ - protected function fillDefaultValidatorFromRegexpMatches(array $matches) - { - foreach ($matches as $match) { - if (isset($match['quantifier']) && strlen($match['quantifier'])) { - $pattern_without_quantifier = str_replace($match['quantifier'], "", $this->original_pattern); - - if (!strlen(trim($pattern_without_quantifier))) { - $this->validators[] = new Validator("any"); // "*" or "?" or "!" means any value with quantifier - } else { - $this->validators[] = new Validator("key", [$pattern_without_quantifier]); - } - return; - } - } - - // default explicit key - $this->validators[] = new Validator("key", [$this->original_pattern]); - } - - /** - * Fill internal value with parsed Quantifier object - * - * @param array $matches - * @throws InvalidPattern - */ - function fillQuantifierFromRegexpMatches(array $matches): void - { - $quantifier_options = [1, 1]; - foreach ($matches as $match) { - if (isset($match['quantifier']) && strlen($match['quantifier'])) { - if (isset($match['single_quantifier']) && strlen($match['single_quantifier'])) { - switch ($match['single_quantifier']) { - case "*": - $quantifier_options = [0, PHP_INT_MAX]; - break; - case "?": - $quantifier_options = [0, 1]; - break; - case "!": - default: - $quantifier_options = [1, 1]; - break; - } - } else { - if (isset($match['quantifier_max_boundary'])) { - - $max_boundary = ltrim($match['quantifier_max_boundary'], ","); - if ($max_boundary == "") { - $max_boundary = PHP_INT_MAX; - } else { - $max_boundary = (int)$max_boundary; - } - - $quantifier_options = [ - (int)$match['quantifier_min_boundary'], - $max_boundary, - ]; - } else { - $quantifier_options = [ - (int)$match['quantifier_min_boundary'], - (int)$match['quantifier_min_boundary'], - ]; - } - } - break; - } - } - try { - $this->quantifier = new Quantifier($quantifier_options[0], $quantifier_options[1]); - } catch (\InvalidArgumentException $e) { - throw new InvalidPattern($e->getMessage(), 0, $e); - } - } - -} \ No newline at end of file diff --git a/src/ARTulloss/FilterX/libs/PASVL/Pattern/VO/Quantifier.php b/src/ARTulloss/FilterX/libs/PASVL/Pattern/VO/Quantifier.php deleted file mode 100644 index 48f6e90..0000000 --- a/src/ARTulloss/FilterX/libs/PASVL/Pattern/VO/Quantifier.php +++ /dev/null @@ -1,134 +0,0 @@ - - * Date: 01/01/2018 - */ - -namespace ARTulloss\FilterX\libs\PASVL\Pattern\VO; - - -class Quantifier -{ - /** @var int */ - protected $from; - /** @var int */ - protected $to; - - /** - * Quantifier constructor. - * @param int $from - * @param int $to - */ - public function __construct(int $from, int $to) - { - if ($from < 0) { - throw new \InvalidArgumentException("lower boundary cannot be negative"); - } - if ($from > $to) { - throw new \InvalidArgumentException("lower boundary cannot be greater than upper boundary"); - } - - $this->from = $from; - $this->to = $to; - } - - /** - * @return int - */ - public function getFrom(): int - { - return $this->from; - } - - /** - * @return int - */ - public function getTo(): int - { - return $this->to; - } - - public function isOptional(): bool - { - return - $this->from == 0 && - $this->to == 1; - } - - public function isRequiredSingle(): bool - { - return - $this->to == 1 && - $this->from == 1; - } - - public function isMultiple(): bool - { - return - $this->to > 1 && - ($this->to - $this->from) > 1; - } - - public function isAny(): bool - { - return - $this->from == 0 && - $this->to == PHP_INT_MAX; - } - - public function isEqual(Quantifier $other_quantifier): bool - { - return - $other_quantifier->getFrom() == $this->getFrom() && - $other_quantifier->getTo() == $this->getTo(); - } - - public function isValidQuantity(int $quantity): bool - { - return - $this->from <= $quantity && - $this->to >= $quantity; - } - - - static function asAny(): self - { - return new static(0, PHP_INT_MAX); - } - - static function asOptional(): self - { - return new static(0, 1); - } - - static function asRequired(): self - { - return new static(1, 1); - } - - static function asInterval(int $min, int $max): self - { - return new static ($min, $max); - } - - public function __toString(): string - { - if (self::isRequiredSingle()) { - return "!"; - } - - if (self::isOptional()) { - return "?"; - } - - if (self::isAny()) { - return "*"; - } - - - return "\{$this->from,$this->to\}"; - - } - - -} \ No newline at end of file diff --git a/src/ARTulloss/FilterX/libs/PASVL/Pattern/VO/SubValidator.php b/src/ARTulloss/FilterX/libs/PASVL/Pattern/VO/SubValidator.php deleted file mode 100644 index 3ca5dcb..0000000 --- a/src/ARTulloss/FilterX/libs/PASVL/Pattern/VO/SubValidator.php +++ /dev/null @@ -1,13 +0,0 @@ - - * Date: 01/01/2018 - */ - -namespace ARTulloss\FilterX\libs\PASVL\Pattern\VO; - - -class SubValidator extends Validator -{ - -} \ No newline at end of file diff --git a/src/ARTulloss/FilterX/libs/PASVL/Pattern/VO/Validator.php b/src/ARTulloss/FilterX/libs/PASVL/Pattern/VO/Validator.php deleted file mode 100644 index 20d591b..0000000 --- a/src/ARTulloss/FilterX/libs/PASVL/Pattern/VO/Validator.php +++ /dev/null @@ -1,51 +0,0 @@ - - * Date: 01/01/2018 - */ - -namespace ARTulloss\FilterX\libs\PASVL\Pattern\VO; - - -class Validator -{ - /** @var string */ - protected $name; - /** @var array */ - protected $arguments = []; - - /** - * Validator constructor. - * @param string $name - * @param array $arguments - */ - public function __construct(string $name, array $arguments = []) - { - $this->name = $name; - $this->arguments = $arguments; - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } - - /** - * @return array - */ - public function getArguments(): array - { - return $this->arguments; - } - - public function isEqual(self $validator): bool - { - return - $validator->getName() == $this->getName() && - $validator->arguments == $this->getArguments(); - } - -} \ No newline at end of file diff --git a/src/ARTulloss/FilterX/libs/PASVL/Traverser/DataMismatchedPattern.php b/src/ARTulloss/FilterX/libs/PASVL/Traverser/DataMismatchedPattern.php deleted file mode 100644 index 297cfb0..0000000 --- a/src/ARTulloss/FilterX/libs/PASVL/Traverser/DataMismatchedPattern.php +++ /dev/null @@ -1,31 +0,0 @@ - - * Date: 03/01/2018 - */ - -namespace ARTulloss\FilterX\libs\PASVL\Traverser; - - -class DataMismatchedPattern extends DataNoMatching -{ - /** @var mixed|null */ - protected $mismatched_pattern; - - public function __construct($mismatched_value, int $mismatched_type, $mismatched_pattern) - { - parent::__construct($mismatched_value, $mismatched_type); - $this->mismatched_pattern = $mismatched_pattern; - } - - - /** - * @return mixed - */ - public function getMismatchedPattern() - { - return $this->mismatched_pattern; - } - - -} \ No newline at end of file diff --git a/src/ARTulloss/FilterX/libs/PASVL/Traverser/DataNoMatching.php b/src/ARTulloss/FilterX/libs/PASVL/Traverser/DataNoMatching.php deleted file mode 100644 index 669f967..0000000 --- a/src/ARTulloss/FilterX/libs/PASVL/Traverser/DataNoMatching.php +++ /dev/null @@ -1,60 +0,0 @@ - - * Date: 03/01/2018 - */ - -namespace ARTulloss\FilterX\libs\PASVL\Traverser; - - -use ARTulloss\FilterX\libs\PASVL\Traverser\VO\FailedReason; - -class DataNoMatching extends \InvalidArgumentException -{ - /** @var mixed */ - protected $key; - /** @var mixed */ - protected $value; - /** @var FailedReason */ - protected $reason; - - /** - * DataNoMatching constructor. - * @param mixed $key - * @param mixed $value - * @param int $reason - */ - public function __construct($key, $value, FailedReason $reason) - { - parent::__construct("Invalid data found"); - $this->key = $key; - $this->value = $value; - $this->reason = $reason; - } - - /** - * @return mixed - */ - public function getKey() - { - return $this->key; - } - - /** - * @return mixed - */ - public function getValue() - { - return $this->value; - } - - /** - * @return FailedReason - */ - public function getReason(): FailedReason - { - return $this->reason; - } - - -} \ No newline at end of file diff --git a/src/ARTulloss/FilterX/libs/PASVL/Traverser/FailReport.php b/src/ARTulloss/FilterX/libs/PASVL/Traverser/FailReport.php deleted file mode 100644 index 4e8d96b..0000000 --- a/src/ARTulloss/FilterX/libs/PASVL/Traverser/FailReport.php +++ /dev/null @@ -1,107 +0,0 @@ - - * Date: 03/01/2018 - */ - -namespace ARTulloss\FilterX\libs\PASVL\Traverser; - - -use ARTulloss\FilterX\libs\PASVL\Traverser\VO\FailedReason; - -class FailReport extends \Exception -{ - /** @var FailedReason */ - private $reason; - /** @var mixed */ - private $mismatch_data_key; - /** @var mixed */ - private $mismatch_data_value; - /** @var mixed */ - private $mismatch_pattern; - /** @var array */ - private $data_key_chain = []; - /** @var array */ - private $pattern_key_chain = []; - - /** - * FailReport constructor. - * @param int $reason - * @param mixed $mismatch_data_key - * @param mixed $mismatch_data_value - * @param mixed $mismatch_pattern - * @param array $data_key_chain - * @param array $pattern_key_chain - */ - public function __construct( - FailedReason $reason, - $mismatch_data_key, - $mismatch_data_value, - $mismatch_pattern, - array $data_key_chain, - array $pattern_key_chain - ) { - $this->reason = $reason; - $this->mismatch_data_key = $mismatch_data_key; - $this->mismatch_data_value = $mismatch_data_value; - $this->mismatch_pattern = $mismatch_pattern; - $this->data_key_chain = $data_key_chain; - $this->pattern_key_chain = $pattern_key_chain; - - parent::__construct(); - } - - /** - * @return FailedReason - */ - public function getReason(): FailedReason - { - return $this->reason; - } - - /** - * @return mixed - */ - public function getMismatchDataKey() - { - return $this->mismatch_data_key; - } - - /** - * @return mixed - */ - public function getMismatchDataValue() - { - return $this->mismatch_data_value; - } - - /** - * @return mixed - */ - public function getMismatchPattern() - { - return $this->mismatch_pattern; - } - - /** - * @return array - */ - public function getDataKeyChain(): array - { - return $this->data_key_chain; - } - - /** - * @return array - */ - public function getPatternKeyChain(): array - { - return $this->pattern_key_chain; - } - - public function getFailedPatternLevel(): int - { - return count($this->getPatternKeyChain()); - } - -} \ No newline at end of file diff --git a/src/ARTulloss/FilterX/libs/PASVL/Traverser/VO/FailedReason.php b/src/ARTulloss/FilterX/libs/PASVL/Traverser/VO/FailedReason.php deleted file mode 100644 index 2cc2b49..0000000 --- a/src/ARTulloss/FilterX/libs/PASVL/Traverser/VO/FailedReason.php +++ /dev/null @@ -1,75 +0,0 @@ - - * Date: 30/01/2018 - */ -declare(strict_types=1); - - -namespace ARTulloss\FilterX\libs\PASVL\Traverser\VO; - - -class FailedReason -{ - const MISMATCHED_KEY = 1; - const MISMATCHED_VALUE = 2; - const MISMATCHED_KEY_QUANTITY = 3; // means data is okay, but count of keys mismatched - - /** @var int */ - private $reason_code; - - /** - * FailedReason constructor. - * @param int $reason_code - */ - public function __construct(int $reason_code) - { - if (!in_array($reason_code, [ - self::MISMATCHED_KEY, - self::MISMATCHED_KEY_QUANTITY, - self::MISMATCHED_VALUE, - ])) { - throw new \InvalidArgumentException("Invalid reason code"); - } - $this->reason_code = $reason_code; - } - - static function fromFailedValue(): self - { - return new self(self::MISMATCHED_VALUE); - } - - static function fromFailedKey(): self - { - return new self(self::MISMATCHED_KEY); - } - - static function fromFailedKeyQuantity(): self - { - return new self(self::MISMATCHED_KEY_QUANTITY); - } - - /** - * @return int - */ - public function getReasonCode(): int - { - return $this->reason_code; - } - - public function isKeyType(): bool - { - return $this->getReasonCode() == self::MISMATCHED_KEY; - } - - public function isKeyQuantityType(): bool - { - return $this->getReasonCode() == self::MISMATCHED_KEY_QUANTITY; - } - - public function isValueType(): bool - { - return $this->getReasonCode() == self::MISMATCHED_VALUE; - } - -} \ No newline at end of file diff --git a/src/ARTulloss/FilterX/libs/PASVL/Traverser/VO/ParsedPatterns.php b/src/ARTulloss/FilterX/libs/PASVL/Traverser/VO/ParsedPatterns.php deleted file mode 100644 index d8fd70e..0000000 --- a/src/ARTulloss/FilterX/libs/PASVL/Traverser/VO/ParsedPatterns.php +++ /dev/null @@ -1,41 +0,0 @@ - - * Date: 03/02/2018 - */ -declare(strict_types=1); - - -namespace ARTulloss\FilterX\libs\PASVL\Traverser\VO; - -use ARTulloss\FilterX\libs\PASVL\Pattern\Pattern; - -/** - * A storage to save parsed pattern instances - * @package ARTulloss\FilterX\libs\PASVL\Traverser\VO - */ -class ParsedPatterns -{ - private $patterns = []; - - function put($pattern) - { - if (!isset($this->patterns[$pattern])) { - $this->patterns[$pattern] = new Pattern($pattern, null, true); - } - } - - function has($pattern): bool - { - return array_key_exists($pattern, $this->patterns); - } - - function get($pattern): Pattern - { - if (!$this->has($pattern)) { - $this->put($pattern); - } - - return $this->patterns[$pattern]; - } -} \ No newline at end of file diff --git a/src/ARTulloss/FilterX/libs/PASVL/Traverser/VO/PatternValidator.php b/src/ARTulloss/FilterX/libs/PASVL/Traverser/VO/PatternValidator.php deleted file mode 100644 index c4f8b31..0000000 --- a/src/ARTulloss/FilterX/libs/PASVL/Traverser/VO/PatternValidator.php +++ /dev/null @@ -1,80 +0,0 @@ - - * Date: 03/02/2018 - */ -declare(strict_types=1); - - -namespace ARTulloss\FilterX\libs\PASVL\Traverser\VO; - -use ARTulloss\FilterX\libs\PASVL\ValidatorLocator\ValidatorLocator; - -/** - * This service has all parsed patterns and can answer yes or no if given data matched given pattern - * Internally it parses validator and performs calls - * @package ARTulloss\FilterX\libs\PASVL\Traverser\VO - */ -class PatternValidator -{ - /** @var ParsedPatterns */ - private $parsedPatterns; - /** @var ValidatorLocator */ - private $validatorLocator; - - /** - * Traverser constructor. - * @param ValidatorLocator $validatorLocator - */ - public function __construct(ValidatorLocator $validatorLocator) - { - $this->parsedPatterns = new ParsedPatterns(); - $this->validatorLocator = $validatorLocator; - } - - /** - * Detect if given data matches given pattern string - * - * @param $data - * @param mixed $pattern - * @return bool - * @throws \Exception - */ - public function match($data, $pattern): bool - { - $this->parsedPatterns->put($pattern); - - $mainValidator = $this->parsedPatterns->get($pattern)->getMainValidator(); - $mainValidatorClass = $this->validatorLocator->getValidatorClass($mainValidator->getName()); - - $matched = call_user_func_array( - $mainValidatorClass, - array_merge([$data], $mainValidator->getArguments()) - ); - - foreach ($this->parsedPatterns->get($pattern)->getSubValidators() as $subValidator) { - $matched = $matched && call_user_func_array( - [$mainValidatorClass, $subValidator->getName()], - array_merge([$data], $subValidator->getArguments()) - ); - - if (!$matched) { - break; - } - } - - return $matched; - } - - /** - * Detects if given count matches allowed boundaries of the pattern - * - * @param mixed $pattern - * @param int $count - * @return bool - */ - public function quantityMatch($pattern, int $count): bool - { - return $this->parsedPatterns->get($pattern)->getQuantifier()->isValidQuantity($count); - } -} \ No newline at end of file diff --git a/src/ARTulloss/FilterX/libs/PASVL/Traverser/VO/Traverser.php b/src/ARTulloss/FilterX/libs/PASVL/Traverser/VO/Traverser.php deleted file mode 100644 index 4580b09..0000000 --- a/src/ARTulloss/FilterX/libs/PASVL/Traverser/VO/Traverser.php +++ /dev/null @@ -1,271 +0,0 @@ - - * Date: 03/02/2018 - */ -declare(strict_types=1); - - -namespace ARTulloss\FilterX\libs\PASVL\Traverser\VO; - -use ARTulloss\FilterX\libs\PASVL\Traverser\DataNoMatching; -use ARTulloss\FilterX\libs\PASVL\Traverser\FailReport; -use ARTulloss\FilterX\libs\PASVL\ValidatorLocator\ValidatorLocator; - - -/** - * Represents a level of data to validate against a pattern - * @package ARTulloss\FilterX\libs\PASVL\Traverser\VO - */ -class Traverser -{ - - /** @var PatternValidator */ - private $validator; - - /** - * Traverser constructor. - * @param ValidatorLocator $locator - */ - public function __construct(ValidatorLocator $locator) - { - $this->validator = new PatternValidator($locator); - } - - /** - * Validate data - * - * @throws FailReport - * @param array $patterns - * @param iterable $data - */ - public function match(array $patterns, iterable $data) - { - try { - $this->matchLevel($data, $patterns); - } catch (DataNoMatching $e) { - - $failed_pattern = $patterns; - $pattern_key_chain = []; - $data_key_chain = []; - - throw new FailReport( - $e->getReason(), - $e->getKey(), - $e->getValue(), - $failed_pattern, - $data_key_chain, - $pattern_key_chain - ); - } - } - - /** - * Return bool, throw no exception - * - * @param array $patterns - * @param iterable $data - * @return bool - */ - public function check(array $patterns, iterable $data): bool - { - try { - $this->match($patterns, $data); - return true; - } catch (FailReport $e) { - return false; - } - } - - /** - * @param iterable $data - * @param array $patterns - * @return void - * @throws \Exception - */ - protected function matchLevel(iterable $data, array $patterns) - { - - // Optimization: analyze explicit keys first - uksort($patterns, function ($key1, $key2) { - return (int)( - substr((string)$key1, 0, 1) == ":" && - substr((string)$key2, 0, 1) != ":" - ); - }); - - // Collects all matching patterns for each dataKey: [ dataKey => patternKey[] ] - $dataKeyToPatternKeysMatch = []; - foreach ($data as $dataKey => $dataValue) { - // 1. Find perspective pattern keys - $perspectivePatternKeys = $this->findMatchedPatterns($dataKey, array_keys($patterns)); - if (!count($perspectivePatternKeys)) { - throw new DataNoMatching($dataKey, $dataValue, FailedReason::fromFailedKey()); - } - - - // 2. Filter perspective pattern keys by validating data value against pattern's corresponding value - $perspectivePatternKeys = $this->filterPerspectiveKeysByMatchingValues( - $perspectivePatternKeys, - $patterns, - $dataValue - ); - - - if (!count($perspectivePatternKeys)) { - throw new DataNoMatching( - $dataKey, - $dataValue, - FailedReason::fromFailedValue() - ); - } - $dataKeyToPatternKeysMatch[$dataKey] = $perspectivePatternKeys; - } - - // 3. Make combinations of data keys and pattern keys and filter those that match pattern's quantifiers - // Ok we have found patterns that match both keys and values, but now we need to validate it against quantity expectations - $combinations = array_filter($this->getCombinations($dataKeyToPatternKeysMatch), - function ($combination) { - // validate this combination against patterns' quantifiers - foreach (array_count_values($combination) as $patternKey => $count) { - if (!$this->validator->quantityMatch($patternKey, $count)) { - return false; - } - } - - return true; - }); - - // 4. For each matched combination make sure that all pattern keys fulfilled expectations - // all pattern keys must have fulfilled expectations - // otherwise this level of data does not match given pattern - $patternKeyFulfillmentMap = array_fill_keys(array_keys($patterns), false); - foreach ($patternKeyFulfillmentMap as $patternKey => $fulfillmentValue) { - // if a patternKey was not selected for data key (within combinations) - // and it does not have 0-quantity expectations, then this patternKey has unfulfilled expectations - $patternKeyIsInCombination = false; - foreach ($combinations as $combination) { - foreach ($combination as $dataKey => $validPatternKey) { - $patternKeyIsInCombination = $validPatternKey == $patternKey; - if ($patternKeyIsInCombination) { - break 2; - }; - } - } - - $patternKeyWasPerspective = false; - foreach ($dataKeyToPatternKeysMatch as $dataKey => $perspectivePatternKeys) { - $patternKeyWasPerspective = $patternKeyWasPerspective || in_array($patternKey, $perspectivePatternKeys); - } - - $patternKeyFulfillmentMap[$patternKey] = - $patternKeyIsInCombination || - ( - !$patternKeyWasPerspective && $this->validator->quantityMatch($patternKey, 0) - ); - } - - if (array_sum($patternKeyFulfillmentMap) != count($patternKeyFulfillmentMap)) { - // fulfillment was not met - throw new DataNoMatching("", "", FailedReason::fromFailedKeyQuantity()); - } - } - - /** - * Validate a given value against multiple patterns - * - * @param scalar $data - * @param array $patterns - * @return array - * @throws \Exception - */ - protected function findMatchedPatterns($data, array $patterns): array - { - $matchedPatterns = []; - foreach ($patterns as $pattern_key => $pattern) { - if ($this->validator->match($data, $pattern)) { - $matchedPatterns[$pattern_key] = $pattern; - } - } - - return $matchedPatterns; - } - - /** - * Return perspective pattern keys which corresponding pattern values match data value - * - * @param $perspectivePatternKeys - * @param $patterns - * @param $dataValue - */ - function filterPerspectiveKeysByMatchingValues( - $perspectivePatternKeys, - $patterns, - $dataValue - ): array { - - return array_filter($perspectivePatternKeys, function ($patternKey) use ($dataValue, $patterns) { - - $patternMatched = false; - $patternValue = $patterns[$patternKey]; // this is just a link, should not be too heavy on memory - - if (is_array($patternValue)) { - - // pattern is an array, value must be array as well - if (!is_iterable($dataValue)) { - - // value does not match the pattern (array expected) - // this is not the right patternValue-dataValue pair - - } else { - - // go down and analyze next array's level - try { - $this->matchLevel($dataValue, $patternValue); - $patternMatched = true; - } catch (DataNoMatching $e) { - // This means that this pattern cannot be matched against given value, - // this exception should not bubble up, it just means that pattern did not match - } - - } - - } else { - - // the pattern is not an array and value is also not an array, validate one against another - $matched_patterns = $this->findMatchedPatterns($dataValue, [$patterns[$patternKey]]); - - // value matched pattern - $patternMatched = (bool)count($matched_patterns); - - } - - return $patternMatched; - }); - - } - - /** - * Get all combinations of multiple arrays (preserves keys) - * - * @link https://gist.github.com/cecilemuller/4688876 - * - * @param array $source [dataKey => [dataPatternKey,...]] - * @return array - */ - private function getCombinations(array $source): array - { - $result = [[]]; - foreach ($source as $property => $property_values) { - $tmp = []; - foreach ($result as $result_item) { - foreach ($property_values as $property_value) { - $tmp[] = array_merge($result_item, [$property => $property_value]); - } - } - $result = $tmp; - } - return $result == [[]] ? [] : $result; - } - -} \ No newline at end of file diff --git a/src/ARTulloss/FilterX/libs/PASVL/Validator/AnyValidator.php b/src/ARTulloss/FilterX/libs/PASVL/Validator/AnyValidator.php deleted file mode 100644 index a5be1a6..0000000 --- a/src/ARTulloss/FilterX/libs/PASVL/Validator/AnyValidator.php +++ /dev/null @@ -1,17 +0,0 @@ - - * Date: 02/01/2018 - */ - -namespace ARTulloss\FilterX\libs\PASVL\Validator; - - -class AnyValidator extends Validator -{ - public function __invoke($data): bool - { - return true; - } - -} \ No newline at end of file diff --git a/src/ARTulloss/FilterX/libs/PASVL/Validator/ArrayValidator.php b/src/ARTulloss/FilterX/libs/PASVL/Validator/ArrayValidator.php deleted file mode 100644 index caefc0c..0000000 --- a/src/ARTulloss/FilterX/libs/PASVL/Validator/ArrayValidator.php +++ /dev/null @@ -1,47 +0,0 @@ - - * Date: 02/01/2018 - */ - -namespace ARTulloss\FilterX\libs\PASVL\Validator; - - -class ArrayValidator extends Validator -{ - /** @var boolean */ - protected $skipValidation; - - public function __invoke($data, string $nullable = "false"): bool - { - $nullable = $this->convertStringToBool($nullable); - $this->skipValidation = is_null($data) && $nullable; - - return $this->skipValidation || is_iterable($data); - } - - public function count($data, $count): bool - { - if ($this->skipValidation) { - return true; - } - - return count($data) == $count; - } - - public function keys($data, ...$keys): bool - { - if ($this->skipValidation) { - return true; - } - - foreach ($data as $key => $value) { - if (!in_array($key, $keys)) { - return false; - } - } - - return true; - } - -} \ No newline at end of file diff --git a/src/ARTulloss/FilterX/libs/PASVL/Validator/BoolValidator.php b/src/ARTulloss/FilterX/libs/PASVL/Validator/BoolValidator.php deleted file mode 100644 index 889a152..0000000 --- a/src/ARTulloss/FilterX/libs/PASVL/Validator/BoolValidator.php +++ /dev/null @@ -1,23 +0,0 @@ - - * Date: 02/01/2018 - */ - -namespace ARTulloss\FilterX\libs\PASVL\Validator; - - -class BoolValidator extends Validator -{ - /** @var boolean */ - protected $skipValidation; - - public function __invoke($data, string $nullable = "false"): bool - { - $nullable = $this->convertStringToBool($nullable); - $this->skipValidation = is_null($data) && $nullable; - - return $this->skipValidation || is_bool($data); - } - -} \ No newline at end of file diff --git a/src/ARTulloss/FilterX/libs/PASVL/Validator/FloatValidator.php b/src/ARTulloss/FilterX/libs/PASVL/Validator/FloatValidator.php deleted file mode 100644 index 633838d..0000000 --- a/src/ARTulloss/FilterX/libs/PASVL/Validator/FloatValidator.php +++ /dev/null @@ -1,22 +0,0 @@ - - * Date: 02/01/2018 - */ - -namespace ARTulloss\FilterX\libs\PASVL\Validator; - - -class FloatValidator extends NumberValidator -{ - /** @var boolean */ - protected $skipValidation; - - public function __invoke($data, string $nullable = "false"): bool - { - $nullable = $this->convertStringToBool($nullable); - $this->skipValidation = is_null($data) && $nullable; - - return $this->skipValidation || is_float($data); - } -} \ No newline at end of file diff --git a/src/ARTulloss/FilterX/libs/PASVL/Validator/IntValidator.php b/src/ARTulloss/FilterX/libs/PASVL/Validator/IntValidator.php deleted file mode 100644 index 4828c13..0000000 --- a/src/ARTulloss/FilterX/libs/PASVL/Validator/IntValidator.php +++ /dev/null @@ -1,22 +0,0 @@ - - * Date: 02/01/2018 - */ - -namespace ARTulloss\FilterX\libs\PASVL\Validator; - - -class IntValidator extends NumberValidator -{ - /** @var boolean */ - protected $skipValidation; - - public function __invoke($data, string $nullable = "false"): bool - { - $nullable = $this->convertStringToBool($nullable); - $this->skipValidation = is_null($data) && $nullable; - - return $this->skipValidation || is_integer($data); - } -} \ No newline at end of file diff --git a/src/ARTulloss/FilterX/libs/PASVL/Validator/InvalidData.php b/src/ARTulloss/FilterX/libs/PASVL/Validator/InvalidData.php deleted file mode 100644 index 68ad6a4..0000000 --- a/src/ARTulloss/FilterX/libs/PASVL/Validator/InvalidData.php +++ /dev/null @@ -1,29 +0,0 @@ - - * Date: 02/01/2018 - */ - -namespace ARTulloss\FilterX\libs\PASVL\Validator; - - -class InvalidData extends \Exception -{ - private $invalid_data = null; - - public function __construct(string $message = "", $invalid_data = null) - { - $this->invalid_data = $invalid_data; - parent::__construct($message); - } - - /** - * @return null - */ - public function getInvalidData() - { - return $this->invalid_data; - } - - -} \ No newline at end of file diff --git a/src/ARTulloss/FilterX/libs/PASVL/Validator/KeyValidator.php b/src/ARTulloss/FilterX/libs/PASVL/Validator/KeyValidator.php deleted file mode 100644 index afd3b99..0000000 --- a/src/ARTulloss/FilterX/libs/PASVL/Validator/KeyValidator.php +++ /dev/null @@ -1,22 +0,0 @@ - - * Date: 02/01/2018 - */ - -namespace ARTulloss\FilterX\libs\PASVL\Validator; - - -class KeyValidator extends Validator -{ - /** - * @param $data - * @param string|int $exact_value comes from the array's key which can be both int or string - * @return bool - */ - public function __invoke($data, $exact_value): bool - { - return $data === $exact_value; - } - -} \ No newline at end of file diff --git a/src/ARTulloss/FilterX/libs/PASVL/Validator/NumberValidator.php b/src/ARTulloss/FilterX/libs/PASVL/Validator/NumberValidator.php deleted file mode 100644 index e9a8a0f..0000000 --- a/src/ARTulloss/FilterX/libs/PASVL/Validator/NumberValidator.php +++ /dev/null @@ -1,116 +0,0 @@ - - * Date: 02/01/2018 - */ - -namespace ARTulloss\FilterX\libs\PASVL\Validator; - - -class NumberValidator extends Validator -{ - /** @var boolean */ - protected $skipValidation; - - public function __invoke($data, string $nullable = "false"): bool - { - $nullable = $this->convertStringToBool($nullable); - $this->skipValidation = is_null($data) && $nullable; - - return $this->skipValidation || is_integer($data) || is_float($data); - } - - public function between($data, $from, $to): bool - { - if ($this->skipValidation) { - return true; - } - - if ($to < $from) { - throw new \Exception("top boundary is lower than bottom boundary"); - } - - return $data <= $to && $data >= $from; - } - - public function in($data, ...$options): bool - { - if ($this->skipValidation) { - return true; - } - - return in_array($data, $options); - } - - public function gt($data, $compare): bool - { - if ($this->skipValidation) { - return true; - } - - return $data > $compare; - } - - public function gte($data, $compare): bool - { - if ($this->skipValidation) { - return true; - } - - return $data >= $compare; - } - - public function lt($data, $compare): bool - { - if ($this->skipValidation) { - return true; - } - - return $data < $compare; - } - - public function lte($data, $compare): bool - { - if ($this->skipValidation) { - return true; - } - - return $data <= $compare; - } - - public function negative($data): bool - { - if ($this->skipValidation) { - return true; - } - - return $data < 0; - } - - public function positive($data): bool - { - if ($this->skipValidation) { - return true; - } - - return $data > 0; - } - - public function min($data, $min): bool - { - if ($this->skipValidation) { - return true; - } - - return $this->gte($data, $min); - } - - public function max($data, $max): bool - { - if ($this->skipValidation) { - return true; - } - - return $this->lte($data, $max); - } -} \ No newline at end of file diff --git a/src/ARTulloss/FilterX/libs/PASVL/Validator/ObjectValidator.php b/src/ARTulloss/FilterX/libs/PASVL/Validator/ObjectValidator.php deleted file mode 100644 index d407659..0000000 --- a/src/ARTulloss/FilterX/libs/PASVL/Validator/ObjectValidator.php +++ /dev/null @@ -1,57 +0,0 @@ - - * Date: 02/01/2018 - */ - -namespace ARTulloss\FilterX\libs\PASVL\Validator; - - -class ObjectValidator extends Validator -{ - /** @var boolean */ - protected $skipValidation; - - /** - * @param $data - * @param string $nullable - * @return bool - */ - public function __invoke($data, string $nullable = "false"): bool - { - $nullable = $this->convertStringToBool($nullable); - $this->skipValidation = is_null($data) && $nullable; - - return is_object($data) || $this->skipValidation; - } - - public function instance($data, $fqcn): bool - { - if ($this->skipValidation) { - return true; - } - - return ($data instanceof $fqcn); - } - - public function property($data, $property, $value): bool - { - if ($this->skipValidation) { - return true; - } - - return (property_exists($data, $property) || property_exists($data, '__get')) - && $data->$property == $value; - } - - public function method($data, $method, $value): bool - { - if ($this->skipValidation) { - return true; - } - - return (method_exists($data, $method) || method_exists($data, '__call')) - && $data->$method() == $value; - } - -} \ No newline at end of file diff --git a/src/ARTulloss/FilterX/libs/PASVL/Validator/StringValidator.php b/src/ARTulloss/FilterX/libs/PASVL/Validator/StringValidator.php deleted file mode 100644 index 6a63010..0000000 --- a/src/ARTulloss/FilterX/libs/PASVL/Validator/StringValidator.php +++ /dev/null @@ -1,165 +0,0 @@ - - * Date: 02/01/2018 - */ - -namespace ARTulloss\FilterX\libs\PASVL\Validator; - - -class StringValidator extends Validator -{ - /** @var boolean */ - protected $skipValidation; - - public function __invoke($data, string $nullable = "false"): bool - { - $nullable = $this->convertStringToBool($nullable); - $this->skipValidation = is_null($data) && $nullable; - - return $this->skipValidation || is_string($data); - } - - public function len($data, int $length): bool - { - if ($this->skipValidation) { - return true; - } - - return mb_strlen($data, 'utf-8') == $length; - } - - public function length($data, int $length): bool - { - if ($this->skipValidation) { - return true; - } - - return $this->len($data, $length); - } - - public function min($data, int $length): bool - { - if ($this->skipValidation) { - return true; - } - - return mb_strlen($data) >= $length; - } - - public function max($data, int $length): bool - { - if ($this->skipValidation) { - return true; - } - - return mb_strlen($data) <= $length; - } - - public function contains($data, string $needle): bool - { - if ($this->skipValidation) { - return true; - } - - return mb_strpos($data, $needle) !== false; - } - - /** - * This regexp methods deserve a special comment. - * Since there can be commas in pattern definition like this: ":regex(#[a-z]{1,2}#)" - * So the pattern analyzer will split it into an array of ["#[a-z]{1","2}#"]. - * That's why code merges it back again - */ - public function regexp($data, ...$pattern): bool - { - if ($this->skipValidation) { - return true; - } - - $merged_pattern = implode(",", $pattern); - return preg_match($merged_pattern, $data); - } - - public function regex($data, ...$pattern): bool - { - if ($this->skipValidation) { - return true; - } - - return call_user_func_array([$this, "regexp"], array_merge([$data], $pattern)); - } - - - public function starts($data, string $starts): bool - { - if ($this->skipValidation) { - return true; - } - - return mb_strpos($data, $starts) === 0; - } - - public function ends($data, string $ends): bool - { - if ($this->skipValidation) { - return true; - } - - return mb_strrpos($data, $ends) === (strlen($data) - strlen($ends)); - } - - public function in($data, ...$options): bool - { - if ($this->skipValidation) { - return true; - } - - return in_array($data, $options); - } - - public function url($data): bool - { - if ($this->skipValidation) { - return true; - } - - return filter_var($data, FILTER_VALIDATE_URL); - } - - public function ip($data): bool - { - if ($this->skipValidation) { - return true; - } - - return filter_var($data, FILTER_VALIDATE_IP); - } - - public function email($data): bool - { - if ($this->skipValidation) { - return true; - } - - return filter_var($data, FILTER_VALIDATE_EMAIL); - } - - public function json($data): bool - { - if ($this->skipValidation) { - return true; - } - - return @json_decode($data) !== null; - } - - public function date($data): bool - { - if ($this->skipValidation) { - return true; - } - - return strtotime($data) !== false; - } -} \ No newline at end of file diff --git a/src/ARTulloss/FilterX/libs/PASVL/Validator/Validator.php b/src/ARTulloss/FilterX/libs/PASVL/Validator/Validator.php deleted file mode 100644 index 1f73fd8..0000000 --- a/src/ARTulloss/FilterX/libs/PASVL/Validator/Validator.php +++ /dev/null @@ -1,47 +0,0 @@ - - * Date: 02/01/2018 - */ - -namespace ARTulloss\FilterX\libs\PASVL\Validator; - - -abstract class Validator -{ - - public function nullable($data, string $strict = "true"): bool - { - $strict = $this->convertStringToBool($strict); - - return - (is_null($data) && $strict) - || ($data == null && !$strict) - || !is_null($data); - } - - public function __call($name, $arguments) - { - throw new \Exception("Missed sub-validator with name: " . static::class . "::" . $name); - } - - /** - * When we use a pattern ":name(false)" then argument is always passed as a string, - * this helper function converts a string to a boolean value by simple rules - * - * @param string $value - * @return bool - */ - protected function convertStringToBool(string $value): bool - { - // Anything but "false" converts to true - switch (strtolower($value)) { - case "false": - return false; - default: - return true; - } - - } - -} \ No newline at end of file diff --git a/src/ARTulloss/FilterX/libs/PASVL/ValidatorLocator/ValidatorLocator.php b/src/ARTulloss/FilterX/libs/PASVL/ValidatorLocator/ValidatorLocator.php deleted file mode 100644 index 71449a1..0000000 --- a/src/ARTulloss/FilterX/libs/PASVL/ValidatorLocator/ValidatorLocator.php +++ /dev/null @@ -1,54 +0,0 @@ - - * Date: 02/01/2018 - */ - -namespace ARTulloss\FilterX\libs\PASVL\ValidatorLocator; - -use ARTulloss\FilterX\libs\PASVL\Validator\Validator; - - -/** - * Goal is to look for validator classes - * @package PASVL - */ -class ValidatorLocator -{ - protected $cache = []; - - /** - * Takes validator string name and locates the corresponding class - * There is a set of default validators located at "src/Validator" folder - * - * @param string $name - * @return Validator - * @throws \Exception - */ - public function getValidatorClass(string $name): Validator - { - if (!array_key_exists($name, $this->cache)) { - if (!($validator = $this->locate($name))) { - if (!($validator = $this->locateDefault($name))) { - throw new \Exception("Missed validator: " . $name); - } - } - $this->cache[$name] = $validator; - } - - return $this->cache[$name]; - } - - protected function locateDefault(string $name): ?Validator - { - - $fqcn = "\\ARTulloss\\FilterX\\libs\\PASVL\\Validator\\" . ucfirst($name) . "Validator"; - return class_exists($fqcn) ? new $fqcn : null; - } - - protected function locate(string $name): ?object - { - // to be overridden in your own ValidatorLocator implementation (if any) - return null; - } -} diff --git a/src/ARTulloss/FilterX/libs/pasvl b/src/ARTulloss/FilterX/libs/pasvl new file mode 160000 index 0000000..e166aaf --- /dev/null +++ b/src/ARTulloss/FilterX/libs/pasvl @@ -0,0 +1 @@ +Subproject commit e166aafb3641a36a4fe294f9302cc07a6f823f74