【问题标题】:Sonata media validation at admin管理员的奏鸣曲媒体验证
【发布时间】:2016-06-12 00:03:28
【问题描述】:

我正在尝试验证图像。我看到了答案 Sonata Media: The file could not be found

如何验证图像(宽度和高度)。 我需要帮助。网络中没有合适的文档。

【问题讨论】:

    标签: symfony sonata-admin sonata


    【解决方案1】:

    要使用奏鸣曲媒体验证图像尺寸,您需要覆盖奏鸣曲媒体的ImageProvider 类,奏鸣曲使用此类来处理图像操作。如果您已经有奏鸣曲媒体包的extended bundle,那么在 services.yml 文件中您可以如下定义您自己的提供程序,确保您的 yml 文件包含在 main config.yml 中

    parameters:
        sonata.media.provider.file.class: Application\Sonata\MediaBundle\Provider\ImageProvider
    

    现在创建您的提供程序并使用奏鸣曲媒体的 ImageProvider 覆盖器 validate() 函数扩展它并定义您自己的验证,或者可以覆盖 buildCreateForm()/buildEditForm() 并为 binaryContent 字段定义您的断言

    命名空间 Application\Sonata\MediaBundle\Provider;

    //... other uses classes
    use Sonata\MediaBundle\Provider\ImageProvider as BaseProvider;
    
    class ImageProvider extends BaseProvider
    {
    
        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;
        }
    
        /**
         * {@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();
            }
    
            if ($media->getWidth() > '1280' || $media->getHeight() > 1280) {
                $errorElement
                    ->with('binaryContent')
                    ->addViolation('Invalid File Dimension : Please upload 1280px * (1280px) image')
                    ->end();
            }
        }
    
    }
    

    【讨论】:

    • 我们不能使用这个。它改变了整个验证。同时使用多个实体(使用奏鸣曲媒体)。如何验证?
    • 根据您的回答,我使用了 buildCreateForm() 但我有问题,请检查链接。 stackoverflow.com/questions/38308774/…
    【解决方案2】:

    此代码对我有用。 仅在 MyBundle(此处为 AppBundle)中使用 SonataMedia 时。我在 SonataUserBundle(Application\Sonata\UserBundle\Entity) 中使用了相同的代码。但是失败了。

    实体:

    <?php
    // To reduce code i deleted many lines
    namespace AppBundle\Entity;
    
    use Doctrine\ORM\Mapping as ORM;
    use Symfony\Component\Validator\Constraints as Assert;
    use Symfony\Component\Validator\Context\ExecutionContextInterface;
    use Gedmo\Mapping\Annotation as Gedmo;
    
    /**
    
     * FZHomeSlider
     *
     * @ORM\Table(name="fz__home_slider")
     * @ORM\Entity(repositoryClass="AppBundle\Repository\FZHomeSliderRepository")
     * @ORM\HasLifecycleCallbacks()
     * @Assert\Callback(methods={ "isMediaSizeValid" })
     */
    class FZHomeSlider {
    
        const FILE_PATH = 'image';
        const FILE_SIZE = 200; # kb
        const FILE_MIN_WIDTH = 1024;
        const FILE_MAX_WIDTH = 1024;
        const FILE_MIN_HEIGHT = 250;
        const FILE_MAX_HEIGHT = 250;
    
        /**
         * @var int
         *
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        private $id;
    
        /**
         * @var string
         *
         * @ORM\OneToOne(targetEntity="Application\Sonata\MediaBundle\Entity\Media" )
         * @ORM\JoinColumns( { @ORM\JoinColumn( referencedColumnName="id", onDelete="CASCADE" ) } )
         * @Assert\NotNull()
         */
        private $image;
    
    
        /**
         * Set image
         *
         * @param \Application\Sonata\MediaBundle\Entity\Media $image
         *
         * @return FZHomeSlider
         */
        public function setImage(\Application\Sonata\MediaBundle\Entity\Media $image = null) {
            $this->image = $image;
    
            return $this;
        }
    
        /**
         * Get image
         *
         * @return \Application\Sonata\MediaBundle\Entity\Media
         */
        public function getImage() {
            return $this->image;
        }
    
        /**
         * @param ExecutionContextInterface $context Description
         */
        public function isMediaSizeValid(ExecutionContextInterface $context) {
            $this->fzValidateImage($context, $this->getImage());
        }
    
        private function fzValidateImage($context, $f) {
            if ($f == NULL) {
                $context->buildViolation('Please select an image.')->atPath(self::FILE_PATH)->addViolation();
            } else if ($f->getSize() > (self::FILE_SIZE * 1024)) {
                $context->buildViolation('The file is too large ( %a% kb). Allowed maximum size is %b% kb.')->atPath(self::FILE_PATH)->setParameters(['%a%' => intval($f->getSize() / 1024), '%b%' => self::FILE_SIZE])->addViolation();
            } else if ($f->getWidth() < self::FILE_MIN_WIDTH) {
                $context->buildViolation('The image width is too small ( %a% px). Minimum width expected is  %b% px.')->atPath(self::FILE_PATH)->setParameters(['%a%' => $f->getWidth(), '%b%' => self::FILE_MIN_WIDTH])->addViolation();
            } else if ($f->getWidth() > self::FILE_MAX_WIDTH) {
                $context->buildViolation('The image width is too big ( %a% px). Allowed maximum width is  %b% px.')->atPath(self::FILE_PATH)->setParameters(['%a%' => $f->getWidth(), '%b%' => self::FILE_MAX_WIDTH])->addViolation();
            } else if ($f->getHeight() < self::FILE_MIN_HEIGHT) {
                $context->buildViolation('The image height is too small ( %a% px). Minimum height expected is  %b% px.')->atPath(self::FILE_PATH)->setParameters(['%a%' => $f->getHeight(), '%b%' => self::FILE_MIN_HEIGHT])->addViolation();
            } else if ($f->getHeight() > self::FILE_MAX_HEIGHT) {
                $context->buildViolation('The image height is too big ( %a% px). Allowed maximum height is  %b% px.')->atPath(self::FILE_PATH)->setParameters(['%a%' => $f->getHeight(), '%b%' => self::FILE_MAX_HEIGHT])->addViolation();
            }
        }
    
    }
    

    在管理员中:

    $formMapper
        ->with('Media')
        ->add('image', 'sonata_type_model_list', ['btn_delete' => false, 'help' => self::$FORM_IMG_HELP, 'required' => false], ['link_parameters' => ['provider' => 'sonata.media.provider.image', 'context' => 'home_slider']])->end()
    

    最终解决和解决方案:

    根据Sonata Admin Doc

    用户管理员

    public function getFormBuilder() {
        $this->formOptions['data_class'] = $this->getClass();
    
        $options = $this->formOptions;
        $options['validation_groups'] = "";
    
        $formBuilder = $this->getFormContractor()->getFormBuilder($this->getUniqid(), $options);
    
        $this->defineFormBuilder($formBuilder);
    
        return $formBuilder;
    }
    public function validate(ErrorElement $errorElement, $object) {
        // throw new \Exception("bingo");
        $errorElement
                ->with('phone')
                ->assertLength(['min' => 10, 'max' => '14', 'minMessage' => "Phone number must be at least {{ limit }} characters long", 'maxMessage' => "Phone number cannot be longer than {{ limit }} characters"])
                ->end()
        ;
    }
    

    此处验证电话仅供参考。您也可以使用 validation.yml 文件进行验证。

    Application/Sonata/UserBundle/Resources/config/validation.yml

    Application\Sonata\UserBundle\Entity\User:
    properties:
        phone:
            - Length:
                min:        10
                minMessage: "Phone number must be at least {{ limit }} characters long"
                max:        13
                maxMessage: "Phone number cannot be longer than {{ limit }} characters"
            - Regex:
                pattern:    "/^[\d]{10,13}$/"
        biography:
            - Length:
                min:        5
                minMessage: "Biography must be at least {{ limit }} characters long"
                max:        7
                maxMessage: "Biography cannot be longer than {{ limit }} characters"
    #        image:
    #            - Image validation is done in Entity
    

    【讨论】:

    • $options['validation_groups'] = "";是主要的。
    • 你能用一个针对初始问题的工作示例来完成你的最终答案吗?谢谢
    • @jjgarcía AppBundle\Entity\FZHomeSlider 检查注释行 * @Assert\Callback(methods={ "isMediaSizeValid" }) 这指向函数/方法 isMediaSizeValid。在 ADMIN AppBundle\Admin\FZHomeSliderAdmin 看到 getFormBuilder(){$options['validation_groups'] = "";}。我解决了这个问题,上面有完整的代码,如果有人需要更多详细信息,请告诉我..
    • @jjgarcía 类 FZHomeSliderAdmin 扩展 Admin {} 。这里 Admin 在这个 validation_group 中有 getFormBuilder(){} 给我带来了问题。所以我删除了我的 FZHomeSliderAdmin 中的所有验证组,只需从 Admin 重复 getFormBuilder() .. 我认为你对这个逻辑感到困惑..
    【解决方案3】:
     * @Assert\Image(
     *     minWidth = 200,
     *     maxWidth = 400,
     *     minHeight = 200,
     *     maxHeight = 400
     * )
    

    您可以为Entity添加Assert注解。看:http://symfony.com/doc/current/reference/constraints/Image.html

    【讨论】:

    • 注释验证在 SonataMedia 字段中不起作用。
    猜你喜欢
    • 1970-01-01
    • 2013-12-04
    • 2018-04-30
    • 1970-01-01
    • 2018-03-22
    • 2012-01-07
    • 1970-01-01
    • 2015-07-22
    • 2014-06-04
    相关资源
    最近更新 更多