我正在使用VichUploader在symfony项目中上传文件。在我使用的配置中(从文档中复制):
service: vich_uploader.namer_property
options: { property: 'slug'}
在我的实体中,我使用Gedmo / Sluggable自动生成slu ::
/**
* @Gedmo\Slug(fields={"title"}, updatable=false)
* @ORM\Column(type="string", length=100, nullable=false)
*/
protected $slug;
但是当试图保存实体时,我得到以下错误500:
无法生成文件名:属性slug为空。
如果我将该属性设置为' title'有用。我是否忘记了配置参数或其他什么来使它与Gedmo slug一起工作?
答案 0 :(得分:2)
此刻,我遇到了同样的问题,作为一种解决方法,我在实体类中做了些改动:
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
,则无法在文件名中添加增量,则以前保存的文件可能被覆盖!解决方法是,您可以将unique=true
添加到易耗属性。答案 1 :(得分:1)
VichUploader侦听prePersist和preUpdate事件,而Sluggable侦听onFlush事件。因为prePersist和preUpdate是在onFlush之前调用的,所以不可能仅使用配置来做到这一点。
但是,如果文件字段可为空,则可以通过更改控制器代码来解决该问题。当您收到带有文件的提交表单时,请删除文件,保存实体,然后重新添加文件并再次保存实体。在第二次保存时,将已经设置了子文件,因此VichUploader将可以很好地保存文件。
if ($form->isSubmitted() && $form->isValid()) {
if ($file = $entity->getFile()) {
$entity->setFile(null);
}
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
if ($file) {
$document->setFile($file);
$em->persist($entity);
$em->flush();
}
// ...
}
仅在添加新文件时有效。如果随后更改了子段并重新保存实体而不上传新文件,则文件名不会更新。
答案 2 :(得分:0)
默认情况下,doctrine extensions bundle不会附加任何侦听器: http://symfony.com/doc/current/bundles/StofDoctrineExtensionsBundle/index.html#activate-the-extensions-you-want
您应该将其配置为缓慢工作:
stof_doctrine_extensions:
orm:
default:
sluggable: true
答案 3 :(得分:0)
我在上传文件时遇到了同样的问题,为此我需要使用fileName作为文件名。
我当时使用Gedmo批注来生成该段塞,但这仅在刷新时触发,而vichUploader名称器在持久化时触发。
对我来说,最简单的方法是不使用Gedmo \ Sluggable注释,而是在我的Document对象上创建一个prePersist侦听器,并使用Cocur \ Slugify库。
这是代码。
我的文档实体:
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);
}
}
}
到目前为止,我还没有遇到任何问题。
让我知道这是否对您有用