Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. FileValidator.php

function FileValidator::validate

Same name in this branch
  1. 11.1.x core/modules/file/src/Validation/FileValidator.php \Drupal\file\Validation\FileValidator::validate()

Overrides ConstraintValidatorInterface::validate

2 calls to FileValidator::validate()
ImageValidator::validate in vendor/symfony/validator/Constraints/ImageValidator.php
Checks if the passed value is valid.
ImageValidator::validate in vendor/symfony/validator/Constraints/ImageValidator.php
Checks if the passed value is valid.
1 method overrides FileValidator::validate()
ImageValidator::validate in vendor/symfony/validator/Constraints/ImageValidator.php
Checks if the passed value is valid.

File

vendor/symfony/validator/Constraints/FileValidator.php, line 41

Class

FileValidator
@author Bernhard Schussek <bschussek@gmail.com>

Namespace

Symfony\Component\Validator\Constraints

Code

public function validate(mixed $value, Constraint $constraint) : void {
    if (!$constraint instanceof File) {
        throw new UnexpectedTypeException($constraint, File::class);
    }
    if (null === $value || '' === $value) {
        return;
    }
    if ($value instanceof UploadedFile && !$value->isValid()) {
        switch ($value->getError()) {
            case \UPLOAD_ERR_INI_SIZE:
                $iniLimitSize = UploadedFile::getMaxFilesize();
                if ($constraint->maxSize && $constraint->maxSize < $iniLimitSize) {
                    $limitInBytes = $constraint->maxSize;
                    $binaryFormat = $constraint->binaryFormat;
                }
                else {
                    $limitInBytes = $iniLimitSize;
                    $binaryFormat = $constraint->binaryFormat ?? true;
                }
                [
                    ,
                    $limitAsString,
                    $suffix,
                ] = $this->factorizeSizes(0, $limitInBytes, $binaryFormat);
                $this->context
                    ->buildViolation($constraint->uploadIniSizeErrorMessage)
                    ->setParameter('{{ limit }}', $limitAsString)
                    ->setParameter('{{ suffix }}', $suffix)
                    ->setCode((string) \UPLOAD_ERR_INI_SIZE)
                    ->addViolation();
                return;
            case \UPLOAD_ERR_FORM_SIZE:
                $this->context
                    ->buildViolation($constraint->uploadFormSizeErrorMessage)
                    ->setCode((string) \UPLOAD_ERR_FORM_SIZE)
                    ->addViolation();
                return;
            case \UPLOAD_ERR_PARTIAL:
                $this->context
                    ->buildViolation($constraint->uploadPartialErrorMessage)
                    ->setCode((string) \UPLOAD_ERR_PARTIAL)
                    ->addViolation();
                return;
            case \UPLOAD_ERR_NO_FILE:
                $this->context
                    ->buildViolation($constraint->uploadNoFileErrorMessage)
                    ->setCode((string) \UPLOAD_ERR_NO_FILE)
                    ->addViolation();
                return;
            case \UPLOAD_ERR_NO_TMP_DIR:
                $this->context
                    ->buildViolation($constraint->uploadNoTmpDirErrorMessage)
                    ->setCode((string) \UPLOAD_ERR_NO_TMP_DIR)
                    ->addViolation();
                return;
            case \UPLOAD_ERR_CANT_WRITE:
                $this->context
                    ->buildViolation($constraint->uploadCantWriteErrorMessage)
                    ->setCode((string) \UPLOAD_ERR_CANT_WRITE)
                    ->addViolation();
                return;
            case \UPLOAD_ERR_EXTENSION:
                $this->context
                    ->buildViolation($constraint->uploadExtensionErrorMessage)
                    ->setCode((string) \UPLOAD_ERR_EXTENSION)
                    ->addViolation();
                return;
            default:
                $this->context
                    ->buildViolation($constraint->uploadErrorMessage)
                    ->setCode((string) $value->getError())
                    ->addViolation();
                return;
        }
    }
    if (!\is_scalar($value) && !$value instanceof FileObject && !$value instanceof \Stringable) {
        throw new UnexpectedValueException($value, 'string');
    }
    $path = $value instanceof FileObject ? $value->getPathname() : (string) $value;
    if (!is_file($path)) {
        $this->context
            ->buildViolation($constraint->notFoundMessage)
            ->setParameter('{{ file }}', $this->formatValue($path))
            ->setCode(File::NOT_FOUND_ERROR)
            ->addViolation();
        return;
    }
    if (!is_readable($path)) {
        $this->context
            ->buildViolation($constraint->notReadableMessage)
            ->setParameter('{{ file }}', $this->formatValue($path))
            ->setCode(File::NOT_READABLE_ERROR)
            ->addViolation();
        return;
    }
    $sizeInBytes = filesize($path);
    $basename = $value instanceof UploadedFile ? $value->getClientOriginalName() : basename($path);
    if ($constraint->filenameMaxLength && $constraint->filenameMaxLength < ($filenameLength = \strlen($basename))) {
        $this->context
            ->buildViolation($constraint->filenameTooLongMessage)
            ->setParameter('{{ filename_max_length }}', $this->formatValue($constraint->filenameMaxLength))
            ->setCode(File::FILENAME_TOO_LONG)
            ->setPlural($constraint->filenameMaxLength)
            ->addViolation();
        return;
    }
    if (0 === $sizeInBytes) {
        $this->context
            ->buildViolation($constraint->disallowEmptyMessage)
            ->setParameter('{{ file }}', $this->formatValue($path))
            ->setParameter('{{ name }}', $this->formatValue($basename))
            ->setCode(File::EMPTY_ERROR)
            ->addViolation();
        return;
    }
    if ($constraint->maxSize) {
        $limitInBytes = $constraint->maxSize;
        if ($sizeInBytes > $limitInBytes) {
            [
                $sizeAsString,
                $limitAsString,
                $suffix,
            ] = $this->factorizeSizes($sizeInBytes, $limitInBytes, $constraint->binaryFormat);
            $this->context
                ->buildViolation($constraint->maxSizeMessage)
                ->setParameter('{{ file }}', $this->formatValue($path))
                ->setParameter('{{ size }}', $sizeAsString)
                ->setParameter('{{ limit }}', $limitAsString)
                ->setParameter('{{ suffix }}', $suffix)
                ->setParameter('{{ name }}', $this->formatValue($basename))
                ->setCode(File::TOO_LARGE_ERROR)
                ->addViolation();
            return;
        }
    }
    $mimeTypes = (array) $constraint->mimeTypes;
    if ($constraint->extensions) {
        $fileExtension = strtolower(pathinfo($basename, \PATHINFO_EXTENSION));
        $found = false;
        $normalizedExtensions = [];
        foreach ((array) $constraint->extensions as $k => $v) {
            if (!\is_string($k)) {
                $k = $v;
                $v = null;
            }
            $normalizedExtensions[] = $k;
            if ($fileExtension !== $k) {
                continue;
            }
            $found = true;
            if (null === $v) {
                if (!class_exists(MimeTypes::class)) {
                    throw new LogicException('You cannot validate the mime-type of files as the Mime component is not installed. Try running "composer require symfony/mime".');
                }
                $mimeTypesHelper = MimeTypes::getDefault();
                $v = $mimeTypesHelper->getMimeTypes($k);
            }
            $mimeTypes = $mimeTypes ? array_intersect($v, $mimeTypes) : (array) $v;
            break;
        }
        if (!$found) {
            $this->context
                ->buildViolation($constraint->extensionsMessage)
                ->setParameter('{{ file }}', $this->formatValue($path))
                ->setParameter('{{ extension }}', $this->formatValue($fileExtension))
                ->setParameter('{{ extensions }}', $this->formatValues($normalizedExtensions))
                ->setParameter('{{ name }}', $this->formatValue($basename))
                ->setCode(File::INVALID_EXTENSION_ERROR)
                ->addViolation();
        }
    }
    if ($mimeTypes) {
        if ($value instanceof FileObject) {
            $mime = $value->getMimeType();
        }
        elseif (isset($mimeTypesHelper) || class_exists(MimeTypes::class)) {
            $mime = ($mimeTypesHelper ?? MimeTypes::getDefault())->guessMimeType($path);
        }
        elseif (!class_exists(FileObject::class)) {
            throw new LogicException('You cannot validate the mime-type of files as the Mime component is not installed. Try running "composer require symfony/mime".');
        }
        else {
            $mime = (new FileObject($value))->getMimeType();
        }
        foreach ($mimeTypes as $mimeType) {
            if ($mimeType === $mime) {
                return;
            }
            if ($discrete = strstr($mimeType, '/*', true)) {
                if (strstr($mime, '/', true) === $discrete) {
                    return;
                }
            }
        }
        $this->context
            ->buildViolation($constraint->mimeTypesMessage)
            ->setParameter('{{ file }}', $this->formatValue($path))
            ->setParameter('{{ type }}', $this->formatValue($mime))
            ->setParameter('{{ types }}', $this->formatValues($mimeTypes))
            ->setParameter('{{ name }}', $this->formatValue($basename))
            ->setCode(File::INVALID_MIME_TYPE_ERROR)
            ->addViolation();
    }
}

API Navigation

  • Drupal Core 11.1.x
  • Topics
  • Classes
  • Functions
  • Constants
  • Globals
  • Files
  • Namespaces
  • Deprecated
  • Services
RSS feed
Powered by Drupal