SonataMediaBundle: how to add svg file extension
I need to add .svg extension to my config.
At the moment in my project I have other extensions like (pdf, images)
I made the following changes
- Added new svg_file to context
- Added file provider (at the end of the config file)
- Added svg to allowed_extensions
- Added image / svg + xml to allowed_mime_types
Now I can upload the svg file, but the problem is that the user can upload other file extensions like pdf, etc.
How can this be avoided? Or find the correct way to validate the form?
Sonata Documentation:
helped me but not for form validation.
What am I missing?
I changed the following files:
#app/config/sonata_config.yml
sonata_media:
default_context: images_file
db_driver: doctrine_orm # or doctrine_mongodb, doctrine_phpcr
contexts:
pdf_file:
providers:
- sonata.media.provider.file
formats: ~
images_file:
providers:
- sonata.media.provider.image
formats:
1x: { width: 870 , height: 412 , quality: 80 }
2x: { width: 1740 , height: 824 , quality: 50 }
svg_file:
providers:
- sonata.media.provider.file
formats: ~
cdn:
server:
path: /uploads/media # http://media.sonata-project.org/
filesystem:
local:
directory: %kernel.root_dir%/../web/uploads/media
create: false
providers:
file:
service: sonata.media.provider.file
resizer: false
filesystem: sonata.media.filesystem.local
cdn: sonata.media.cdn.server
generator: sonata.media.generator.default
thumbnail: sonata.media.thumbnail.format
allowed_extensions: ['pdf', 'txt', 'rtf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pttx', 'odt', 'odg', 'odp', 'ods', 'odc', 'odf', 'odb', 'csv', 'xml','svg']
allowed_mime_types: ['application/pdf', 'application/x-pdf', 'application/rtf', 'text/html', 'text/rtf', 'text/plain', 'image/svg+xml']
Form file:
use Sonata\AdminBundle\Admin\Admin;
class CustomAdmin extends Admin
{
/**
* @param FormMapper $formMapper
*/
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add(
'NormalLogo',
'sonata_type_model_list',
array('required' => false),
array(
'link_parameters' => array('context' => 'images_file', 'provider' => 'sonata.media.provider.image'),
)
)
->add(
'SvgLogo',
'sonata_type_model_list',
array('required' => false),
array(
'link_parameters' => array('context' => 'svg_file', 'provider' => 'sonata.media.provider.file'),
)
)
->add('overriddenBy', 'sonata_type_model',
array(
'empty_value' => 'Not overridden',
'btn_add' => false,
'btn_list' => false,
'btn_delete' => false,
'btn_catalogue' => false,
)
);
}
}
source to share
You can create your own provider for SVG files just for this, you need to define the service for the SVG provider first.
parameters:
application_sonata_media.svg_class: Application\Sonata\MediaBundle\Provider\SVGProvider
services:
sonata.media.provider.svg:
class: %application_sonata_media.svg_class%
tags:
- { name: sonata.media.provider }
arguments:
- sonata.media.provider.svg
- @sonata.media.filesystem.local
- @sonata.media.cdn.server
- @sonata.media.generator.default
- @sonata.media.thumbnail.format
- allowed_extensions: ['svg']
- allowed_mime_types: ['image/svg+xml']
Using sonata you can generate extended packages EASYEXTENDS BUNDLE
by default it creates extended package in src/Application/Sonata/MediaBundle
, but you can specify other destination as So, create above service in extended media package services.yml
and import in main config.yml
. If you want to add more mime types or extensions you can define in the service aboveallowed_mime_types: ['image/svg+xml','application/pdf']
imports:
- { resource: @ApplicationSonataMediaBundle/Resources/config/services.yml }
Now create your provider class in the extended media package as SVGProvider
and extend your provider class with sonata carrierFileProvider
<?php
namespace Application\Sonata\MediaBundle\Provider;
use Sonata\MediaBundle\Provider\FileProvider as BaseFileProvider;
use Gaufrette\Filesystem;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Validator\ErrorElement;
use Sonata\MediaBundle\CDN\CDNInterface;
use Sonata\MediaBundle\Generator\GeneratorInterface;
use Sonata\MediaBundle\Metadata\MetadataBuilderInterface;
use Sonata\MediaBundle\Model\MediaInterface;
use Sonata\MediaBundle\Thumbnail\ThumbnailInterface;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\NotNull;
class SVGProvider extends BaseFileProvider {
protected $allowedMimeTypes;
protected $allowedExtensions;
protected $metadata;
public function __construct( $name, Filesystem $filesystem, CDNInterface $cdn, GeneratorInterface $pathGenerator, ThumbnailInterface $thumbnail, array $allowedExtensions = array(), array $allowedMimeTypes = array(), MetadataBuilderInterface $metadata = null ) {
parent::__construct( $name, $filesystem, $cdn, $pathGenerator, $thumbnail );
$this->allowedExtensions = $allowedExtensions;
$this->allowedMimeTypes = $allowedMimeTypes;
$this->metadata = $metadata;
}
public function buildCreateForm( FormMapper $formMapper ) {
$formMapper->add( 'binaryContent', 'file', array(
'label' => 'Upload SVG file only',
'constraints' => array(
new NotBlank(),
new NotNull(),
),
) );
}
/**
* {@inheritdoc}
*/
public function validate( ErrorElement $errorElement, MediaInterface $media ) {
if ( ! $media->getBinaryContent() instanceof \SplFileInfo ) {
return;
}
if ( $media->getBinaryContent() instanceof UploadedFile ) {
$fileName = $media->getBinaryContent()->getClientOriginalName();
} elseif ( $media->getBinaryContent() instanceof File ) {
$fileName = $media->getBinaryContent()->getFilename();
} else {
throw new \RuntimeException( sprintf( 'Invalid binary content type: %s', get_class( $media->getBinaryContent() ) ) );
}
if ( ! in_array( strtolower( pathinfo( $fileName, PATHINFO_EXTENSION ) ), $this->allowedExtensions ) ) {
$errorElement
->with( 'binaryContent' )
->addViolation( 'Invalid extensions' )
->end();
}
if ( ! in_array( $media->getBinaryContent()->getMimeType(), $this->allowedMimeTypes ) ) {
$errorElement
->with( 'binaryContent' )
->addViolation( 'Invalid mime type : ' . $media->getBinaryContent()->getMimeType() )
->end();
}
}
}
Here you can override the base class functions and define your own functionality as you want, for example want to add some checks on file input, you can set up a function validate()
to change attributes for the file input field, which you can define in the buildCreateForm()
method
Now in your admin, if you want to only allow SVG uploads, you can define your own provider that only allows SVG files
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add(
'SvgLogo',
'sonata_type_model_list',
array('required' => false),
array(
'link_parameters' => array('context' => 'svg_file', 'provider' => 'sonata.media.provider.svg'),
)
)
}
source to share