New contact form with friendlycaptcha
This commit is contained in:
@@ -13,21 +13,17 @@ use Nette;
|
||||
use Nette\Schema\Context;
|
||||
use Nette\Schema\Helpers;
|
||||
use Nette\Schema\Schema;
|
||||
use function array_merge, array_unique, implode, is_array;
|
||||
|
||||
|
||||
final class AnyOf implements Schema
|
||||
{
|
||||
use Base;
|
||||
use Nette\SmartObject;
|
||||
|
||||
/** @var array */
|
||||
private $set;
|
||||
private array $set;
|
||||
|
||||
|
||||
/**
|
||||
* @param mixed|Schema ...$set
|
||||
*/
|
||||
public function __construct(...$set)
|
||||
public function __construct(mixed ...$set)
|
||||
{
|
||||
if (!$set) {
|
||||
throw new Nette\InvalidStateException('The enumeration must not be empty.');
|
||||
@@ -61,16 +57,16 @@ final class AnyOf implements Schema
|
||||
/********************* processing ****************d*g**/
|
||||
|
||||
|
||||
public function normalize($value, Context $context)
|
||||
public function normalize(mixed $value, Context $context): mixed
|
||||
{
|
||||
return $this->doNormalize($value, $context);
|
||||
}
|
||||
|
||||
|
||||
public function merge($value, $base)
|
||||
public function merge(mixed $value, mixed $base): mixed
|
||||
{
|
||||
if (is_array($value) && isset($value[Helpers::PREVENT_MERGING])) {
|
||||
unset($value[Helpers::PREVENT_MERGING]);
|
||||
if (is_array($value) && isset($value[Helpers::PreventMerging])) {
|
||||
unset($value[Helpers::PreventMerging]);
|
||||
return $value;
|
||||
}
|
||||
|
||||
@@ -78,7 +74,16 @@ final class AnyOf implements Schema
|
||||
}
|
||||
|
||||
|
||||
public function complete($value, Context $context)
|
||||
public function complete(mixed $value, Context $context): mixed
|
||||
{
|
||||
$isOk = $context->createChecker();
|
||||
$value = $this->findAlternative($value, $context);
|
||||
$isOk() && $value = $this->doTransform($value, $context);
|
||||
return $isOk() ? $value : null;
|
||||
}
|
||||
|
||||
|
||||
private function findAlternative(mixed $value, Context $context): mixed
|
||||
{
|
||||
$expecteds = $innerErrors = [];
|
||||
foreach ($this->set as $item) {
|
||||
@@ -88,7 +93,7 @@ final class AnyOf implements Schema
|
||||
$res = $item->complete($item->normalize($value, $dolly), $dolly);
|
||||
if (!$dolly->errors) {
|
||||
$context->warnings = array_merge($context->warnings, $dolly->warnings);
|
||||
return $this->doFinalize($res, $context);
|
||||
return $res;
|
||||
}
|
||||
|
||||
foreach ($dolly->errors as $error) {
|
||||
@@ -100,7 +105,7 @@ final class AnyOf implements Schema
|
||||
}
|
||||
} else {
|
||||
if ($item === $value) {
|
||||
return $this->doFinalize($value, $context);
|
||||
return $value;
|
||||
}
|
||||
|
||||
$expecteds[] = Nette\Schema\Helpers::formatValue($item);
|
||||
@@ -112,22 +117,24 @@ final class AnyOf implements Schema
|
||||
} else {
|
||||
$context->addError(
|
||||
'The %label% %path% expects to be %expected%, %value% given.',
|
||||
Nette\Schema\Message::TYPE_MISMATCH,
|
||||
Nette\Schema\Message::TypeMismatch,
|
||||
[
|
||||
'value' => $value,
|
||||
'expected' => implode('|', array_unique($expecteds)),
|
||||
]
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public function completeDefault(Context $context)
|
||||
public function completeDefault(Context $context): mixed
|
||||
{
|
||||
if ($this->required) {
|
||||
$context->addError(
|
||||
'The mandatory item %path% is missing.',
|
||||
Nette\Schema\Message::MISSING_ITEM
|
||||
Nette\Schema\Message::MissingItem,
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
161
vendor/nette/schema/src/Schema/Elements/Base.php
vendored
161
vendor/nette/schema/src/Schema/Elements/Base.php
vendored
@@ -11,6 +11,8 @@ namespace Nette\Schema\Elements;
|
||||
|
||||
use Nette;
|
||||
use Nette\Schema\Context;
|
||||
use Nette\Schema\Helpers;
|
||||
use function count, is_string;
|
||||
|
||||
|
||||
/**
|
||||
@@ -18,26 +20,18 @@ use Nette\Schema\Context;
|
||||
*/
|
||||
trait Base
|
||||
{
|
||||
/** @var bool */
|
||||
private $required = false;
|
||||
private bool $required = false;
|
||||
private mixed $default = null;
|
||||
|
||||
/** @var mixed */
|
||||
private $default;
|
||||
|
||||
/** @var callable|null */
|
||||
/** @var ?callable */
|
||||
private $before;
|
||||
|
||||
/** @var array[] */
|
||||
private $asserts = [];
|
||||
|
||||
/** @var string|null */
|
||||
private $castTo;
|
||||
|
||||
/** @var string|null */
|
||||
private $deprecated;
|
||||
/** @var callable[] */
|
||||
private array $transforms = [];
|
||||
private ?string $deprecated = null;
|
||||
|
||||
|
||||
public function default($value): self
|
||||
public function default(mixed $value): self
|
||||
{
|
||||
$this->default = $value;
|
||||
return $this;
|
||||
@@ -60,15 +54,30 @@ trait Base
|
||||
|
||||
public function castTo(string $type): self
|
||||
{
|
||||
$this->castTo = $type;
|
||||
return $this->transform(Helpers::getCastStrategy($type));
|
||||
}
|
||||
|
||||
|
||||
public function transform(callable $handler): self
|
||||
{
|
||||
$this->transforms[] = $handler;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
public function assert(callable $handler, ?string $description = null): self
|
||||
{
|
||||
$this->asserts[] = [$handler, $description];
|
||||
return $this;
|
||||
$expected = $description ?: (is_string($handler) ? "$handler()" : '#' . count($this->transforms));
|
||||
return $this->transform(function ($value, Context $context) use ($handler, $description, $expected) {
|
||||
if ($handler($value)) {
|
||||
return $value;
|
||||
}
|
||||
$context->addError(
|
||||
'Failed assertion ' . ($description ? "'%assertion%'" : '%assertion%') . ' for %label% %path% with value %value%.',
|
||||
Nette\Schema\Message::FailedAssertion,
|
||||
['value' => $value, 'assertion' => $expected],
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -80,12 +89,12 @@ trait Base
|
||||
}
|
||||
|
||||
|
||||
public function completeDefault(Context $context)
|
||||
public function completeDefault(Context $context): mixed
|
||||
{
|
||||
if ($this->required) {
|
||||
$context->addError(
|
||||
'The mandatory item %path% is missing.',
|
||||
Nette\Schema\Message::MISSING_ITEM
|
||||
Nette\Schema\Message::MissingItem,
|
||||
);
|
||||
return null;
|
||||
}
|
||||
@@ -94,7 +103,7 @@ trait Base
|
||||
}
|
||||
|
||||
|
||||
public function doNormalize($value, Context $context)
|
||||
public function doNormalize(mixed $value, Context $context): mixed
|
||||
{
|
||||
if ($this->before) {
|
||||
$value = ($this->before)($value);
|
||||
@@ -109,92 +118,46 @@ trait Base
|
||||
if ($this->deprecated !== null) {
|
||||
$context->addWarning(
|
||||
$this->deprecated,
|
||||
Nette\Schema\Message::DEPRECATED
|
||||
Nette\Schema\Message::Deprecated,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function doValidate($value, string $expected, Context $context): bool
|
||||
private function doTransform(mixed $value, Context $context): mixed
|
||||
{
|
||||
if (!Nette\Utils\Validators::is($value, $expected)) {
|
||||
$expected = str_replace(['|', ':'], [' or ', ' in range '], $expected);
|
||||
$context->addError(
|
||||
'The %label% %path% expects to be %expected%, %value% given.',
|
||||
Nette\Schema\Message::TYPE_MISMATCH,
|
||||
['value' => $value, 'expected' => $expected]
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private function doValidateRange($value, array $range, Context $context, string $types = ''): bool
|
||||
{
|
||||
if (is_array($value) || is_string($value)) {
|
||||
[$length, $label] = is_array($value)
|
||||
? [count($value), 'items']
|
||||
: (in_array('unicode', explode('|', $types), true)
|
||||
? [Nette\Utils\Strings::length($value), 'characters']
|
||||
: [strlen($value), 'bytes']);
|
||||
|
||||
if (!self::isInRange($length, $range)) {
|
||||
$context->addError(
|
||||
"The length of %label% %path% expects to be in range %expected%, %length% $label given.",
|
||||
Nette\Schema\Message::LENGTH_OUT_OF_RANGE,
|
||||
['value' => $value, 'length' => $length, 'expected' => implode('..', $range)]
|
||||
);
|
||||
return false;
|
||||
}
|
||||
} elseif ((is_int($value) || is_float($value)) && !self::isInRange($value, $range)) {
|
||||
$context->addError(
|
||||
'The %label% %path% expects to be in range %expected%, %value% given.',
|
||||
Nette\Schema\Message::VALUE_OUT_OF_RANGE,
|
||||
['value' => $value, 'expected' => implode('..', $range)]
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private function isInRange($value, array $range): bool
|
||||
{
|
||||
return ($range[0] === null || $value >= $range[0])
|
||||
&& ($range[1] === null || $value <= $range[1]);
|
||||
}
|
||||
|
||||
|
||||
private function doFinalize($value, Context $context)
|
||||
{
|
||||
if ($this->castTo) {
|
||||
if (Nette\Utils\Reflection::isBuiltinType($this->castTo)) {
|
||||
settype($value, $this->castTo);
|
||||
} else {
|
||||
$object = new $this->castTo;
|
||||
foreach ($value as $k => $v) {
|
||||
$object->$k = $v;
|
||||
}
|
||||
|
||||
$value = $object;
|
||||
$isOk = $context->createChecker();
|
||||
foreach ($this->transforms as $handler) {
|
||||
$value = $handler($value, $context);
|
||||
if (!$isOk()) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->asserts as $i => [$handler, $description]) {
|
||||
if (!$handler($value)) {
|
||||
$expected = $description ?: (is_string($handler) ? "$handler()" : "#$i");
|
||||
$context->addError(
|
||||
'Failed assertion ' . ($description ? "'%assertion%'" : '%assertion%') . ' for %label% %path% with value %value%.',
|
||||
Nette\Schema\Message::FAILED_ASSERTION,
|
||||
['value' => $value, 'assertion' => $expected]
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
/** @deprecated use Nette\Schema\Validators::validateType() */
|
||||
private function doValidate(mixed $value, string $expected, Context $context): bool
|
||||
{
|
||||
$isOk = $context->createChecker();
|
||||
Helpers::validateType($value, $expected, $context);
|
||||
return $isOk();
|
||||
}
|
||||
|
||||
|
||||
/** @deprecated use Nette\Schema\Validators::validateRange() */
|
||||
private static function doValidateRange(mixed $value, array $range, Context $context, string $types = ''): bool
|
||||
{
|
||||
$isOk = $context->createChecker();
|
||||
Helpers::validateRange($value, $range, $context, $types);
|
||||
return $isOk();
|
||||
}
|
||||
|
||||
|
||||
/** @deprecated use doTransform() */
|
||||
private function doFinalize(mixed $value, Context $context): mixed
|
||||
{
|
||||
return $this->doTransform($value, $context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,39 +13,37 @@ use Nette;
|
||||
use Nette\Schema\Context;
|
||||
use Nette\Schema\Helpers;
|
||||
use Nette\Schema\Schema;
|
||||
use function array_diff_key, array_fill_keys, array_key_exists, array_keys, array_map, array_merge, array_pop, array_values, is_array, is_object;
|
||||
|
||||
|
||||
final class Structure implements Schema
|
||||
{
|
||||
use Base;
|
||||
use Nette\SmartObject;
|
||||
|
||||
/** @var Schema[] */
|
||||
private $items;
|
||||
private array $items;
|
||||
|
||||
/** @var Schema|null for array|list */
|
||||
private $otherItems;
|
||||
/** for array|list */
|
||||
private ?Schema $otherItems = null;
|
||||
|
||||
/** @var array{?int, ?int} */
|
||||
private $range = [null, null];
|
||||
|
||||
/** @var bool */
|
||||
private $skipDefaults = false;
|
||||
private array $range = [null, null];
|
||||
private bool $skipDefaults = false;
|
||||
|
||||
|
||||
/**
|
||||
* @param Schema[] $items
|
||||
* @param Schema[] $shape
|
||||
*/
|
||||
public function __construct(array $items)
|
||||
public function __construct(array $shape)
|
||||
{
|
||||
(function (Schema ...$items) {})(...array_values($items));
|
||||
$this->items = $items;
|
||||
$this->castTo = 'object';
|
||||
(function (Schema ...$items) {})(...array_values($shape));
|
||||
$this->items = $shape;
|
||||
$this->castTo('object');
|
||||
$this->required = true;
|
||||
}
|
||||
|
||||
|
||||
public function default($value): self
|
||||
public function default(mixed $value): self
|
||||
{
|
||||
throw new Nette\InvalidStateException('Structure cannot have default value.');
|
||||
}
|
||||
@@ -65,10 +63,7 @@ final class Structure implements Schema
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string|Schema $type
|
||||
*/
|
||||
public function otherItems($type = 'mixed'): self
|
||||
public function otherItems(string|Schema $type = 'mixed'): self
|
||||
{
|
||||
$this->otherItems = $type instanceof Schema ? $type : new Type($type);
|
||||
return $this;
|
||||
@@ -82,13 +77,26 @@ final class Structure implements Schema
|
||||
}
|
||||
|
||||
|
||||
public function extend(array|self $shape): self
|
||||
{
|
||||
$shape = $shape instanceof self ? $shape->items : $shape;
|
||||
return new self(array_merge($this->items, $shape));
|
||||
}
|
||||
|
||||
|
||||
public function getShape(): array
|
||||
{
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
|
||||
/********************* processing ****************d*g**/
|
||||
|
||||
|
||||
public function normalize($value, Context $context)
|
||||
public function normalize(mixed $value, Context $context): mixed
|
||||
{
|
||||
if ($prevent = (is_array($value) && isset($value[Helpers::PREVENT_MERGING]))) {
|
||||
unset($value[Helpers::PREVENT_MERGING]);
|
||||
if ($prevent = (is_array($value) && isset($value[Helpers::PreventMerging]))) {
|
||||
unset($value[Helpers::PreventMerging]);
|
||||
}
|
||||
|
||||
$value = $this->doNormalize($value, $context);
|
||||
@@ -107,7 +115,7 @@ final class Structure implements Schema
|
||||
}
|
||||
|
||||
if ($prevent) {
|
||||
$value[Helpers::PREVENT_MERGING] = true;
|
||||
$value[Helpers::PreventMerging] = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,37 +123,34 @@ final class Structure implements Schema
|
||||
}
|
||||
|
||||
|
||||
public function merge($value, $base)
|
||||
public function merge(mixed $value, mixed $base): mixed
|
||||
{
|
||||
if (is_array($value) && isset($value[Helpers::PREVENT_MERGING])) {
|
||||
unset($value[Helpers::PREVENT_MERGING]);
|
||||
if (is_array($value) && isset($value[Helpers::PreventMerging])) {
|
||||
unset($value[Helpers::PreventMerging]);
|
||||
$base = null;
|
||||
}
|
||||
|
||||
if (is_array($value) && is_array($base)) {
|
||||
$index = 0;
|
||||
$index = $this->otherItems === null ? null : 0;
|
||||
foreach ($value as $key => $val) {
|
||||
if ($key === $index) {
|
||||
$base[] = $val;
|
||||
$index++;
|
||||
} elseif (array_key_exists($key, $base)) {
|
||||
$itemSchema = $this->items[$key] ?? $this->otherItems;
|
||||
$base[$key] = $itemSchema
|
||||
? $itemSchema->merge($val, $base[$key])
|
||||
: Helpers::merge($val, $base[$key]);
|
||||
} else {
|
||||
$base[$key] = $val;
|
||||
$base[$key] = array_key_exists($key, $base) && ($itemSchema = $this->items[$key] ?? $this->otherItems)
|
||||
? $itemSchema->merge($val, $base[$key])
|
||||
: $val;
|
||||
}
|
||||
}
|
||||
|
||||
return $base;
|
||||
}
|
||||
|
||||
return Helpers::merge($value, $base);
|
||||
return $value ?? $base;
|
||||
}
|
||||
|
||||
|
||||
public function complete($value, Context $context)
|
||||
public function complete(mixed $value, Context $context): mixed
|
||||
{
|
||||
if ($value === null) {
|
||||
$value = []; // is unable to distinguish null from array in NEON
|
||||
@@ -153,13 +158,17 @@ final class Structure implements Schema
|
||||
|
||||
$this->doDeprecation($context);
|
||||
|
||||
if (!$this->doValidate($value, 'array', $context)
|
||||
|| !$this->doValidateRange($value, $this->range, $context)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
$isOk = $context->createChecker();
|
||||
Helpers::validateType($value, 'array', $context);
|
||||
$isOk() && Helpers::validateRange($value, $this->range, $context);
|
||||
$isOk() && $this->validateItems($value, $context);
|
||||
$isOk() && $value = $this->doTransform($value, $context);
|
||||
return $isOk() ? $value : null;
|
||||
}
|
||||
|
||||
$errCount = count($context->errors);
|
||||
|
||||
private function validateItems(array &$value, Context $context): void
|
||||
{
|
||||
$items = $this->items;
|
||||
if ($extraKeys = array_keys(array_diff_key($value, $items))) {
|
||||
if ($this->otherItems) {
|
||||
@@ -167,11 +176,11 @@ final class Structure implements Schema
|
||||
} else {
|
||||
$keys = array_map('strval', array_keys($items));
|
||||
foreach ($extraKeys as $key) {
|
||||
$hint = Nette\Utils\ObjectHelpers::getSuggestion($keys, (string) $key);
|
||||
$hint = Nette\Utils\Helpers::getSuggestion($keys, (string) $key);
|
||||
$context->addError(
|
||||
'Unexpected item %path%' . ($hint ? ", did you mean '%hint%'?" : '.'),
|
||||
Nette\Schema\Message::UNEXPECTED_ITEM,
|
||||
['hint' => $hint]
|
||||
Nette\Schema\Message::UnexpectedItem,
|
||||
['hint' => $hint],
|
||||
)->path[] = $key;
|
||||
}
|
||||
}
|
||||
@@ -190,16 +199,10 @@ final class Structure implements Schema
|
||||
|
||||
array_pop($context->path);
|
||||
}
|
||||
|
||||
if (count($context->errors) > $errCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
return $this->doFinalize($value, $context);
|
||||
}
|
||||
|
||||
|
||||
public function completeDefault(Context $context)
|
||||
public function completeDefault(Context $context): mixed
|
||||
{
|
||||
return $this->required
|
||||
? $this->complete([], $context)
|
||||
|
||||
113
vendor/nette/schema/src/Schema/Elements/Type.php
vendored
113
vendor/nette/schema/src/Schema/Elements/Type.php
vendored
@@ -9,35 +9,25 @@ declare(strict_types=1);
|
||||
|
||||
namespace Nette\Schema\Elements;
|
||||
|
||||
use Nette;
|
||||
use Nette\Schema\Context;
|
||||
use Nette\Schema\DynamicParameter;
|
||||
use Nette\Schema\Helpers;
|
||||
use Nette\Schema\Schema;
|
||||
use function array_key_exists, array_pop, implode, is_array, str_replace, strpos;
|
||||
|
||||
|
||||
final class Type implements Schema
|
||||
{
|
||||
use Base;
|
||||
use Nette\SmartObject;
|
||||
|
||||
/** @var string */
|
||||
private $type;
|
||||
|
||||
/** @var Schema|null for arrays */
|
||||
private $itemsValue;
|
||||
|
||||
/** @var Schema|null for arrays */
|
||||
private $itemsKey;
|
||||
private string $type;
|
||||
private ?Schema $itemsValue = null;
|
||||
private ?Schema $itemsKey = null;
|
||||
|
||||
/** @var array{?float, ?float} */
|
||||
private $range = [null, null];
|
||||
|
||||
/** @var string|null */
|
||||
private $pattern;
|
||||
|
||||
/** @var bool */
|
||||
private $merge = true;
|
||||
private array $range = [null, null];
|
||||
private ?string $pattern = null;
|
||||
private bool $merge = true;
|
||||
|
||||
|
||||
public function __construct(string $type)
|
||||
@@ -84,11 +74,9 @@ final class Type implements Schema
|
||||
|
||||
|
||||
/**
|
||||
* @param string|Schema $valueType
|
||||
* @param string|Schema|null $keyType
|
||||
* @internal use arrayOf() or listOf()
|
||||
*/
|
||||
public function items($valueType = 'mixed', $keyType = null): self
|
||||
public function items(string|Schema $valueType = 'mixed', string|Schema|null $keyType = null): self
|
||||
{
|
||||
$this->itemsValue = $valueType instanceof Schema
|
||||
? $valueType
|
||||
@@ -110,10 +98,10 @@ final class Type implements Schema
|
||||
/********************* processing ****************d*g**/
|
||||
|
||||
|
||||
public function normalize($value, Context $context)
|
||||
public function normalize(mixed $value, Context $context): mixed
|
||||
{
|
||||
if ($prevent = (is_array($value) && isset($value[Helpers::PREVENT_MERGING]))) {
|
||||
unset($value[Helpers::PREVENT_MERGING]);
|
||||
if ($prevent = (is_array($value) && isset($value[Helpers::PreventMerging]))) {
|
||||
unset($value[Helpers::PreventMerging]);
|
||||
}
|
||||
|
||||
$value = $this->doNormalize($value, $context);
|
||||
@@ -134,17 +122,17 @@ final class Type implements Schema
|
||||
}
|
||||
|
||||
if ($prevent && is_array($value)) {
|
||||
$value[Helpers::PREVENT_MERGING] = true;
|
||||
$value[Helpers::PreventMerging] = true;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
public function merge($value, $base)
|
||||
public function merge(mixed $value, mixed $base): mixed
|
||||
{
|
||||
if (is_array($value) && isset($value[Helpers::PREVENT_MERGING])) {
|
||||
unset($value[Helpers::PREVENT_MERGING]);
|
||||
if (is_array($value) && isset($value[Helpers::PreventMerging])) {
|
||||
unset($value[Helpers::PreventMerging]);
|
||||
return $value;
|
||||
}
|
||||
|
||||
@@ -168,11 +156,11 @@ final class Type implements Schema
|
||||
}
|
||||
|
||||
|
||||
public function complete($value, Context $context)
|
||||
public function complete(mixed $value, Context $context): mixed
|
||||
{
|
||||
$merge = $this->merge;
|
||||
if (is_array($value) && isset($value[Helpers::PREVENT_MERGING])) {
|
||||
unset($value[Helpers::PREVENT_MERGING]);
|
||||
if (is_array($value) && isset($value[Helpers::PreventMerging])) {
|
||||
unset($value[Helpers::PreventMerging]);
|
||||
$merge = false;
|
||||
}
|
||||
|
||||
@@ -182,49 +170,40 @@ final class Type implements Schema
|
||||
|
||||
$this->doDeprecation($context);
|
||||
|
||||
if (!$this->doValidate($value, $this->type, $context)
|
||||
|| !$this->doValidateRange($value, $this->range, $context, $this->type)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($value !== null && $this->pattern !== null && !preg_match("\x01^(?:$this->pattern)$\x01Du", $value)) {
|
||||
$context->addError(
|
||||
"The %label% %path% expects to match pattern '%pattern%', %value% given.",
|
||||
Nette\Schema\Message::PATTERN_MISMATCH,
|
||||
['value' => $value, 'pattern' => $this->pattern]
|
||||
);
|
||||
return;
|
||||
$isOk = $context->createChecker();
|
||||
Helpers::validateType($value, $this->type, $context);
|
||||
$isOk() && Helpers::validateRange($value, $this->range, $context, $this->type);
|
||||
$isOk() && $value !== null && $this->pattern !== null && Helpers::validatePattern($value, $this->pattern, $context);
|
||||
$isOk() && is_array($value) && $this->validateItems($value, $context);
|
||||
$isOk() && $merge && $value = Helpers::merge($value, $this->default);
|
||||
$isOk() && $value = $this->doTransform($value, $context);
|
||||
if (!$isOk()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($value instanceof DynamicParameter) {
|
||||
$expected = $this->type . ($this->range === [null, null] ? '' : ':' . implode('..', $this->range));
|
||||
$context->dynamics[] = [$value, str_replace(DynamicParameter::class . '|', '', $expected)];
|
||||
$context->dynamics[] = [$value, str_replace(DynamicParameter::class . '|', '', $expected), $context->path];
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
private function validateItems(array &$value, Context $context): void
|
||||
{
|
||||
if (!$this->itemsValue) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->itemsValue) {
|
||||
$errCount = count($context->errors);
|
||||
$res = [];
|
||||
foreach ($value as $key => $val) {
|
||||
$context->path[] = $key;
|
||||
$context->isKey = true;
|
||||
$key = $this->itemsKey ? $this->itemsKey->complete($key, $context) : $key;
|
||||
$context->isKey = false;
|
||||
$res[$key] = $this->itemsValue->complete($val, $context);
|
||||
array_pop($context->path);
|
||||
}
|
||||
|
||||
if (count($context->errors) > $errCount) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$value = $res;
|
||||
$res = [];
|
||||
foreach ($value as $key => $val) {
|
||||
$context->path[] = $key;
|
||||
$context->isKey = true;
|
||||
$key = $this->itemsKey ? $this->itemsKey->complete($key, $context) : $key;
|
||||
$context->isKey = false;
|
||||
$res[$key ?? ''] = $this->itemsValue->complete($val, $context);
|
||||
array_pop($context->path);
|
||||
}
|
||||
|
||||
if ($merge) {
|
||||
$value = Helpers::merge($value, $this->default);
|
||||
}
|
||||
|
||||
return $this->doFinalize($value, $context);
|
||||
$value = $res;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user