Skip to content

Instantly share code, notes, and snippets.

@ismail1432
Last active December 25, 2022 20:02
Show Gist options
  • Save ismail1432/fb2439302b0c117d3bad55ab2cfceb2e to your computer and use it in GitHub Desktop.
Save ismail1432/fb2439302b0c117d3bad55ab2cfceb2e to your computer and use it in GitHub Desktop.
// AppFileValidator.php
<?php
declare(strict_types=1);
namespace App\Constraints;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Mime\MimeTypesInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Constraints\FileValidator as OriginalFileValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
class AppFileValidator extends OriginalFileValidator
{
private MimeTypesInterface $mimeTypes;
public function __construct(MimeTypesInterface $mimeTypes)
{
$this->mimeTypes = $mimeTypes;
}
public function validate($value, Constraint $constraint)
{
if (!$constraint instanceof AppFile) {
throw new UnexpectedTypeException($constraint, AppFile::class);
}
if (null === $value || '' === $value) {
return;
}
$path = $value instanceof File ? $value->getPathname() : (string)$value;
$basename = $value instanceof UploadedFile ? $value->getClientOriginalName() : basename($path);
// Here we guess the MIME type with our guesser instead of the default in FileValidator
$mime = $this->mimeTypes->guessMimeType($path);
$mimeTypes = (array) $constraint->mimeTypes;
foreach ($mimeTypes as $mimeType) {
// ⚠️ If the MIME type is allowed, we set the mimeTypes options to null
// in order to avoid a new check with in the FileValidator.
if ($mimeType === $mime) {
// reset the mimeTypes constraint
$constraint->mimeTypes = null;
// call the FileValidator::validate to validate other constraint
parent::validate($value, $constraint);
return;
}
}
// Build violations
$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(AppFile::INVALID_MIME_TYPE_ERROR)
->addViolation();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment