SonataMediaBundle: Как добавить расширение файла svg

Мне нужно добавить расширение файла .svg в мою конфигурацию.

На данный момент в моем проекте есть другие расширения как (pdf, изображения)

Я сделал следующие изменения

  1. В контекст добавлен новый файл svg_file.
  2. Добавлен поставщик файлов (в конце файла конфигурации)
  3. Добавлен svg в allowed_extensions.
  4. Добавлено изображение/svg+xml в allowed_mime_types.

Теперь я могу загрузить файл svg, но проблема в том, что пользователь может загружать другие расширения файлов, например pdf и т. д.

Как этого избежать? Или найти правильный способ проверки формы?

Документация Сонаты:

помог мне, но не для проверки формы.

Что мне не хватает?


Я изменил следующие файлы:

#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']

Файл формы:

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,
            )
        );
}
}

person Reyela    schedule 27.04.2015    source источник


Ответы (1)


Вы можете создать своего собственного провайдера для файлов SVG, только для этого вам нужно сначала определить службу для вашего провайдера SVG.

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']

Используя сонату, вы можете создавать расширенные пакеты, используя EASYEXTENDS BUNDLE по умолчанию. он генерирует расширенный пакет в src/Application/Sonata/MediaBundle, но вы также можете указать другое место назначения. Теперь создайте вышеуказанный сервис в расширенном медиапакете services.yml и импортируйте в основной config.yml. Если вы хотите добавить больше типов mime или расширений, вы можете определить в вышеуказанном сервисе allowed_mime_types: ['image/svg+xml','application/pdf']

imports:
    - { resource: @ApplicationSonataMediaBundle/Resources/config/services.yml }

Теперь создайте свой класс провайдера в своем расширенном пакете мультимедиа как SVGProvider и расширьте свой класс провайдера с помощью FileProvider сонаты.

<?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();
        }
    }
}

Здесь вы можете переопределить функции базового класса и определить свои собственные функции по своему усмотрению, например, вы хотите добавить некоторые проверки для ввода файла, вы можете настроить функцию validate() для изменения атрибутов для поля ввода файла, вы можете определить его в методе buildCreateForm()

Теперь в вашем администраторе, если вы хотите разрешить загрузку только SVG, вы можете определить своего собственного провайдера, который разрешает только файлы SVG.

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'),
            )
        )
}
person M Khalid Junaid    schedule 29.09.2015
comment
Все еще верное решение, спасибо. Я немного адаптировал его, и его можно найти здесь. - person kunicmarko20; 01.10.2017