validation-bugsnag-email
This commit is contained in:
3
vendor/nette/utils/composer.json
vendored
3
vendor/nette/utils/composer.json
vendored
@@ -20,7 +20,8 @@
|
||||
"require-dev": {
|
||||
"nette/tester": "~2.0",
|
||||
"tracy/tracy": "^2.3",
|
||||
"phpstan/phpstan": "^1.0"
|
||||
"phpstan/phpstan": "^1.0",
|
||||
"jetbrains/phpstorm-attributes": "dev-master"
|
||||
},
|
||||
"conflict": {
|
||||
"nette/di": "<3.0.6"
|
||||
|
33
vendor/nette/utils/contributing.md
vendored
33
vendor/nette/utils/contributing.md
vendored
@@ -1,33 +0,0 @@
|
||||
How to contribute & use the issue tracker
|
||||
=========================================
|
||||
|
||||
Nette welcomes your contributions. There are several ways to help out:
|
||||
|
||||
* Create an issue on GitHub, if you have found a bug
|
||||
* Write test cases for open bug issues
|
||||
* Write fixes for open bug/feature issues, preferably with test cases included
|
||||
* Contribute to the [documentation](https://nette.org/en/writing)
|
||||
|
||||
Issues
|
||||
------
|
||||
|
||||
Please **do not use the issue tracker to ask questions**. We will be happy to help you
|
||||
on [Nette forum](https://forum.nette.org) or chat with us on [Gitter](https://gitter.im/nette/nette).
|
||||
|
||||
A good bug report shouldn't leave others needing to chase you up for more
|
||||
information. Please try to be as detailed as possible in your report.
|
||||
|
||||
**Feature requests** are welcome. But take a moment to find out whether your idea
|
||||
fits with the scope and aims of the project. It's up to *you* to make a strong
|
||||
case to convince the project's developers of the merits of this feature.
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
If you'd like to contribute, please take a moment to read [the contributing guide](https://nette.org/en/contributing).
|
||||
|
||||
The best way to propose a feature is to discuss your ideas on [Nette forum](https://forum.nette.org) before implementing them.
|
||||
|
||||
Please do not fix whitespace, format code, or make a purely cosmetic patch.
|
||||
|
||||
Thanks! :heart:
|
14
vendor/nette/utils/ncs.php
vendored
14
vendor/nette/utils/ncs.php
vendored
@@ -1,14 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Rules for Nette Coding Standard
|
||||
* https://github.com/nette/coding-standard
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
// use function in Arrays.php, Callback.php, Html.php, Strings.php
|
||||
'single_import_per_statement' => false,
|
||||
'ordered_imports' => false,
|
||||
];
|
18
vendor/nette/utils/ncs.xml
vendored
18
vendor/nette/utils/ncs.xml
vendored
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<ruleset name="Custom" namespace="Nette">
|
||||
<rule ref="$presets/php72.xml"/>
|
||||
|
||||
<!-- bug in SlevomatCodingStandard -->
|
||||
<rule ref="SlevomatCodingStandard.Operators.RequireCombinedAssignmentOperator">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
|
||||
<!-- bug in FunctionSpacingSniff -->
|
||||
<exclude-pattern>./tests/Utils/Reflection.getDeclaringMethod.alias.phpt</exclude-pattern>
|
||||
<exclude-pattern>./tests/Utils/Reflection.getDeclaringMethod.insteadof.phpt</exclude-pattern>
|
||||
|
||||
<!-- use function in Arrays.php, Callback.php, Html.php, Strings.php -->
|
||||
<rule ref="SlevomatCodingStandard.Namespaces.MultipleUsesPerLine.MultipleUsesPerLine">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
</ruleset>
|
30
vendor/nette/utils/readme.md
vendored
30
vendor/nette/utils/readme.md
vendored
@@ -13,21 +13,21 @@ Introduction
|
||||
|
||||
In package nette/utils you will find a set of [useful classes](https://doc.nette.org/utils) for everyday use:
|
||||
|
||||
- [Arrays](https://doc.nette.org/arrays) - manipulate arrays
|
||||
- [Callback](https://doc.nette.org/callback) - PHP callbacks
|
||||
- [Date and Time](https://doc.nette.org/datetime) - modify times and dates
|
||||
- [Filesystem](https://doc.nette.org/filesystem) - copying, renaming, …
|
||||
- [Helper Functions](https://doc.nette.org/helpers)
|
||||
- [HTML elements](https://doc.nette.org/html-elements) - generate HTML
|
||||
- [Images](https://doc.nette.org/images) - crop, resize, rotate images
|
||||
- [JSON](https://doc.nette.org/json) - encoding and decoding
|
||||
- [Generating Random Strings](https://doc.nette.org/random)
|
||||
- [Paginator](https://doc.nette.org/paginator) - pagination math
|
||||
- [PHP Reflection](https://doc.nette.org/reflection)
|
||||
- [Strings](https://doc.nette.org/strings) - useful text functions
|
||||
- [SmartObject](https://doc.nette.org/smartobject) - PHP object enhancements
|
||||
- [Validation](https://doc.nette.org/validators) - validate inputs
|
||||
- [Type](https://doc.nette.org/type) - PHP data type
|
||||
- [Arrays](https://doc.nette.org/utils/arrays) - manipulate arrays
|
||||
- [Callback](https://doc.nette.org/utils/callback) - PHP callbacks
|
||||
- [Date and Time](https://doc.nette.org/utils/datetime) - modify times and dates
|
||||
- [Filesystem](https://doc.nette.org/utils/filesystem) - copying, renaming, …
|
||||
- [Helper Functions](https://doc.nette.org/utils/helpers)
|
||||
- [HTML elements](https://doc.nette.org/utils/html-elements) - generate HTML
|
||||
- [Images](https://doc.nette.org/utils/images) - crop, resize, rotate images
|
||||
- [JSON](https://doc.nette.org/utils/json) - encoding and decoding
|
||||
- [Generating Random Strings](https://doc.nette.org/utils/random)
|
||||
- [Paginator](https://doc.nette.org/utils/paginator) - pagination math
|
||||
- [PHP Reflection](https://doc.nette.org/utils/reflection)
|
||||
- [Strings](https://doc.nette.org/utils/strings) - useful text functions
|
||||
- [SmartObject](https://doc.nette.org/utils/smartobject) - PHP object enhancements
|
||||
- [Validation](https://doc.nette.org/utils/validators) - validate inputs
|
||||
- [Type](https://doc.nette.org/utils/type) - PHP data type
|
||||
|
||||
|
||||
Installation
|
||||
|
8
vendor/nette/utils/src/Utils/Arrays.php
vendored
8
vendor/nette/utils/src/Utils/Arrays.php
vendored
@@ -9,6 +9,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Nette\Utils;
|
||||
|
||||
use JetBrains\PhpStorm\Language;
|
||||
use Nette;
|
||||
use function is_array, is_int, is_object, count;
|
||||
|
||||
@@ -203,7 +204,12 @@ class Arrays
|
||||
* @param string[] $array
|
||||
* @return string[]
|
||||
*/
|
||||
public static function grep(array $array, string $pattern, int $flags = 0): array
|
||||
public static function grep(
|
||||
array $array,
|
||||
#[Language('RegExp')]
|
||||
string $pattern,
|
||||
int $flags = 0
|
||||
): array
|
||||
{
|
||||
return Strings::pcre('preg_grep', [$pattern, $array, $flags]);
|
||||
}
|
||||
|
2
vendor/nette/utils/src/Utils/Callback.php
vendored
2
vendor/nette/utils/src/Utils/Callback.php
vendored
@@ -157,7 +157,7 @@ final class Callback
|
||||
*/
|
||||
public static function isStatic(callable $callable): bool
|
||||
{
|
||||
return is_array($callable) ? is_string($callable[0]) : is_string($callable);
|
||||
return is_string(is_array($callable) ? $callable[0] : $callable);
|
||||
}
|
||||
|
||||
|
||||
|
3
vendor/nette/utils/src/Utils/Image.php
vendored
3
vendor/nette/utils/src/Utils/Image.php
vendored
@@ -393,7 +393,8 @@ class Image
|
||||
$newWidth,
|
||||
$newHeight,
|
||||
int $flags = self::FIT
|
||||
): array {
|
||||
): array
|
||||
{
|
||||
if ($newWidth === null) {
|
||||
} elseif (self::isPercent($newWidth)) {
|
||||
$newWidth = (int) round($srcWidth / 100 * abs($newWidth));
|
||||
|
17
vendor/nette/utils/src/Utils/Reflection.php
vendored
17
vendor/nette/utils/src/Utils/Reflection.php
vendored
@@ -19,23 +19,12 @@ final class Reflection
|
||||
{
|
||||
use Nette\StaticClass;
|
||||
|
||||
private const BuiltinTypes = [
|
||||
'string' => 1, 'int' => 1, 'float' => 1, 'bool' => 1, 'array' => 1, 'object' => 1,
|
||||
'callable' => 1, 'iterable' => 1, 'void' => 1, 'null' => 1, 'mixed' => 1, 'false' => 1,
|
||||
'never' => 1,
|
||||
];
|
||||
|
||||
private const ClassKeywords = [
|
||||
'self' => 1, 'parent' => 1, 'static' => 1,
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Determines if type is PHP built-in type. Otherwise, it is the class name.
|
||||
*/
|
||||
public static function isBuiltinType(string $type): bool
|
||||
{
|
||||
return isset(self::BuiltinTypes[strtolower($type)]);
|
||||
return Validators::isBuiltinType($type);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +33,7 @@ final class Reflection
|
||||
*/
|
||||
public static function isClassKeyword(string $name): bool
|
||||
{
|
||||
return isset(self::ClassKeywords[strtolower($name)]);
|
||||
return Validators::isClassKeyword($name);
|
||||
}
|
||||
|
||||
|
||||
@@ -261,7 +250,7 @@ final class Reflection
|
||||
if (empty($name)) {
|
||||
throw new Nette\InvalidArgumentException('Class name must not be empty.');
|
||||
|
||||
} elseif (isset(self::BuiltinTypes[$lower])) {
|
||||
} elseif (Validators::isBuiltinType($lower)) {
|
||||
return $lower;
|
||||
|
||||
} elseif ($lower === 'self' || $lower === 'static') {
|
||||
|
32
vendor/nette/utils/src/Utils/Strings.php
vendored
32
vendor/nette/utils/src/Utils/Strings.php
vendored
@@ -9,6 +9,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Nette\Utils;
|
||||
|
||||
use JetBrains\PhpStorm\Language;
|
||||
use Nette;
|
||||
use function is_array, is_object, strlen;
|
||||
|
||||
@@ -485,7 +486,12 @@ class Strings
|
||||
* Splits a string into array by the regular expression. Parenthesized expression in the delimiter are captured.
|
||||
* Parameter $flags can be any combination of PREG_SPLIT_NO_EMPTY and PREG_OFFSET_CAPTURE flags.
|
||||
*/
|
||||
public static function split(string $subject, string $pattern, int $flags = 0): array
|
||||
public static function split(
|
||||
string $subject,
|
||||
#[Language('RegExp')]
|
||||
string $pattern,
|
||||
int $flags = 0
|
||||
): array
|
||||
{
|
||||
return self::pcre('preg_split', [$pattern, $subject, -1, $flags | PREG_SPLIT_DELIM_CAPTURE]);
|
||||
}
|
||||
@@ -495,7 +501,13 @@ class Strings
|
||||
* Checks if given string matches a regular expression pattern and returns an array with first found match and each subpattern.
|
||||
* Parameter $flags can be any combination of PREG_OFFSET_CAPTURE and PREG_UNMATCHED_AS_NULL flags.
|
||||
*/
|
||||
public static function match(string $subject, string $pattern, int $flags = 0, int $offset = 0): ?array
|
||||
public static function match(
|
||||
string $subject,
|
||||
#[Language('RegExp')]
|
||||
string $pattern,
|
||||
int $flags = 0,
|
||||
int $offset = 0
|
||||
): ?array
|
||||
{
|
||||
if ($offset > strlen($subject)) {
|
||||
return null;
|
||||
@@ -511,7 +523,13 @@ class Strings
|
||||
* Finds all occurrences matching regular expression pattern and returns a two-dimensional array. Result is array of matches (ie uses by default PREG_SET_ORDER).
|
||||
* Parameter $flags can be any combination of PREG_OFFSET_CAPTURE, PREG_UNMATCHED_AS_NULL and PREG_PATTERN_ORDER flags.
|
||||
*/
|
||||
public static function matchAll(string $subject, string $pattern, int $flags = 0, int $offset = 0): array
|
||||
public static function matchAll(
|
||||
string $subject,
|
||||
#[Language('RegExp')]
|
||||
string $pattern,
|
||||
int $flags = 0,
|
||||
int $offset = 0
|
||||
): array
|
||||
{
|
||||
if ($offset > strlen($subject)) {
|
||||
return [];
|
||||
@@ -531,7 +549,13 @@ class Strings
|
||||
* @param string|array $pattern
|
||||
* @param string|callable $replacement
|
||||
*/
|
||||
public static function replace(string $subject, $pattern, $replacement = '', int $limit = -1): string
|
||||
public static function replace(
|
||||
string $subject,
|
||||
#[Language('RegExp')]
|
||||
$pattern,
|
||||
$replacement = '',
|
||||
int $limit = -1
|
||||
): string
|
||||
{
|
||||
if (is_object($replacement) || is_array($replacement)) {
|
||||
if (!is_callable($replacement, false, $textual)) {
|
||||
|
160
vendor/nette/utils/src/Utils/Type.php
vendored
160
vendor/nette/utils/src/Utils/Type.php
vendored
@@ -17,11 +17,11 @@ use Nette;
|
||||
*/
|
||||
final class Type
|
||||
{
|
||||
/** @var array */
|
||||
/** @var array<int, string|self> */
|
||||
private $types;
|
||||
|
||||
/** @var bool */
|
||||
private $single;
|
||||
private $simple;
|
||||
|
||||
/** @var string |, & */
|
||||
private $kind;
|
||||
@@ -44,24 +44,29 @@ final class Type
|
||||
: $reflection->getType();
|
||||
}
|
||||
|
||||
if ($type === null) {
|
||||
return null;
|
||||
return $type ? self::fromReflectionType($type, $reflection, true) : null;
|
||||
}
|
||||
|
||||
} elseif ($type instanceof \ReflectionNamedType) {
|
||||
$name = self::resolve($type->getName(), $reflection);
|
||||
return new self($type->allowsNull() && $type->getName() !== 'mixed' ? [$name, 'null'] : [$name]);
|
||||
|
||||
private static function fromReflectionType(\ReflectionType $type, $of, bool $asObject)
|
||||
{
|
||||
if ($type instanceof \ReflectionNamedType) {
|
||||
$name = self::resolve($type->getName(), $of);
|
||||
return $asObject
|
||||
? new self($type->allowsNull() && $name !== 'mixed' ? [$name, 'null'] : [$name])
|
||||
: $name;
|
||||
|
||||
} elseif ($type instanceof \ReflectionUnionType || $type instanceof \ReflectionIntersectionType) {
|
||||
return new self(
|
||||
array_map(
|
||||
function ($t) use ($reflection) { return self::resolve($t->getName(), $reflection); },
|
||||
function ($t) use ($of) { return self::fromReflectionType($t, $of, false); },
|
||||
$type->getTypes()
|
||||
),
|
||||
$type instanceof \ReflectionUnionType ? '|' : '&'
|
||||
);
|
||||
|
||||
} else {
|
||||
throw new Nette\InvalidStateException('Unexpected type of ' . Reflection::toString($reflection));
|
||||
throw new Nette\InvalidStateException('Unexpected type of ' . Reflection::toString($of));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,37 +76,39 @@ final class Type
|
||||
*/
|
||||
public static function fromString(string $type): self
|
||||
{
|
||||
if (!preg_match('#(?:
|
||||
\?([\w\\\\]+)|
|
||||
[\w\\\\]+ (?: (&[\w\\\\]+)* | (\|[\w\\\\]+)* )
|
||||
)()$#xAD', $type, $m)) {
|
||||
if (!Validators::isTypeDeclaration($type)) {
|
||||
throw new Nette\InvalidArgumentException("Invalid type '$type'.");
|
||||
}
|
||||
|
||||
[, $nType, $iType] = $m;
|
||||
if ($nType) {
|
||||
return new self([$nType, 'null']);
|
||||
} elseif ($iType) {
|
||||
return new self(explode('&', $type), '&');
|
||||
} else {
|
||||
return new self(explode('|', $type));
|
||||
if ($type[0] === '?') {
|
||||
return new self([substr($type, 1), 'null']);
|
||||
}
|
||||
|
||||
$unions = [];
|
||||
foreach (explode('|', $type) as $part) {
|
||||
$part = explode('&', trim($part, '()'));
|
||||
$unions[] = count($part) === 1 ? $part[0] : new self($part, '&');
|
||||
}
|
||||
|
||||
return count($unions) === 1 && $unions[0] instanceof self
|
||||
? $unions[0]
|
||||
: new self($unions);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Resolves 'self', 'static' and 'parent' to the actual class name.
|
||||
* @param \ReflectionFunctionAbstract|\ReflectionParameter|\ReflectionProperty $reflection
|
||||
* @param \ReflectionFunctionAbstract|\ReflectionParameter|\ReflectionProperty $of
|
||||
*/
|
||||
public static function resolve(string $type, $reflection): string
|
||||
public static function resolve(string $type, $of): string
|
||||
{
|
||||
$lower = strtolower($type);
|
||||
if ($reflection instanceof \ReflectionFunction) {
|
||||
if ($of instanceof \ReflectionFunction) {
|
||||
return $type;
|
||||
} elseif ($lower === 'self' || $lower === 'static') {
|
||||
return $reflection->getDeclaringClass()->name;
|
||||
} elseif ($lower === 'parent' && $reflection->getDeclaringClass()->getParentClass()) {
|
||||
return $reflection->getDeclaringClass()->getParentClass()->name;
|
||||
return $of->getDeclaringClass()->name;
|
||||
} elseif ($lower === 'parent' && $of->getDeclaringClass()->getParentClass()) {
|
||||
return $of->getDeclaringClass()->getParentClass()->name;
|
||||
} else {
|
||||
return $type;
|
||||
}
|
||||
@@ -110,31 +117,42 @@ final class Type
|
||||
|
||||
private function __construct(array $types, string $kind = '|')
|
||||
{
|
||||
if ($types[0] === 'null') { // null as last
|
||||
array_push($types, array_shift($types));
|
||||
$o = array_search('null', $types, true);
|
||||
if ($o !== false) { // null as last
|
||||
array_splice($types, $o, 1);
|
||||
$types[] = 'null';
|
||||
}
|
||||
|
||||
$this->types = $types;
|
||||
$this->single = ($types[1] ?? 'null') === 'null';
|
||||
$this->simple = is_string($types[0]) && ($types[1] ?? 'null') === 'null';
|
||||
$this->kind = count($types) > 1 ? $kind : '';
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->single
|
||||
? (count($this->types) > 1 ? '?' : '') . $this->types[0]
|
||||
: implode($this->kind, $this->types);
|
||||
$multi = count($this->types) > 1;
|
||||
if ($this->simple) {
|
||||
return ($multi ? '?' : '') . $this->types[0];
|
||||
}
|
||||
|
||||
$res = [];
|
||||
foreach ($this->types as $type) {
|
||||
$res[] = $type instanceof self && $multi ? "($type)" : $type;
|
||||
}
|
||||
return implode($this->kind, $res);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the array of subtypes that make up the compound type as strings.
|
||||
* @return string[]
|
||||
* @return array<int, string|string[]>
|
||||
*/
|
||||
public function getNames(): array
|
||||
{
|
||||
return $this->types;
|
||||
return array_map(function ($t) {
|
||||
return $t instanceof self ? $t->getNames() : $t;
|
||||
}, $this->types);
|
||||
}
|
||||
|
||||
|
||||
@@ -144,16 +162,18 @@ final class Type
|
||||
*/
|
||||
public function getTypes(): array
|
||||
{
|
||||
return array_map(function ($name) { return self::fromString($name); }, $this->types);
|
||||
return array_map(function ($t) {
|
||||
return $t instanceof self ? $t : new self([$t]);
|
||||
}, $this->types);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the type name for single types, otherwise null.
|
||||
* Returns the type name for simple types, otherwise null.
|
||||
*/
|
||||
public function getSingleName(): ?string
|
||||
{
|
||||
return $this->single
|
||||
return $this->simple
|
||||
? $this->types[0]
|
||||
: null;
|
||||
}
|
||||
@@ -178,29 +198,36 @@ final class Type
|
||||
|
||||
|
||||
/**
|
||||
* Returns true whether it is a single type. Simple nullable types are also considered to be single types.
|
||||
* Returns true whether it is a simple type. Single nullable types are also considered to be simple types.
|
||||
*/
|
||||
public function isSimple(): bool
|
||||
{
|
||||
return $this->simple;
|
||||
}
|
||||
|
||||
|
||||
/** @deprecated use isSimple() */
|
||||
public function isSingle(): bool
|
||||
{
|
||||
return $this->single;
|
||||
return $this->simple;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true whether the type is both a single and a PHP built-in type.
|
||||
* Returns true whether the type is both a simple and a PHP built-in type.
|
||||
*/
|
||||
public function isBuiltin(): bool
|
||||
{
|
||||
return $this->single && Reflection::isBuiltinType($this->types[0]);
|
||||
return $this->simple && Validators::isBuiltinType($this->types[0]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true whether the type is both a single and a class name.
|
||||
* Returns true whether the type is both a simple and a class name.
|
||||
*/
|
||||
public function isClass(): bool
|
||||
{
|
||||
return $this->single && !Reflection::isBuiltinType($this->types[0]);
|
||||
return $this->simple && !Validators::isBuiltinType($this->types[0]);
|
||||
}
|
||||
|
||||
|
||||
@@ -209,43 +236,46 @@ final class Type
|
||||
*/
|
||||
public function isClassKeyword(): bool
|
||||
{
|
||||
return $this->single && Reflection::isClassKeyword($this->types[0]);
|
||||
return $this->simple && Validators::isClassKeyword($this->types[0]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verifies type compatibility. For example, it checks if a value of a certain type could be passed as a parameter.
|
||||
*/
|
||||
public function allows(string $type): bool
|
||||
public function allows(string $subtype): bool
|
||||
{
|
||||
if ($this->types === ['mixed']) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$type = self::fromString($type);
|
||||
$subtype = self::fromString($subtype);
|
||||
return $subtype->isUnion()
|
||||
? Arrays::every($subtype->types, function ($t) {
|
||||
return $this->allows2($t instanceof self ? $t->types : [$t]);
|
||||
})
|
||||
: $this->allows2($subtype->types);
|
||||
}
|
||||
|
||||
if ($this->isIntersection()) {
|
||||
if (!$type->isIntersection()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Arrays::every($this->types, function ($currentType) use ($type) {
|
||||
$builtin = Reflection::isBuiltinType($currentType);
|
||||
return Arrays::some($type->types, function ($testedType) use ($currentType, $builtin) {
|
||||
return $builtin
|
||||
? strcasecmp($currentType, $testedType) === 0
|
||||
: is_a($testedType, $currentType, true);
|
||||
});
|
||||
});
|
||||
}
|
||||
private function allows2(array $subtypes): bool
|
||||
{
|
||||
return $this->isUnion()
|
||||
? Arrays::some($this->types, function ($t) use ($subtypes) {
|
||||
return $this->allows3($t instanceof self ? $t->types : [$t], $subtypes);
|
||||
})
|
||||
: $this->allows3($this->types, $subtypes);
|
||||
}
|
||||
|
||||
$method = $type->isIntersection() ? 'some' : 'every';
|
||||
return Arrays::$method($type->types, function ($testedType) {
|
||||
$builtin = Reflection::isBuiltinType($testedType);
|
||||
return Arrays::some($this->types, function ($currentType) use ($testedType, $builtin) {
|
||||
|
||||
private function allows3(array $types, array $subtypes): bool
|
||||
{
|
||||
return Arrays::every($types, function ($type) use ($subtypes) {
|
||||
$builtin = Validators::isBuiltinType($type);
|
||||
return Arrays::some($subtypes, function ($subtype) use ($type, $builtin) {
|
||||
return $builtin
|
||||
? strcasecmp($currentType, $testedType) === 0
|
||||
: is_a($testedType, $currentType, true);
|
||||
? strcasecmp($type, $subtype) === 0
|
||||
: is_a($subtype, $type, true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
47
vendor/nette/utils/src/Utils/Validators.php
vendored
47
vendor/nette/utils/src/Utils/Validators.php
vendored
@@ -19,6 +19,12 @@ class Validators
|
||||
{
|
||||
use Nette\StaticClass;
|
||||
|
||||
private const BuiltinTypes = [
|
||||
'string' => 1, 'int' => 1, 'float' => 1, 'bool' => 1, 'array' => 1, 'object' => 1,
|
||||
'callable' => 1, 'iterable' => 1, 'void' => 1, 'null' => 1, 'mixed' => 1, 'false' => 1,
|
||||
'never' => 1, 'true' => 1,
|
||||
];
|
||||
|
||||
/** @var array<string,?callable> */
|
||||
protected static $validators = [
|
||||
// PHP types
|
||||
@@ -118,7 +124,8 @@ class Validators
|
||||
$key,
|
||||
?string $expected = null,
|
||||
string $label = "item '%' in array"
|
||||
): void {
|
||||
): void
|
||||
{
|
||||
if (!array_key_exists($key, $array)) {
|
||||
throw new AssertionException('Missing ' . str_replace('%', $key, $label) . '.');
|
||||
|
||||
@@ -327,7 +334,7 @@ class Validators
|
||||
[$alpha]([-0-9$alpha]{0,17}[$alpha])? # top domain
|
||||
$)Dix
|
||||
XX
|
||||
, $value);
|
||||
, $value);
|
||||
}
|
||||
|
||||
|
||||
@@ -351,7 +358,7 @@ XX
|
||||
(\\#\\S*)? # fragment
|
||||
$)Dix
|
||||
XX
|
||||
, $value);
|
||||
, $value);
|
||||
}
|
||||
|
||||
|
||||
@@ -380,4 +387,38 @@ XX
|
||||
{
|
||||
return preg_match('#^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$#D', $value) === 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determines if type is PHP built-in type. Otherwise, it is the class name.
|
||||
*/
|
||||
public static function isBuiltinType(string $type): bool
|
||||
{
|
||||
return isset(self::BuiltinTypes[strtolower($type)]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determines if type is special class name self/parent/static.
|
||||
*/
|
||||
public static function isClassKeyword(string $name): bool
|
||||
{
|
||||
return (bool) preg_match('#^(self|parent|static)$#Di', $name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether the given type declaration is syntactically valid.
|
||||
*/
|
||||
public static function isTypeDeclaration(string $type): bool
|
||||
{
|
||||
return (bool) preg_match(<<<'XX'
|
||||
~(
|
||||
\?? (?<type> \\? (?<name> [a-zA-Z_\x7f-\xff][\w\x7f-\xff]*) (\\ (?&name))* ) |
|
||||
(?<intersection> (?&type) (& (?&type))+ ) |
|
||||
(?<upart> (?&type) | \( (?&intersection) \) ) (\| (?&upart))+
|
||||
)$~xAD
|
||||
XX
|
||||
, $type);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user