Php Symfony VichUploaderBundle:无法生成文件名
我正在使用VichUploader上载symfony项目中的文件。在我使用的配置中(从文档中复制): 在我的实体中,我使用Gedmo/slaggable自动生成slug:Php Symfony VichUploaderBundle:无法生成文件名,php,symfony,vichuploaderbundle,Php,Symfony,Vichuploaderbundle,我正在使用VichUploader上载symfony项目中的文件。在我使用的配置中(从文档中复制): 在我的实体中,我使用Gedmo/slaggable自动生成slug: /** * @Gedmo\Slug(fields={"title"}, updatable=false) * @ORM\Column(type="string", length=100, nullable=false) */ protected $slug; 但在尝试保存实体时,我遇到以下错误500: 无法生成文件名:
/**
* @Gedmo\Slug(fields={"title"}, updatable=false)
* @ORM\Column(type="string", length=100, nullable=false)
*/
protected $slug;
但在尝试保存实体时,我遇到以下错误500:
无法生成文件名:属性slug为空
如果我将属性设置为“title”,它将工作。我是否忘记了一个配置参数或其他使其与Gedmo slug一起工作的东西?默认情况下,条令扩展包不附加任何侦听器: 您应该将其配置为使Slagable工作:
stof_doctrine_extensions:
orm:
default:
sluggable: true
目前我也遇到了同样的问题,作为一种解决方法,我稍微更改了entity类中的slug getter:
use Gedmo\Sluggable\Util\Urlizer;
class Event
{
// ...
/**
* @var string
*
* @Gedmo\Slug(fields={"name"})
* @ORM\Column(name="slug", type="string", length=128, unique=true)
*/
private $slug;
// ...
public function getSlug()
{
if (!$this->slug) {
return Urlizer::urlize($this->getName());
}
return $this->slug;
}
}
这就成功了
不幸的是,有几个缺点:
urlizer
,则getter将无法向文件名添加增量,以前保存的文件可能会被覆盖!作为一种解决方法,您可以将unique=true
添加到Slaggable属性我在上传一个文件时遇到了同样的问题,我需要文件名作为slug 我使用Gedmo注释来生成slug,但是这只在flush时触发,而vichUploader名称在persist时触发 对于我来说,最简单的方法是不使用Gedmo\slaggable注释,而是在我的文档对象上创建一个prePersist侦听器,并使用Cocur\slagify库 这是代码 我的文档实体:
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Timestampable\Traits\TimestampableEntity;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* @ORM\Entity(repositoryClass="App\Repository\DocumentRepository")
* @Vich\Uploadable
* @ORM\EntityListeners({"App\Listeners\DocumentListener"})
*/
class Document
{
use TimestampableEntity;
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=100, nullable=false)
*/
private $fileName;
/**
* @Vich\UploadableField(mapping="document", fileNameProperty="fileName")
* @var File
*/
private $documentFile;
/**
* @ORM\Column(type="string", length=100, unique=true)
*/
private $slug;
/**
*/
public function getDocumentFile(): ?File
{
return $this->documentFile;
}
/**
* @param File $documentFile
* @return Document
* @throws \Exception
*/
public function setDocumentFile(File $documentFile = null): Document
{
$this->documentFile = $documentFile;
if($documentFile){
$this->updatedAt = new \DateTimeImmutable();
}
return $this;
}
public function getId(): ?int
{
return $this->id;
}
public function getSlug(): ?string
{
return $this->slug;
}
public function setSlug(string $slug): self
{
$this->slug = $slug;
return $this;
}
/**
* @return mixed
*/
public function getFileName()
{
return $this->fileName;
}
/**
* @param mixed $fileName
*/
public function setFileName($fileName): void
{
$this->fileName = $fileName;
}
}
听众:
namespace App\Listeners;
use App\Entity\Document;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Cocur\Slugify\Slugify;
class DocumentListener
{
public function prePersist(Document $document, LifecycleEventArgs $args)
{
$slugify = new Slugify();
if(!empty($document->getDocumentFile())){
$originalName = pathinfo($document->getDocumentFile()->getClientOriginalName(), PATHINFO_FILENAME);
$slug = $slugify->slugify($originalName);
$document->setSlug($slug);
}
}
}
到目前为止,我还没有遇到任何问题
让我知道这是否适用于您VichUploader侦听prePersist和preUpdate事件,而Sluggable侦听onFlush事件。因为prePersist和preUpdate是在onFlush之前调用的,所以纯粹使用配置是不可能做到这一点的 但是,如果文件字段可为空,则可以通过更改控制器代码来解决此问题。收到提交的表单和文件后,删除该文件,保存实体,然后重新添加该文件并再次保存实体。在第二次保存时,slug已经被设置,因此VichUploader将能够很好地保存文件
if ($form->isSubmitted() && $form->isValid()) {
if ($file = $entity->getFile()) {
$entity->setFile(null);
}
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
if ($file) {
$entity->setFile($file);
$em->persist($entity);
$em->flush();
}
// ...
}
这仅在添加新文件时有效。如果随后更改slug并重新保存实体而不上载新文件,则文件名不会更新。我猜原因是两个捆绑包都使用
flush
事件进行操作,并且以错误的顺序执行……但是有机会配置吗?@Nicki您找到了该怎么做吗?我刚刚遇到了同样的问题-我更改了vich_uploader.namer_uniqid的名称作为一个快速修复,但这不是我想要的。slug是生成的,但它似乎是在VichUploader尝试访问它之后生成的。@Nicki和您的config.yml
中有上面的配置?不是确切的配置,因为我在没有StofBundle的情况下安装了Gedmo。但是监听器已经配置好,并生成了slug。
if ($form->isSubmitted() && $form->isValid()) {
if ($file = $entity->getFile()) {
$entity->setFile(null);
}
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
if ($file) {
$entity->setFile($file);
$em->persist($entity);
$em->flush();
}
// ...
}