This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
symfony/src/Symfony/Component/Validator/Constraints/UuidValidator.php

108 lines
3.6 KiB
PHP
Raw Normal View History

2014-02-18 20:53:41 +00:00
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
/**
* Validates whether the value is a valid UUID per RFC 4122.
*
* @author Colin O'Dell <colinodell@gmail.com>
* @author Bernhard Schussek <bschussek@gmail.com>
2014-02-18 20:53:41 +00:00
*
* @see http://tools.ietf.org/html/rfc4122
* @see https://en.wikipedia.org/wiki/Universally_unique_identifier
*/
class UuidValidator extends ConstraintValidator
{
/**
* Regular expression which verifies allowed characters and the proper format.
*
* The strict pattern matches UUIDs like this: xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
* Roughly speaking: x = any hexadecimal character, M = any allowed version, N = any allowed variant.
*/
const STRICT_PATTERN = '/^[a-f0-9]{8}-[a-f0-9]{4}-[%s][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/i';
/**
* The loose pattern validates similar yet non-compliant UUIDs.
*
* Dashes are completely optional. If present, they should only appear between every fourth character.
* The value can also be wrapped with characters like []{} for backwards-compatibility with other systems.
* Neither the version nor the variant is validated by this pattern.
*/
const LOOSE_PATTERN = '/^[a-f0-9]{4}(?:-?[a-f0-9]{4}){7}$/i';
/**
* Properly-formatted UUIDs contain 32 hex digits, separated by 4 dashes.
* We can use this fact to avoid performing a preg_match on strings of other sizes.
*/
const STRICT_UUID_LENGTH = 36;
/**
* {@inheritdoc}
2014-02-18 20:53:41 +00:00
*/
public function validate($value, Constraint $constraint)
{
if (null === $value || '' === $value) {
return;
}
if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
throw new UnexpectedTypeException($value, 'string');
}
$value = (string) $value;
if ($constraint->strict) {
$length = strlen($value);
if ($length < static::STRICT_UUID_LENGTH) {
$this->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
->addViolation();
return;
}
if ($length > static::STRICT_UUID_LENGTH) {
$this->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
->addViolation();
return;
}
2014-02-18 20:53:41 +00:00
// Insert the allowed versions into the regular expression
$pattern = sprintf(static::STRICT_PATTERN, implode('', $constraint->versions));
if (!preg_match($pattern, $value)) {
$this->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
->addViolation();
2014-02-18 20:53:41 +00:00
}
return;
}
// Trim any wrapping characters like [] or {} used by some legacy systems
$value = trim($value, '[]{}');
if (!preg_match(static::LOOSE_PATTERN, $value)) {
$this->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
->addViolation();
2014-02-18 20:53:41 +00:00
}
}
}