validation-bugsnag-email
This commit is contained in:
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