You are here

public function IbanValidator::validate in Plug 7

Checks if the passed value is valid.

@api

Parameters

mixed $value The value that should be validated:

Constraint $constraint The constraint for the validation:

Overrides ConstraintValidatorInterface::validate

File

lib/Symfony/validator/Symfony/Component/Validator/Constraints/IbanValidator.php, line 30

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
  $canonicalized = str_replace(' ', '', $value);

  // The IBAN must have at least 4 characters...
  if (strlen($canonicalized) < 4) {
    $this
      ->buildViolation($constraint->message)
      ->setParameter('{{ value }}', $this
      ->formatValue($value))
      ->setCode(Iban::TOO_SHORT_ERROR)
      ->addViolation();
    return;
  }

  // ...start with a country code...
  if (!ctype_alpha($canonicalized[0]) || !ctype_alpha($canonicalized[1])) {
    $this
      ->buildViolation($constraint->message)
      ->setParameter('{{ value }}', $this
      ->formatValue($value))
      ->setCode(Iban::INVALID_COUNTRY_CODE_ERROR)
      ->addViolation();
    return;
  }

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

  // ...and contain uppercase characters only
  if ($canonicalized !== strtoupper($canonicalized)) {
    $this
      ->buildViolation($constraint->message)
      ->setParameter('{{ value }}', $this
      ->formatValue($value))
      ->setCode(Iban::INVALID_CASE_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 = $this
    ->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 !== $this
    ->bigModulo97($checkSum)) {
    $this
      ->buildViolation($constraint->message)
      ->setParameter('{{ value }}', $this
      ->formatValue($value))
      ->setCode(Iban::CHECKSUM_FAILED_ERROR)
      ->addViolation();
  }
}