You are here

public function IbanValidator::validate in Zircon Profile 8

Same name and namespace in other branches
  1. 8.0 vendor/symfony/validator/Constraints/IbanValidator.php \Symfony\Component\Validator\Constraints\IbanValidator::validate()

Checks if the passed value is valid.

Parameters

mixed $value The value that should be validated:

Constraint $constraint The constraint for the validation:

Overrides ConstraintValidatorInterface::validate

File

vendor/symfony/validator/Constraints/IbanValidator.php, line 143

Class

IbanValidator
@author Manuel Reinhard <manu@sprain.ch> @author Michael Schummel @author Bernhard Schussek <bschussek@gmail.com>

Namespace

Symfony\Component\Validator\Constraints

Code

public function validate($value, Constraint $constraint) {
  if (!$constraint instanceof Iban) {
    throw new UnexpectedTypeException($constraint, __NAMESPACE__ . '\\Iban');
  }
  if (null === $value || '' === $value) {
    return;
  }
  if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
    throw new UnexpectedTypeException($value, 'string');
  }
  $value = (string) $value;

  // Remove spaces and convert to uppercase
  $canonicalized = str_replace(' ', '', strtoupper($value));

  // The IBAN must contain only digits and characters...
  if (!ctype_alnum($canonicalized)) {
    if ($this->context instanceof ExecutionContextInterface) {
      $this->context
        ->buildViolation($constraint->message)
        ->setParameter('{{ value }}', $this
        ->formatValue($value))
        ->setCode(Iban::INVALID_CHARACTERS_ERROR)
        ->addViolation();
    }
    else {
      $this
        ->buildViolation($constraint->message)
        ->setParameter('{{ value }}', $this
        ->formatValue($value))
        ->setCode(Iban::INVALID_CHARACTERS_ERROR)
        ->addViolation();
    }
    return;
  }

  // ...start with a two-letter country code
  $countryCode = substr($canonicalized, 0, 2);
  if (!ctype_alpha($countryCode)) {
    if ($this->context instanceof ExecutionContextInterface) {
      $this->context
        ->buildViolation($constraint->message)
        ->setParameter('{{ value }}', $this
        ->formatValue($value))
        ->setCode(Iban::INVALID_COUNTRY_CODE_ERROR)
        ->addViolation();
    }
    else {
      $this
        ->buildViolation($constraint->message)
        ->setParameter('{{ value }}', $this
        ->formatValue($value))
        ->setCode(Iban::INVALID_COUNTRY_CODE_ERROR)
        ->addViolation();
    }
    return;
  }

  // ...have a format available
  if (!array_key_exists($countryCode, self::$formats)) {
    if ($this->context instanceof ExecutionContextInterface) {
      $this->context
        ->buildViolation($constraint->message)
        ->setParameter('{{ value }}', $this
        ->formatValue($value))
        ->setCode(Iban::NOT_SUPPORTED_COUNTRY_CODE_ERROR)
        ->addViolation();
    }
    else {
      $this
        ->buildViolation($constraint->message)
        ->setParameter('{{ value }}', $this
        ->formatValue($value))
        ->setCode(Iban::NOT_SUPPORTED_COUNTRY_CODE_ERROR)
        ->addViolation();
    }
    return;
  }

  // ...and have a valid format
  if (!preg_match('/^' . self::$formats[$countryCode] . '$/', $canonicalized)) {
    if ($this->context instanceof ExecutionContextInterface) {
      $this->context
        ->buildViolation($constraint->message)
        ->setParameter('{{ value }}', $this
        ->formatValue($value))
        ->setCode(Iban::INVALID_FORMAT_ERROR)
        ->addViolation();
    }
    else {
      $this
        ->buildViolation($constraint->message)
        ->setParameter('{{ value }}', $this
        ->formatValue($value))
        ->setCode(Iban::INVALID_FORMAT_ERROR)
        ->addViolation();
    }
    return;
  }

  // Move the first four characters to the end
  // e.g. CH93 0076 2011 6238 5295 7
  //   -> 0076 2011 6238 5295 7 CH93
  $canonicalized = substr($canonicalized, 4) . substr($canonicalized, 0, 4);

  // Convert all remaining letters to their ordinals
  // The result is an integer, which is too large for PHP's int
  // data type, so we store it in a string instead.
  // e.g. 0076 2011 6238 5295 7 CH93
  //   -> 0076 2011 6238 5295 7 121893
  $checkSum = self::toBigInt($canonicalized);

  // Do a modulo-97 operation on the large integer
  // We cannot use PHP's modulo operator, so we calculate the
  // modulo step-wisely instead
  if (1 !== self::bigModulo97($checkSum)) {
    if ($this->context instanceof ExecutionContextInterface) {
      $this->context
        ->buildViolation($constraint->message)
        ->setParameter('{{ value }}', $this
        ->formatValue($value))
        ->setCode(Iban::CHECKSUM_FAILED_ERROR)
        ->addViolation();
    }
    else {
      $this
        ->buildViolation($constraint->message)
        ->setParameter('{{ value }}', $this
        ->formatValue($value))
        ->setCode(Iban::CHECKSUM_FAILED_ERROR)
        ->addViolation();
    }
  }
}