我想,可能是创建另一个提供程序并指定某些验证过程的情况。我将尝试通过png
图像提供者(Symfony 4 兼容)解释我的愿景。
首先,创建提供者。它只是盒子中一些现有提供者的扩展(ImageProvider
在这种情况下):
namespace App\Provider;
use Sonata\MediaBundle\Provider\ImageProvider;
class PngProvider extends ImageProvider
{
}
二、在services.yaml中定义DI配置:
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"}]]
如您所见,最后两个参数定义了要上传的文件的文件扩展名和 mime 类型。
然后,为您的实体文件添加属性:
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;
请注意@Assert\Valid
媒体属性的限制,否则媒体文件在上传过程中会跳过验证。
现在您可以将您的提供程序与一些奏鸣曲媒体上下文一起使用:
sonata_media:
contexts:
some_context:
providers:
- sonata.media.provider.png
formats: ~
例如,在表单类型中使用它:
use Sonata\MediaBundle\Form\Type\MediaType;
...
$builder->add('pngFileProperty', MediaType::class, [
'context' => 'some_context',
'provider' => 'sonata.media.provider.png',
])
PngProvider::validate()
您可以通过覆盖您的自定义提供程序的方法来提供一些额外的验证条件(最大文件大小或类似的东西) :
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();
}
}
}