How to avoid duplicates on ManyToMany relation with Doctrine2 and Zend Framework2? - orm

The objective is to have 2 entity Article and Tag, with a many to many relation where the tags in Tag Table remain unique even if declare the same tag for other article.
I try to explain better with code:
Article Entity:
/**
* #ORM\Entity
* #ORM\Table(name="articles")
*/
class Article {
/**
* #ORM\Id #ORM\GeneratedValue(strategy="AUTO") #ORM\Column(type="integer")
* #var int
*/
protected $id;
/**
* #ORM\Column(type="string")
* #var string
*/
protected $name;
/**
* #ORM\ManyToMany(targetEntity="Tag\Entity\Tag",inversedBy="platforms",cascade={"persist","remove"})
*
* #return Tag[]
*/
protected $tags;
public function __construct() {
$this->tags = new ArrayCollection();
}
public function setId($id) {
$this->id = $id;
}
public function getId() {
return $this->id;
}
public function setName($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
public function setTags($tags){
$this->tags = $tags;
}
public function setTagsFromArray(array $tags){
foreach($tags as $tag){
$this->tags->add(new Tag($tag));
}
}
/**
* Return the associated Tags
*
* #param boolean $getOnlyTagsName [optional] If set to true return a simple array of string (tags name).
* If set to false return array of Tag objects.
*
* #return Tag[]|string[]
*/
public function getTags($getOnlyTagsName=false) {
if ($getOnlyTagsName){
return array_map(function($i) { return $i->getName(); }, $this->tags->toArray());
}
return $this->tags;
}
public function addTags($tags) {
foreach($tags as $tag){
$this->tags->add($tag);
}
}
public function removeTags($tags) {
foreach ($tags as $tag){
$this->tags->removeElement($tag);
}
}
}
Tag Entity:
/**
* #ORM\Entity
* #ORM\Table(name="tags")
* ORM\HasLifecycleCallbacks // NOT USED
*/
class Tag {
/**
* #ORM\Id #ORM\Column(type="integer") #ORM\GeneratedValue
* #var int
*/
protected $id;
/**
* #ORM\Column(type="string",unique=true)
* #var string
*/
protected $name;
/**
* #ORM\Column(type="datetime",name="created_at")
* #var datetime
*/
protected $createdAt;
/**
* #ORM\Column(type="datetime",name="updated_at")
* #var datetime
*/
protected $updatedAt;
/**
* #ORM\ManyToMany(targetEntity="Article\Entity\Article", mappedBy="tags")
* var Tag[]
*/
protected $platforms;
/**
* Constructor
*
* #param string $name Tag's name
*/
public function __construct($name = null) {
$this->setName($name);
$this->setCreatedAt(new DateTime('now'));
$this->setUpdatedAt(new DateTime('now'));
}
/**
* Avoid duplicate entries.
*
* ORM\PrePersist // NOT USED
*/
public function onPrePersist(LifecycleEventArgs $args) {
}
/**
* Avoid duplicate entries.
*
* ORM\PreUpdate // NOT USED
*/
public function onPreUpdate(PreUpdateEventArgs $args) {
}
public function setId($id) {
$this->id = $id;
}
/**
* Returns tag's id
*
* #return integer
*/
public function getId() {
return $this->id;
}
/**
* Sets the tag's name
*
* #param string $name Name to set
*/
public function setName($name) {
$this->name = $name;
}
/**
* Returns tag's name
*
* #return string
*/
public function getName() {
return $this->name;
}
public function setCreatedAt(DateTime $date) {
$this->createdAt = $date;
}
public function getCreatedAt() {
return $this->createdAt;
}
public function setUpdatedAt(DateTime $date) {
$this->updatedAt = $date;
}
public function getUpdatedAt() {
return $this->updatedAt;
}
}
Then I have the Article Form (with Article Fieldset) where there is a tagsinput (jquery plugin) element. So the form post it's like:
object(Zend\Stdlib\Parameters)[151]
public 'security' => string 'dc2a6ff900fbc87933e07bd35ef36709...' (length=65)
public 'article' =>
array (size=3)
'id' => string '' (length=0)
'name' => string 'Article 1' (length=13)
'tags' =>
array (size=3)
0 => string 'tag1' (length=3)
1 => string 'tag2' (length=4)
2 => string 'tag3' (length=7)
public 'submit' => string 'Add' (length=8)
A the first insert all goes well, but when I try to insert another article with one of the article1 tags I get the error:
An exception occurred while executing 'INSERT INTO tags (name, created_at, updated_at) VALUES (?, ?, ?)' with params ["tag2", "2014-04-26 22:05:37", "2014-04-26 22:05:37"]:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'tag2' for key 'UNIQ_6FBC94265E237E06'
I know that I can use prePersist and preUpdate event listner, but I made some test but I don't know how to use Unit Of Work to avoid duplicates.

You can't have the Tag's name property (and database field) defined as unique. You'll have the Integrity constraint violation every time you set a new tag with a previously picked tag name. You just need to control that a name is not picked for a tag related to the same article.
You could add a Zend\Validator\Db\NoRecordExists validator to the tagsinput element to achieve that. It would be something like that:
$tagsinput->getValidatorChain()->addValidator(
new NoRecordExists( array(
'adapter' => $this->getServiceManager()->get( 'Zend\Db\Adapter\Adapter' ),
'table' => 'tag',
'field' => 'name',
'message' => 'The tag name already exists',
'exclude' => 'article_id = ' . $article->getId(),
) );
--
Edit:
This solution won't work if there are more than one tag, when tagsinput's value will be an array. You could iterate through the array to validate each tag, but it's not an efficient solution, it would execute N queries. You could implement a similar validator which accepts a where clause like TAG_NAME IN ( 'tag1', 'tag2', 'tag3' )
--
Note that this validator doesn't work with Doctrine2; table, field and exclude parameters have database values.
This should work when adding tags to an existing article. To validate that a new article doesn't have duplicated tags, you could do it client side or you could write your own validator.

Related

Encode password easyadmin v3

I have my user that I can manage from my administration panel, I can change the password, but the problem is that in the database it is not encrypted. It is in clear in the database, Save you how I could do it so that it is not anymore? I give you my user entity as well as the crud user And I use the easyadmin v3 and symfony 5 bundle.
My entity User
<?php
namespace App\Entity;
use App\Repository\UserRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* #ORM\Entity(repositoryClass=UserRepository::class)
*/
class User implements UserInterface
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=180, unique=true)
*/
private $email;
/**
* #ORM\Column(type="json")
*/
private $roles = [];
/**
* #var string The hashed password
* #ORM\Column(type="string")
*/
private $password;
/**
* #ORM\Column(type="string", length=255)
*/
private $prenom;
/**
* #ORM\Column(type="string", length=255)
*/
private $nom;
/**
* #ORM\Column(type="string", length=255)
*/
private $telephone;
/**
* #ORM\Column(type="text", nullable=true)
*/
private $aPropos;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
private $facebook;
/**
* #ORM\OneToMany(targetEntity=Realisation::class, mappedBy="user", orphanRemoval=true)
*/
private $realisations;
public function __construct()
{
$this->realisations = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
/**
* A visual identifier that represents this user.
*
* #see UserInterface
*/
public function getUsername(): string
{
return (string) $this->email;
}
/**
* #see UserInterface
*/
public function getRoles(): array
{
$roles = $this->roles;
// guarantee every user at least has ROLE_USER
$roles[] = 'ROLE_USER';
return array_unique($roles);
}
public function setRoles(array $roles): self
{
$this->roles = $roles;
return $this;
}
/**
* #see UserInterface
*/
public function getPassword(): string
{
return (string) $this->password;
}
public function setPassword(string $password): self
{
$this->password = $password;
return $this;
}
/**
* Returning a salt is only needed, if you are not using a modern
* hashing algorithm (e.g. bcrypt or sodium) in your security.yaml.
*
* #see UserInterface
*/
public function getSalt(): ?string
{
return null;
}
/**
* #see UserInterface
*/
public function eraseCredentials()
{
// If you store any temporary, sensitive data on the user, clear it here
// $this->plainPassword = null;
}
public function getPrenom(): ?string
{
return $this->prenom;
}
public function setPrenom(string $prenom): self
{
$this->prenom = $prenom;
return $this;
}
public function getNom(): ?string
{
return $this->nom;
}
public function setNom(string $nom): self
{
$this->nom = $nom;
return $this;
}
public function getTelephone(): ?string
{
return $this->telephone;
}
public function setTelephone(string $telephone): self
{
$this->telephone = $telephone;
return $this;
}
public function getAPropos(): ?string
{
return $this->aPropos;
}
public function setAPropos(?string $aPropos): self
{
$this->aPropos = $aPropos;
return $this;
}
public function getFacebook(): ?string
{
return $this->facebook;
}
public function setFacebook(?string $facebook): self
{
$this->facebook = $facebook;
return $this;
}
/**
* #return Collection|Realisation[]
*/
public function getRealisations(): Collection
{
return $this->realisations;
}
public function addRealisation(Realisation $realisation): self
{
if (!$this->realisations->contains($realisation)) {
$this->realisations[] = $realisation;
$realisation->setUser($this);
}
return $this;
}
public function removeRealisation(Realisation $realisation): self
{
if ($this->realisations->removeElement($realisation)) {
// set the owning side to null (unless already changed)
if ($realisation->getUser() === $this) {
$realisation->setUser(null);
}
}
return $this;
}
public function __toString()
{
return $this->nom;
}
/* public function __toString(){
return $this->nom;
}*/
}
<?php
namespace App\Controller\Admin;
use App\Entity\User;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Field\IntegerField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
class UserCrudController extends AbstractCrudController
{
public static function getEntityFqcn(): string
{
return User::class;
}
public function configureFields(string $pageName): iterable
{
return [
IntegerField::new('id','ID')->onlyOnIndex(),
TextField::new('email'),
TextField::new('password'),
TextField::new('nom'),
TextField::new('telephone'),
TextField::new('aPropos'),
TextField::new('facebook'),
];
}
}
This could be helpful ...
<?php
namespace App\Event\Subscriber;
use App\Entity\BackendUser;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeEntityUpdatedEvent;
class EasyAdminHooksSubscriber implements EventSubscriberInterface {
/**
* #var UserPasswordEncoderInterface
*/
private $passwordEncoder;
/**
* #var ContainerInterface
*/
private $container;
/**
* EasyAdminSubscriber constructor.
*
* #param UserPasswordEncoderInterface $passwordEncoder
* #param ContainerInterface $container
*/
public function __construct(UserPasswordEncoderInterface $passwordEncoder, ContainerInterface $container) {
$this->passwordEncoder = $passwordEncoder;
$this->container = $container;
}
public static function getSubscribedEvents(): array {
return array(
BeforeEntityUpdatedEvent::class => array('preUpdateEntity')
);
}
/**
* #param BeforeEntityUpdatedEvent $event
*
* #noinspection PhpUnused
*/
public function preUpdateEntity(BeforeEntityUpdatedEvent $event) {
$entity = $event->getEntityInstance();
if($entity instanceof BackendUser) {
$this->preUpdateBackendUser($entity);
}
}
/**
* #param BackendUser $be_user
*/
private function preUpdateBackendUser(BackendUser &$be_user) {
$plain_password = $be_user->getPlainPassword();
if(!empty($plain_password)) {
$new_password = $this->passwordEncoder->encodePassword($be_user, $plain_password);
$be_user->setPassword($new_password);
$be_user->setPlainPassword();
}
}
}
Here's a solution I found while trying to create/edit users from my web app's admin dashboard (Symfony 5.3 and EasyAdmin v3). I found it in the EasyAdmin issue tracker over on Github.
You will need to add a plain password field to you User class and set the appropriate getter & setter methods.
/**
* #var string
*/
private $plainPassword;
/**
* #return string
*/
public function getPlainPassword(): string
{
return $this->plainPassword;
}
Add event listeners to listen to create/edit form submission events, extract the plain password from the submitted form data and then hash it.
/** #var UserPasswordHasherInterface */
private $hasher;
public function createEditFormBuilder(EntityDto $entityDto, KeyValueStore $keyValueStore, AdminContext $context): FormBuilderInterface
{
$formBuilder = parent::createEditFormBuilder($entityDto, $keyValueStore, $context);
$this->addEncodePasswordEventListener($formBuilder);
return $formBuilder;
}
public function createNewFormBuilder(EntityDto $entityDto, KeyValueStore $formOptions, AdminContext $context): FormBuilderInterface
{
$formBuilder = parent::createNewFormBuilder($entityDto, $formOptions, $context);
$this->addEncodePasswordEventListener($formBuilder);
return $formBuilder;
}
/**
* #param FormBuilderInterface $formBuilder
*/
public function addEncodePasswordEventListener(FormBuilderInterface $formBuilder)
{
$formBuilder->addEventListener(FormEvents::SUBMIT, function (FormEvent $event){
/** #var User $user */
$user = $event->getData();
if ($user->getPlainPassword()) {
$user->setPassword($this->hasher->hashPassword($user, $user->getPlainPassword()));
}
});
}
Then finally you need to render the appropriate form fields.
public function configureFields(string $pageName): iterable
{
return [
# other fields
Field::new('plainPassword', 'New Password')->onlyOnForms()
->setFormType(RepeatedType::class)
->setFormTypeOptions([
'type' => PasswordType::class,
'first_options' => ['label' => 'New password'],
'second_options' => ['label' => 'Repeat Password']
])->setRequired(true)
];
}
Hope someone finds this useful.
You can add plain password field in User entity:
private ?string $plainPassword= '';
public function getPlainPassword(): ?string
{
return $this->plainPassword;
}
public function setPlainPassword(?string $plainPassword): void
{
$this->plainPassword = $plainPassword;
}
Add password updater in User repo:
public function setNewPassword(PasswordAuthenticatedUserInterface $user, string $plainPassword): void
{
$hashedPassword = $this->hasher->hashPassword($user, $plainPassword);
$user->setPassword($hashedPassword);
$this->_em->persist($user);
$this->_em->flush();
}
And override update/persist methods In UserCrudController:
public function updateEntity(EntityManagerInterface $entityManager, $entityInstance): void
{
$this->updatePassword($entityInstance);
parent::updateEntity($entityManager, $entityInstance);
}
public function persistEntity(EntityManagerInterface $entityManager, $entityInstance): void
{
$this->updatePassword($entityInstance);
parent::persistEntity($entityManager, $entityInstance);
}
private function updatePassword(User $user): void
{
if ($user->getPlainPassword() == '') return;
$this->userRepository->setNewPassword($user, $user->getPlainPassword());
}
It's work in Symfony 5.4.2 / EasyAdmin 3.5.19

Undefined method 'encodePassword'. - error in Apiplateform security encoder undefined

I have a problem in my symfony security api in the service PasswordService. It can't find the encoder
I can't guess what should I do.
This is my security.yaaml file:
This is my code:
<?php
namespace App\Services;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
class PasswordService
{
/**
* #var PasswordService
*/
private $userPasswordEncoder;
/**
* #param UserPasswordEncoderInterface $userPasswordEncoder
*/
public function __construct(UserPasswordEncoderInterface $userPasswordEncoder)
{
$this->userPasswordEncoder = $userPasswordEncoder;
}
/**
* #param object $entity
* #param string $password
* #return string
*/
public function encode(object $entity, string $password): string
{
return $this->userPasswordEncoder->encodePassword($entity, $password);
}
/**
* #param string $password
* #return int
*/
public function formatRequirement(string $password)
{
return preg_match('#^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*\W)#', $password);
}
/**
* #param object $entity
* #param string $password
* #return bool
*/
public function isValid(object $entity, string $password): bool
{
return $this->userPasswordEncoder->isPasswordValid($entity, $password);
}
}
There is no real error you just have a wrong annotation here:
/**
* #var PasswordService <========
*/
private $userPasswordEncoder;
If you remove it, it should be fine. (Or replace it with UserPasswordEncoderInterface)

Avoiding getters and setters in PHP 7.4

As PHP 7.4 supports typed class properties: https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.core.typed-properties. Looks like a lot of code could be eliminated, in particular getters and setters that in entities and DTOs that was responsible for controlling properties types. For example such snippet:
class Foo implements BarInterface
{
/**
* #var int
*/
protected $id;
/**
* #var int|null
*/
protected $type;
/**
* #return int
*/
public function getId(): int
{
return $this->id;
}
/**
* #param int $id
* #return $this
*/
public function setId(int $id)
{
$this->id = $id;
return $this;
}
/**
* #return int|null
*/
public function getType(): ?int
{
return $this->type;
}
/**
* #param int|null $type
* #return $this
*/
public function setType(?int $type)
{
$this->type = $type;
return $this;
}
}
Can be refactored to:
class Foo implements BarInterface
{
public int $id;
public ?int $type;
}
Am I right that this is good idea? What should I take into consideration while making such refactoring?

Symfony 3. Problems with join and the VichUploaderBundle

I load several pictures with the Vichuploaderbundle and the EntryImg Entity.
That is successful!
I have also an Entity named Entries.
Each Entry should be linked with one or more Images
I want to join both Entities in the Repository.
What is the error?
Here is my Entries Entity
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
//use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* #ORM\Entity(repositoryClass="AppBundle\Repository\EntriesRepository")
* #ORM\Table(name="entries")
*/
class Entries
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
* #ORM\OneToMany(targetEntity="AppBundle\Entity\EntryImg", mappedBy="entries")
*/
private $id;
/**
* #ORM\Column(type="string")
*/
private $name;
/**
* #ORM\Column(type="text")
*/
private $description;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\User")
* #ORM\JoinColumn()
*/
private $user;
public function getId()
{
return $this->id;
}
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
}
public function getDescription()
{
return $this->description();
}
public function setDescription($description)
{
$this->description = $description;
return $this;
}
public function getUser()
{
return $this->user;
}
public function setUser(User $user)
{
$this->user = $user;
}
}
My Image Entity
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\File;
//use Symfony\Component\HttpFoundation\File\UploadedFile;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* #ORM\Entity
* #ORM\Table(name="`entry_img`")
* #Vich\Uploadable
*/
class EntryImg
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
protected $id;
/**
* #ORM\Column(type="string", length=255)
* #var string
*/
private $image;
/**
* #Assert\File(maxSize="2000k",mimeTypes={"image/png", "image/jpeg", "image/pjpeg"})
* #Vich\UploadableField(mapping="entry_images", fileNameProperty="image")
* #var File
*/
private $imageFile;
/**
* #ORM\Column(type="datetime")
* #var \DateTime
*/
private $updatedAt;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Entries")
* #ORM\JoinColumn(name="entries_id",referencedColumnName="id",nullable=true)
*/
private $entry;
public function setImageFile(File $image = null)
{
$this->imageFile = $image;
// VERY IMPORTANT:
// It is required that at least one field changes if you are using Doctrine,
// otherwise the event listeners won't be called and the file is lost
if ($image) {
// if 'updatedAt' is not defined in your entity, use another property
$this->updatedAt = new \DateTime('now');
}
}
public function getImageFile()
{
return $this->imageFile;
}
public function setImage($image)
{
$this->image = $image;
}
public function getImage()
{
return $this->image;
}
public function getId()
{
return $this->id;
}
public function getEntry(){
return $this->entry();
}
public function setEntry(Entries $entry){
$this->entry = $entry;
}
}
and my repository
<?php
namespace AppBundle\Repository;
use AppBundle\Entity\Entries;
use AppBundle\Entity\EntryImg;
use Doctrine\ORM\EntityRepository;
class EntriesRepository extends EntityRepository
{
public function findAllEntries($e_ids)
{
$query = $this->createQueryBuilder('e')
->leftJoin('e.id','entry_img');
$i = 0;
foreach($e_ids as $e_id){
if($i==0){
//var_dump($e_id);
$query->where('e.id = :entries_'.$i)
->setParameter('entries_'.$i,$e_id['entry']);
}else if($i>0){
$query->orWhere('e.id = :entries_'.$i)
->setParameter('entries_'.$i,$e_id['entry']);
}
$i++;
}
$result = $query->getQuery()->execute();
return $result;
}
In your class Entries, you have this line:
#ORM\OneToMany(targetEntity="AppBundle\Entity\EntryImg", mappedBy="entries")
But in your EntryImg class, there isn't any $entries property.
Also, if 1 Entries can have many EntryImg, you need to use arraycollection.
I think you should rewrite your Entries class like this:
use Doctrine\Common\Collections\ArrayCollection; //don't forget this line for the constructor
class Entries
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
//look here I remove the relation and put it on $entriesImg property
*/
private $id;
/**
* #ORM\Column(type="array")
* #ORM\OneToMany(targetEntity="AppBundle\Entity\EntryImg", mappedBy="entry") //look here I changed "entries" by "entry" which is the actual property in your EntryImg class. (you did not have any $entries property)
*/
private $entriesImg;
.. the rest of your properties
public function __construct()
{
$this->entriesImg= new ArrayCollection();
}
public function addEntryImg(\AppBundle\Entity\EntryImg $entryImg)
{
$this->entriesImg[] = $entryImg;
return $this;
}
public function removeEntryImg(\AppBundle\Entity\EntryImg $entryImg)
{
$this->entriesImg->removeElement($entryImg);
}
// also don't forget to implement classic getters and setters for the $entriesImg property
Don't forget to implement a toString method for both your entities, you will need it for Crud operation.
Then, later in your repository, you forgot to use the ->addSelect(); method like this
class EntriesRepository extends EntityRepository
{
public function findAllEntries()
{
$query = $this->createQueryBuilder('e')
->leftJoin('e.entriesImg','i');
->addSelect('i')
// whatever from your logic ....

Synfony 2 File Uploader with Doctrine 2

I want to make a simple file uploader with Symfony 2 and Doctrine 2.
I've follow this tutorial :
http://symfony.com/doc/current/cookbook/doctrine/file_uploads.html
and this one :
http://leny-bernard.com/fr/afficher/article/creer-un-site-facilement-en-symfony2-partie-4
Here is my Entity class :
namespace Luna\KBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\File;
/**
* Luna\KBundle\Entity\Media
*
* #ORM\Entity
*/
class Media
{
/**
* #var integer $id
*/
private $id;
/**
* #var string $title
*/
private $title;
/**
* #var text $description
*/
private $description;
/**
* #var string $author
*/
private $author;
/**
* #var string $source
*/
private $source;
/**
* #Assert\File(maxSize="6000000")
*/
private $paths;
/**
* #var string $type
*/
private $type;
/**
* #var Luna\KBundle\Entity\object
*/
private $idobject;
/***********************************METHODS***********************************/
/**
* Set idobject
*
* #param Luna\KBundle\Entity\Object $idobject
*/
public function setIdobject(\Luna\KBundle\Entity\object $idobject)
{
$this->idObject = $idObject;
}
/**
* Get idObject
*
* #return Luna\KBundle\Entity\Object
*/
public function getIdObject()
{
return $this->idObject;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set title
*
* #param string $title
*/
public function setTitle($title)
{
$this->title = $title;
}
/**
* Get title
*
* #return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Set description
*
* #param text $description
*/
public function setDescription($description)
{
$this->description = $description;
}
/**
* Get description
*
* #return text
*/
public function getDescription()
{
return $this->description;
}
/**
* Set author
*
* #param string $author
*/
public function setAuthor($author)
{
$this->author = $author;
}
/**
* Get author
*
* #return string
*/
public function getAuthor()
{
return $this->author;
}
/**
* Set source
*
* #param string $source
*/
public function setSource($source)
{
$this->source = $source;
}
/**
* Get source
*
* #return string
*/
public function getSource()
{
return $this->source;
}
/**
* Set paths
*
* #param string $paths
*/
public function setPaths($paths)
{
$this->paths = $paths;
}
/**
* Get paths
*
* #return string
*/
public function getPaths()
{
return $this->paths;
}
/**
* Set type
*
* #param string $type
*/
public function setType($type)
{
$this->type = $type;
}
/**
* Get type
*
* #return string
*/
public function getType()
{
return $this->type;
}
public function getAbsolutePath()
{
return null === $this->paths ? null : $this->getUploadRootDir().'/'.$this->paths;
}
public function getWebPath()
{
return null === $this->paths ? null : $this->getUploadDir().'/'.$this->paths;
}
protected function getUploadRootDir()
{
// the absolute directory path where uploaded documents should be saved
return __DIR__.'/../../../../web/'.$this->getUploadDir();
}
protected function getUploadDir()
{
// get rid of the __DIR__ so it doesn't screw when displaying uploaded doc/image in the view.
return 'uploads/mediaobject';
}
}
The fact is that #Assert\File(maxSize="6000000") is not working : I don't have a file uploader but just a simple texte field ?!
How can I make this works correctly ?
Regards Guys :)
EDIT : Here my Form builder
namespace Luna\KBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
class MediaInit extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('title')
->add('description')
->add('author')
->add('source')
->add('paths')
->add('type')
->add('idObject')
;
}
}
And Here my twig template :
{% extends '::layout.html.twig' %}
{####################################### MEDIA INIT###########################}
{% block content %}
<h1>Creer un Media</h1>
Entrez les informations de votre media ici
<form action="{{ path('media_init') }}" method="post" {{ form_enctype(form) }}>
{{ form_widget(form) }}
<p>
<button type="submit">Creer</button>
</p>
</form>
{% endblock %}
When you want to upload a file you need to declare a path field & a virtual file field. So, your class needs to look like :
class Media
{
private $path;
/**
* #Assert\File(maxSize="6000000")
*/
private $file;
}
And your form:
class MediaInit extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('file');
}
}
It seems that $builder variable in MediaInit class is not initialized properly (with "Media" type).