问题
I am using VichUploader to upload files within a symfony project. In configuration i use (copied from documentation):
service: vich_uploader.namer_property
options: { property: 'slug'}
In my entity i generate the slugs automatically with Gedmo/Sluggable:
/**
* @Gedmo\Slug(fields={"title"}, updatable=false)
* @ORM\Column(type="string", length=100, nullable=false)
*/
protected $slug;
But when trying to save the entity i get the following error 500:
File name could not be generated: property slug is empty.
If i set the property to 'title' it works. Did i forget a configuration parameter or something else to get it working with the Gedmo slug?
回答1:
I'm having the same issue at the moment, as a workaround, I've slightly changed the slug getter in the entity class:
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;
}
}
That did the trick.
Unfortunately, there're a couple of drawbacks:
- If you ever want to update sluggable behaviour in the annotation to include additional properties, you'll have to update the getter as well.
- This method lacks a check against the database: if there's already a record in the database with the same name
urlizer
in the getter won't be able to add an increment to the file name, previously saved file may be overwritten! As a workaround, you can addunique=true
to sluggable properties.
回答2:
By default the doctrine extensions bundle does not attach any listener: http://symfony.com/doc/current/bundles/StofDoctrineExtensionsBundle/index.html#activate-the-extensions-you-want
You should configure it to get sluggable working:
stof_doctrine_extensions:
orm:
default:
sluggable: true
回答3:
I was having the same problem uploading a document for which I needed the fileName to be the slug.
I was using Gedmo annotations to generate the slug, however this only triggers on flush and the vichUploader namer is triggered upon persist.
The easiest way for me to get this working was to not use the Gedmo\Sluggable annotation but rather create a prePersist listener on my Document object and use the Cocur\Slugify library.
So here is the code.
My Document Entity:
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;
}
}
And the listener :
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);
}
}
}
So far I have not had any problems.
Let me know if this works for you
来源:https://stackoverflow.com/questions/35749923/symfony-vichuploaderbundle-file-name-could-not-be-generated