I guess, it may be the case to create another provider and specify certain validation process. I'll try to explain my vision with png
images provider (Symfony 4 compatible).
First, create provider. It is just the extension of some existing provider from the box (ImageProvider
in the case):
namespace App\Provider;
use Sonata\MediaBundle\Provider\ImageProvider;
class PngProvider extends ImageProvider
{
}
Second, define DI configuration in services.yaml:
sonata.media.provider.png:
class: App\Provider\PngProvider
tags:
- { name: sonata.media.provider }
arguments:
- 'sonata.media.provider.png'
- '@sonata.media.filesystem.local'
- '@sonata.media.cdn.server'
- '@sonata.media.generator.default'
- '@sonata.media.thumbnail.format'
- ['png']
- ['image/png', 'image/x-png']
calls:
- [ setTemplates, [{"helper_view":"SonataMediaBundle:Provider:view_image.html.twig","helper_thumbnail":"SonataMediaBundle:Provider:thumbnail.html.twig"}]]
As you can see, two last arguments define file extensions and mime types for files to upload.
Then, add property for your entity file:
namespace App\Entity;
use App\Entity\Media; // or you Media class
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ORM\Mapping as ORM;
class SomeEntity
{
/**
* @var Media
* @Assert\Valid
* @ORM\ManyToOne(targetEntity="Media", cascade={"all"})
*/
private $pngFileProperty;
Please, pay attention to @Assert\Valid
constraint for the media property, or media file would skip validation during uploading.
Now you can use your provider with some sonata media contexts:
sonata_media:
contexts:
some_context:
providers:
- sonata.media.provider.png
formats: ~
And use it, for example, in form types:
use Sonata\MediaBundle\Form\Type\MediaType;
...
$builder->add('pngFileProperty', MediaType::class, [
'context' => 'some_context',
'provider' => 'sonata.media.provider.png',
])
You can provide some additional validation conditions (max file size or smth like this stuff) by overriding PngProvider::validate()
method for your custom provider:
namespace App\Provider;
use Sonata\CoreBundle\Validator\ErrorElement;
use Sonata\MediaBundle\Model\MediaInterface;
use Sonata\MediaBundle\Provider\ImageProvider;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class PngProvider extends ImageProvider
{
const VERY_BIG_FILE = 100000; // bytes
public function validate(ErrorElement $errorElement, MediaInterface $media)
{
parent::validate($errorElement, $media);
if ($media->getBinaryContent() instanceof UploadedFile) {
$size = $media->getBinaryContent()->getClientSize();
} elseif ($media->getBinaryContent() instanceof File) {
$size = $media->getBinaryContent()->getSize();
} else {
// parent would throw an Exception in this case so be happy, don't worry
}
if ($size > self::VERY_BIG_FILE) {
$errorElement
->with('binaryContent')
->addViolation('The file is too big, max size: '.self::VERY_BIG_FILE)
->end();
}
}
}