管理员的奏鸣曲媒体验证

Sonata media validation at admin

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

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

 * @Assert\Image(
 *     minWidth = 200,
 *     maxWidth = 400,
 *     minHeight = 200,
 *     maxHeight = 400
 * )

您可以为实体添加断言注解。看看:http://symfony.com/doc/current/reference/constraints/Image.html

要使用 sonata media 验证图像尺寸,您需要覆盖 sonata media 的 ImageProvider class,sonata 使用此 class 来处理图像 manipulation.If 您已经有 extended bundle 的 sonata media bundle 然后在 services.yml 文件中你可以定义你自己的提供者如下,确保你的 yml 文件包含在 main config.yml

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

现在创建您的提供者并使用 sonata media 的 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();
        }
    }

}

这段代码对我有用。 仅当在 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()
    ;
}

此处验证phone仅供参考。您还可以使用 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