D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
opt
/
psa
/
admin
/
plib
/
vendor
/
laminas
/
laminas-validator
/
src
/
Filename :
IsJsonString.php
back
Copy
<?php declare(strict_types=1); namespace Laminas\Validator; use JsonException; use function gettype; use function is_float; use function is_int; use function is_numeric; use function is_string; use function json_decode; use function str_starts_with; use const JSON_ERROR_DEPTH; use const JSON_THROW_ON_ERROR; /** * @psalm-type CustomOptions = array{ * allow: int-mask-of<self::ALLOW_*>, * maxDepth: positive-int, * } * @psalm-import-type AbstractOptions from AbstractValidator * @psalm-type Options = AbstractOptions|CustomOptions */ final class IsJsonString extends AbstractValidator { public const ERROR_NOT_STRING = 'errorNotString'; public const ERROR_TYPE_NOT_ALLOWED = 'errorTypeNotAllowed'; public const ERROR_MAX_DEPTH_EXCEEDED = 'errorMaxDepthExceeded'; public const ERROR_INVALID_JSON = 'errorInvalidJson'; public const ALLOW_INT = 0b0000001; public const ALLOW_FLOAT = 0b0000010; public const ALLOW_BOOL = 0b0000100; public const ALLOW_ARRAY = 0b0001000; public const ALLOW_OBJECT = 0b0010000; public const ALLOW_ALL = 0b0011111; /** @var array<self::ERROR_*, non-empty-string> */ protected $messageTemplates = [ self::ERROR_NOT_STRING => 'Expected a string but %type% was received', self::ERROR_TYPE_NOT_ALLOWED => 'Received a JSON %type% but this type is not acceptable', self::ERROR_MAX_DEPTH_EXCEEDED => 'The decoded JSON payload exceeds the allowed depth of %maxDepth%', self::ERROR_INVALID_JSON => 'An invalid JSON payload was received', ]; /** @var array<string, string> */ protected $messageVariables = [ 'type' => 'type', 'maxDepth' => 'maxDepth', ]; protected ?string $type = null; /** @var int-mask-of<self::ALLOW_*> */ protected int $allow = self::ALLOW_ALL; /** @var positive-int */ protected int $maxDepth = 512; /** * @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0 * * @param int-mask-of<self::ALLOW_*> $type */ public function setAllow(int $type): void { $this->allow = $type; } /** * @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0 * * @param positive-int $maxDepth */ public function setMaxDepth(int $maxDepth): void { $this->maxDepth = $maxDepth; } public function isValid(mixed $value): bool { if (! is_string($value)) { $this->error(self::ERROR_NOT_STRING); $this->type = gettype($value); return false; } if (is_numeric($value)) { /** @psalm-var mixed $value */ $value = json_decode($value); if (is_int($value) && ! $this->isAllowed(self::ALLOW_INT)) { $this->error(self::ERROR_TYPE_NOT_ALLOWED); $this->type = 'int'; return false; } if (is_float($value) && ! $this->isAllowed(self::ALLOW_FLOAT)) { $this->error(self::ERROR_TYPE_NOT_ALLOWED); $this->type = 'float'; return false; } return true; } if ($value === 'true' || $value === 'false') { if (! $this->isAllowed(self::ALLOW_BOOL)) { $this->error(self::ERROR_TYPE_NOT_ALLOWED); $this->type = 'boolean'; return false; } return true; } if (str_starts_with($value, '[') && ! $this->isAllowed(self::ALLOW_ARRAY)) { $this->error(self::ERROR_TYPE_NOT_ALLOWED); $this->type = 'array'; return false; } if (str_starts_with($value, '{') && ! $this->isAllowed(self::ALLOW_OBJECT)) { $this->error(self::ERROR_TYPE_NOT_ALLOWED); $this->type = 'object'; return false; } try { /** @psalm-suppress UnusedFunctionCall */ json_decode($value, true, $this->maxDepth, JSON_THROW_ON_ERROR); return true; } catch (JsonException $e) { if ($e->getCode() === JSON_ERROR_DEPTH) { $this->error(self::ERROR_MAX_DEPTH_EXCEEDED); return false; } $this->error(self::ERROR_INVALID_JSON); return false; } } /** @param self::ALLOW_* $flag */ private function isAllowed(int $flag): bool { return ($this->allow & $flag) === $flag; } }