php - 如何在 Symfony 5 上使用带有 easyAdmin 3 的 Vich uploader

标签 php symfony symfony5 easyadmin vichuploaderbundle

我一直在尝试使用 VichUploader 在 Symfony 项目上上传文件,已经在使用 EasyAdmin 3。
我已正确配置所有内容,但出现此错误:

The "pieceJointeFile" image field must define the directory where the images are uploaded using the setUploadDir() method.

<?php

namespace App\Entity;

use App\Repository\InventaireRepository;
use DateTime;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;

My entity

/**
 * @ORM\Entity(repositoryClass=InventaireRepository::class)
 * @Vich\Uploadable
 */
class Inventaire
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity=Conducteur::class, inversedBy="inventaires")
     */
    private $conducteur;

    /**
     * @ORM\Column(type="date")
     */
    private $dateInventaire;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $pieceJointe;

    /**
     * @Vich\UploadableField(mapping="pieceJointe", fileNameProperty="pieceJointe")
     */
    private $pieceJointeFile;

    /**
     * @ORM\Column(type="datetime")
     */
    private $updatedAt;

    public function __construct()
    {
        $this->updatedAt = new DateTime();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getConducteur(): ?Conducteur
    {
        return $this->conducteur;
    }

    public function setConducteur(?Conducteur $conducteur): self
    {
        $this->conducteur = $conducteur;

        return $this;
    }

    public function getDateInventaire(): ?\DateTimeInterface
    {
        return $this->dateInventaire;
    }

    public function setDateInventaire(\DateTimeInterface $dateInventaire): self
    {
        $this->dateInventaire = $dateInventaire;

        return $this;
    }

    public function getPieceJointeFile() {
        return $this->pieceJointeFile;
    }

    public function setPieceJointeFile($pieceJointeFile): void
    {
        $this->pieceJointeFile = $pieceJointeFile;

        if($pieceJointeFile) {
            $this->updatedAt = new DateTime();
        }
    }

    public function getPieceJointe() {
        return $this->pieceJointe;
    }


    public function setPieceJointe($pieceJointe):self
    {
        $this->pieceJointe = $pieceJointe;
        return $this;
    }

    public function getUpdatedAt()
    {
        return $this->updatedAt;
    }
}
vich上传器配置
vich_uploader:
    db_driver: orm

    mappings:
        pieceJointe:
            uri_prefix: /files/pieceJointe
            upload_destination: '%kernel.project_dir%/public/files/pieceJointe'
最后是我的 crud Controller
<?php

namespace App\Controller\Admin;

use App\Entity\Inventaire;
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
use EasyCorp\Bundle\EasyAdminBundle\Field\DateField;
use EasyCorp\Bundle\EasyAdminBundle\Field\ImageField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
use Vich\UploaderBundle\Form\Type\VichFileType;
use Vich\UploaderBundle\Form\Type\VichImageType;

class InventaireCrudController extends AbstractCrudController
{
    public static function getEntityFqcn(): string
    {
        return Inventaire::class;
    }


    public function configureFields(string $pageName): iterable
    {
        return [
            DateField::new('dateInventaire'),
            AssociationField::new('conducteur'),
            TextField::new('pieceJointeFile')->setFormType(VichFileType::class, [
                'delete_label' => 'supprimer?'
            ])->onlyOnForms(),
            ImageField::new('pieceJointe')->setBasePath('/files/pieceJointe')->onlyOnDetail(),
            ImageField::new('pieceJointeFile')->setFormType(VichImageType::class)
        ];
    }



    public function configureActions(Actions $actions): Actions
    {
        return $actions
            ->add(Crud::PAGE_INDEX, Action::DETAIL);
    }
}
最后,我想澄清一下,当使用 TextField 时它工作正常。

最佳答案

你可以通过创建一个简单的字段类来解决这个问题

<?PHP

namespace App\Field;

use App\Form\MetaDataType;
use EasyCorp\Bundle\EasyAdminBundle\Contracts\Field\FieldInterface;
use EasyCorp\Bundle\EasyAdminBundle\Field\FieldTrait;
use Vich\UploaderBundle\Form\Type\VichImageType;

final class VichImageField implements FieldInterface
{
    use FieldTrait;

    public static function new(string $propertyName, ?string $label = 'Image'): self
    {
        return (new self())
            ->setProperty($propertyName)
            ->setLabel($label)
            // this template is used in 'index' and 'detail' pages
            ->setTemplatePath('admin/field/vich_image.html.twig')
            // this is used in 'edit' and 'new' pages to edit the field contents
            // you can use your own form types too
            ->setFormType(VichImageType::class)
            ->addCssClass('field-vich-image')
        ;
    }
}
然后在你的 crud Controller 中使用它
use App\Field\VichImageField;

...
yield VichImageField::new('image')->hideOnForm();
yield VichImageField::new('imageFile')->onlyOnForms();
来这里两次是因为你需要image要渲染的字段和 imageFile在表格上
{# admin/field/vich_image.html.twig #}
{% if field.value %}
  {% if field.value|match('/\.svg$/') %}
    <div class="thumbnail">
      {{ vich_uploader_asset(entity.instance, field.property ~ 'File', entity.fqcn) }}
    </div>
  {% else %}
    {% set html_id = 'ea-lightbox-' ~ field.uniqueId %}
    <a href="#" class="ea-lightbox-thumbnail" data-featherlight="#{{ html_id }}" data-featherlight-close-on-click="anywhere">
        <img src="{{ vich_uploader_asset(entity.instance, field.property ~ 'File', entity.fqcn)|imagine_filter('admin_thumbnail') }}" alt="{{ entity.name }}" class="img-fluid">
    </a>

    <div id="{{ html_id }}" class="ea-lightbox">
        <img src="{{ vich_uploader_asset(entity.instance, field.property ~ 'File', entity.fqcn)|imagine_filter('admin_full') }}" alt="{{ entity.name }}">
    </div>
  {% endif %}
{% else %}
    <span class="badge badge-secondary">
        Empty
    </span>
{% endif %}

关于php - 如何在 Symfony 5 上使用带有 easyAdmin 3 的 Vich uploader ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65203184/

相关文章:

php - TCPDF & mPDF 错误 : Some data has already been output to browser, 无法发送 PDF 文件

php - 将配置从 service.yaml 移动到 Symfony5 中的另一个文件

php - Symfony,继承实体和学说迁移

foreach 循环内的 PHP foreach 循环

php - 当该帖子的标签等于一个主题时,不显示重复的帖子

PHP 像 Dovecot 的 SQL 一样加密

php - 在Symfony 5上使用DateTime约束时,为什么会收到 "This value should be of type string"?

php - 无法在实体 A 到 B 之间添加新的 ManyToMany 属性,因为我已经拥有这两个实体的 ManyToMany 属性

php - 使用 Oauth 发布推文

symfony - 在 Twig 模板中嵌入服务