Multiple-File upload - symfony3 - symfony

Symfony3 with PhpStorm.2016.3.2
I succeeded in making a file uploader for one picture only. But now I need to make it "multiple"
I will show you the code and the error that comes up with it as I canno't upload multiple files.
here is the controller
public function newAction(Request $request)
{
$restaurant = new Restaurant();
$form = $this->createForm(RestaurantType::class, $restaurant);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
// file upload
if ($request->files->get('restaurant')['picture'] != null) {
$file = $request->files->get('restaurant')['picture'];
$targetDir = $this->getParameter('uploaded_restaurants');
$filename = $this->get('app.uploader')->upload($file, $targetDir);
$mediaRestaurant = null;
if ($restaurant->getId() != null) {
$mediaRestaurant = $this->getDoctrine()->getRepository('AppBundle:Media')->findPictureByRestaurant($restaurant);
}
if ($mediaRestaurant) {
$media = $mediaRestaurant;
$fs = new Filesystem();
try {
$fs->remove($this->get('kernel')->getRootDir().'/../web/uploads/restaurants/'.$media->getName());
} catch (IOException $e) {
echo "error";
}
} else {
$media = new Media();
$media->setCreatedAt(new \DateTime());
}
$originalName = $file->getClientOriginalName();
$media->setName($filename)
->setOriginalName($originalName)
->setType('img')
->setContext('restaurant_picture')
->setUpdatedAt(new \DateTime())
;
$media->setRestaurant($restaurant);
$em->persist($media);
}
$restaurant->setIsActivated(false);
$em->persist($restaurant);
$em->flush();
}
return $this->render('admin/restaurant/new.html.twig', array(
'restaurant' => $restaurant,
'form' => $form->createView(),
));
}
my FormType(called RestaurantType) where I added a field for file upload (when I set up multiple to false it actually works for only one picture)
$builder
->add('picture', FileType::class, array(
'label' => 'Photos du restaurant',
'multiple' => true,
'required' => false,
'mapped' => false,
'attr' => array(
'accept' => '.jpg,.jpeg,.png'),
))
The service to uploads file
class FileUploader
{
/**
* #param UploadedFile $file
* #param $targetDir
* #return string
*/
public function upload(UploadedFile $file, $targetDir)
{
$fileName = md5(uniqid()).'.'.$file->guessExtension();
$file->move($targetDir, $fileName);
return $fileName;
}
}
the queryBuilder in the MediaRepository
public function findPictureByRestaurant(Restaurant $restaurant)
{
return $this->createQueryBuilder('m')
->select('m')
->where('m.restaurant = :restaurant')
->setParameter('restaurant', $restaurant)
->andWhere('m.context = :restaurant_picture')
->setParameter('restaurant_picture', 'restaurant_picture')
->getQuery()
->getOneOrNullResult();
}
in my show.html.twig where you can see the picture
{% if restaurant.medias != null and restaurant.medias.count > 0 and restaurant.medias[0].name != null %}
<img src="/uploads/restaurants/{{ restaurant.medias[0].name }}">
{% endif %}
my config.yml where the files are uploaded
parameters:
locale: fr
uploaded_restaurants: "%kernel.root_dir%/../web/uploads/restaurants"
And the entity Restaurant which is pretty long (sorry)
/**
* Restaurant
*
* #ORM\Table(name="restaurant")
* #ORM\Entity(repositoryClass="AppBundle\Repository\RestaurantRepository")
*/
class Restaurant
{
/**
* #var FoodType
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\FoodType", inversedBy="restaurants")
* #ORM\JoinColumn(name="food_type_id", referencedColumnName="id")
*/
private $foodType;
/**
* #var City
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\City", inversedBy="restaurants")
* #ORM\JoinColumn(name="city_id", referencedColumnName="id")
*/
private $city;
/**
* #var ArrayCollection
*
* #ORM\OneToMany(targetEntity="AppBundle\Entity\Media", mappedBy="restaurant")
*/
private $medias;
/**
* #var ArrayCollection
*
* #ORM\OneToMany(targetEntity="AppBundle\Entity\Privatisation", mappedBy="restaurant")
*/
private $privatisations;
/**
* #var ArrayCollection
*
* #ORM\OneToMany(targetEntity="AppBundle\Entity\Retrocession", mappedBy="restaurant")
*/
private $retrocessions;
/**
* #var ArrayCollection
*
* #ORM\OneToMany(targetEntity="AppBundle\Entity\OpenedSlot", mappedBy="restaurant")
*/
private $openedSlots;
/**
* #var ArrayCollection
*
* #ORM\OneToMany(targetEntity="AppBundle\Entity\ExceptionSlot", mappedBy="restaurant")
*/
private $exceptionSlots;
/**
* #var ArrayCollection
*
* #ORM\OneToMany(targetEntity="AppBundle\Entity\Slot", mappedBy="restaurant")
*/
private $slots;
/**
* #var ArrayCollection
*
* #ORM\OneToMany(targetEntity="AppBundle\Entity\Chef", mappedBy="restaurant")
*/
private $chefs;
/**
* Constructor
*/
public function __construct()
{
$this->medias = new ArrayCollection();
$this->privatisations = new ArrayCollection();
$this->retrocessions = new ArrayCollection();
$this->openedSlots = new ArrayCollection();
$this->exceptionSlots = new ArrayCollection();
$this->slots = new ArrayCollection();
$this->chefs = new ArrayCollection();
}
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=120, unique=true)
* #Assert\Length(
* max = 120,
* maxMessage = "Ce champ ne peut pas dépasser {{ limit }} caractères."
* )
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="slug", type="string", length=255, unique=true)
* #Gedmo\Slug(fields={"name"})
* #Assert\Length(
* max = 255,
* maxMessage = "Ce champ ne peut pas dépasser {{ limit }} caractères."
* )
*/
private $slug;
/**
* #var string
*
* #ORM\Column(name="description", type="text")
*/
private $description;
/**
* #var string
*
* #ORM\Column(name="webUrl", type="string", length=255, nullable=true)
* #Assert\Length(
* max = 255,
* maxMessage = "Ce champ ne peut pas dépasser {{ limit }} caractères."
* )
*/
private $webUrl;
/**
* #var string
*
* #ORM\Column(name="tripAdvisorUrl", type="string", length=255, nullable=true)
* #Assert\Length(
* max = 255,
* maxMessage = "Ce champ ne peut pas dépasser {{ limit }} caractères."
* )
*/
private $tripAdvisorUrl;
/**
* #var string
*
* #ORM\Column(name="facebookUrl", type="string", length=255, nullable=true)
* #Assert\Length(
* max = 255,
* maxMessage = "Ce champ ne peut pas dépasser {{ limit }} caractères."
* )
*/
private $facebookUrl;
/**
* #var string
*
* #ORM\Column(name="twitterUrl", type="string", length=255, nullable=true)
* #Assert\Length(
* max = 255,
* maxMessage = "Ce champ ne peut pas dépasser {{ limit }} caractères."
* )
*/
private $twitterUrl;
/**
* #var string
*
* #ORM\Column(name="instagramUrl", type="string", length=255, nullable=true)
* #Assert\Length(
* max = 255,
* maxMessage = "Ce champ ne peut pas dépasser {{ limit }} caractères."
* )
*/
private $instagramUrl;
/**
* #var string
*
* #ORM\Column(name="phone", type="string", length=20)
* #Assert\Regex(
* pattern="#^0[1-9]([-. ]?[0-9]{2}){4}$#",
* match=true,
* message="Numéro de téléphone invalide."
* )
*/
private $phone;
/**
* #var string
*
* #ORM\Column(name="phone2", type="string", length=20, nullable=true)
* #Assert\Regex(
* pattern="#^0[1-9]([-. ]?[0-9]{2}){4}$#",
* match=true,
* message="Numéro de téléphone invalide."
* )
*/
private $phone2;
/**
* #var string
*
* #ORM\Column(name="email", type="string", length=255)
* #Assert\Length(
* max = 255,
* maxMessage = "Ce champ ne peut pas dépasser {{ limit }} caractères."
* )
*/
private $email;
/**
* #var float
*
* #ORM\Column(name="latitude", type="float")
* #Assert\Regex(
* pattern="/^-?(?:\d+|\d*\.\d+)$/",
* match=true,
* )
*/
private $latitude;
/**
* #var float
*
* #ORM\Column(name="longitude", type="float")
* #Assert\Regex(
* pattern="/^-?(?:\d+|\d*\.\d+)$/",
* match=true,
* )
*/
private $longitude;
/**
* #var int
*
* #ORM\Column(name="stars", type="integer", nullable=true)
* #Assert\Regex(
* pattern="/^[0-9]+$/",
* match=true,
* message="Ceci n'est pas un chiffre."
* )
*/
private $stars;
/**
* #var int
*
* #ORM\Column(name="seatNumber", type="integer", nullable=true)
* #Assert\Regex(
* pattern="/^[0-9]+$/",
* match=true,
* )
*/
private $seatNumber;
/**
* #var float
*
* #ORM\Column(name="minPrice", type="float", nullable=true)
* #Assert\Regex(
* pattern="/^-?(?:\d+|\d*\.\d+)$/",
* match=true,
* )
*/
private $minPrice;
/**
* #var float
*
* #ORM\Column(name="maxPrice", type="float", nullable=true)
* #Assert\Regex(
* pattern="/^-?(?:\d+|\d*\.\d+)$/",
* match=true,
* )
*/
private $maxPrice;
/**
* #var string
*
* #ORM\Column(name="address", type="string", length=255)
* #Assert\Length(
* max = 255,
* maxMessage = "Ce champ ne peut pas dépasser {{ limit }} caractères."
* )
*/
private $address;
/**
* #var bool
*
* #ORM\Column(name="is_activated", type="boolean")
*/
private $isActivated = true;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*
* #return Restaurant
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set slug
*
* #param string $slug
*
* #return Restaurant
*/
public function setSlug($slug)
{
$this->slug = $slug;
return $this;
}
/**
* Get slug
*
* #return string
*/
public function getSlug()
{
return $this->slug;
}
/**
* Set description
*
* #param string $description
*
* #return Restaurant
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set webUrl
*
* #param string $webUrl
*
* #return Restaurant
*/
public function setWebUrl($webUrl)
{
$this->webUrl = $webUrl;
return $this;
}
/**
* Get webUrl
*
* #return string
*/
public function getWebUrl()
{
return $this->webUrl;
}
/**
* Set tripAdvisorUrl
*
* #param string $tripAdvisorUrl
*
* #return Restaurant
*/
public function setTripAdvisorUrl($tripAdvisorUrl)
{
$this->tripAdvisorUrl = $tripAdvisorUrl;
return $this;
}
/**
* Get tripAdvisorUrl
*
* #return string
*/
public function getTripAdvisorUrl()
{
return $this->tripAdvisorUrl;
}
/**
* Set facebookUrl
*
* #param string $facebookUrl
*
* #return Restaurant
*/
public function setFacebookUrl($facebookUrl)
{
$this->facebookUrl = $facebookUrl;
return $this;
}
/**
* Get facebookUrl
*
* #return string
*/
public function getFacebookUrl()
{
return $this->facebookUrl;
}
/**
* Set twitterUrl
*
* #param string $twitterUrl
*
* #return Restaurant
*/
public function setTwitterUrl($twitterUrl)
{
$this->twitterUrl = $twitterUrl;
return $this;
}
/**
* Get twitterUrl
*
* #return string
*/
public function getTwitterUrl()
{
return $this->twitterUrl;
}
/**
* Set instagramUrl
*
* #param string $instagramUrl
*
* #return Restaurant
*/
public function setInstagramUrl($instagramUrl)
{
$this->instagramUrl = $instagramUrl;
return $this;
}
/**
* Get instagramUrl
*
* #return string
*/
public function getInstagramUrl()
{
return $this->instagramUrl;
}
/**
* Set phone
*
* #param string $phone
*
* #return Restaurant
*/
public function setPhone($phone)
{
$this->phone = $phone;
return $this;
}
/**
* Get phone
*
* #return string
*/
public function getPhone()
{
return $this->phone;
}
/**
* Set phone2
*
* #param string $phone2
*
* #return Restaurant
*/
public function setPhone2($phone2)
{
$this->phone2 = $phone2;
return $this;
}
/**
* Get phone2
*
* #return string
*/
public function getPhone2()
{
return $this->phone2;
}
/**
* Set email
*
* #param string $email
*
* #return Restaurant
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get email
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set latitude
*
* #param float $latitude
*
* #return Restaurant
*/
public function setLatitude($latitude)
{
$this->latitude = $latitude;
return $this;
}
/**
* Get latitude
*
* #return float
*/
public function getLatitude()
{
return $this->latitude;
}
/**
* Set longitude
*
* #param float $longitude
*
* #return Restaurant
*/
public function setLongitude($longitude)
{
$this->longitude = $longitude;
return $this;
}
/**
* Get longitude
*
* #return float
*/
public function getLongitude()
{
return $this->longitude;
}
/**
* Set stars
*
* #param integer $stars
*
* #return Restaurant
*/
public function setStars($stars)
{
$this->stars = $stars;
return $this;
}
/**
* Get stars
*
* #return int
*/
public function getStars()
{
return $this->stars;
}
/**
* Set seatNumber
*
* #param integer $seatNumber
*
* #return Restaurant
*/
public function setSeatNumber($seatNumber)
{
$this->seatNumber = $seatNumber;
return $this;
}
/**
* Get seatNumber
*
* #return int
*/
public function getSeatNumber()
{
return $this->seatNumber;
}
/**
* Set minPrice
*
* #param float $minPrice
*
* #return Restaurant
*/
public function setMinPrice($minPrice)
{
$this->minPrice = $minPrice;
return $this;
}
/**
* Get minPrice
*
* #return float
*/
public function getMinPrice()
{
return $this->minPrice;
}
/**
* Set maxPrice
*
* #param float $maxPrice
*
* #return Restaurant
*/
public function setMaxPrice($maxPrice)
{
$this->maxPrice = $maxPrice;
return $this;
}
/**
* Get maxPrice
*
* #return float
*/
public function getMaxPrice()
{
return $this->maxPrice;
}
/**
* Set address
*
* #param string $address
*
* #return Restaurant
*/
public function setAddress($address)
{
$this->address = $address;
return $this;
}
/**
* Get address
*
* #return string
*/
public function getAddress()
{
return $this->address;
}
/**
* Add media
*
* #param Media $media
*
* #return Restaurant
*/
public function addMedia(Media $media)
{
$this->medias[] = $media;
return $this;
}
/**
* Remove media
*
* #param Media $media
*/
public function removeMedia(Media $media)
{
$this->medias->removeElement($media);
}
/**
* Get medias
*
* #return ArrayCollection
*/
public function getMedias()
{
return $this->medias;
}
/**
* Set foodType
*
* #param FoodType $foodType
*
* #return Restaurant
*/
public function setFoodType(FoodType $foodType = null)
{
$this->foodType = $foodType;
return $this;
}
/**
* Get foodType
*
* #return FoodType
*/
public function getFoodType()
{
return $this->foodType;
}
/**
* Add privatisation
*
* #param Privatisation $privatisation
*
* #return Restaurant
*/
public function addPrivatisation(Privatisation $privatisation)
{
$this->privatisations[] = $privatisation;
return $this;
}
/**
* Remove privatisation
*
* #param Privatisation $privatisation
*/
public function removePrivatisation(Privatisation $privatisation)
{
$this->privatisations->removeElement($privatisation);
}
/**
* Get privatisations
*
* #return ArrayCollection
*/
public function getPrivatisations()
{
return $this->privatisations;
}
/**
* Add retrocession
*
* #param Retrocession $retrocession
*
* #return Restaurant
*/
public function addRetrocession(Retrocession $retrocession)
{
$this->retrocessions[] = $retrocession;
return $this;
}
/**
* Remove retrocession
*
* #param Retrocession $retrocession
*/
public function removeRetrocession(Retrocession $retrocession)
{
$this->retrocessions->removeElement($retrocession);
}
/**
* Get retrocessions
*
* #return ArrayCollection
*/
public function getRetrocessions()
{
return $this->retrocessions;
}
/**
* Add openedSlot
*
* #param OpenedSlot $openedSlot
*
* #return Restaurant
*/
public function addOpenedSlot(OpenedSlot $openedSlot)
{
$this->openedSlots[] = $openedSlot;
return $this;
}
/**
* Remove openedSlot
*
* #param OpenedSlot $openedSlot
*/
public function removeOpenedSlot(OpenedSlot $openedSlot)
{
$this->openedSlots->removeElement($openedSlot);
}
/**
* Get openedSlots
*
* #return ArrayCollection
*/
public function getOpenedSlots()
{
return $this->openedSlots;
}
/**
* Add exceptionSlot
*
* #param ExceptionSlot $exceptionSlot
*
* #return Restaurant
*/
public function addExceptionSlot(ExceptionSlot $exceptionSlot)
{
$this->exceptionSlots[] = $exceptionSlot;
return $this;
}
/**
* Remove exceptionSlot
*
* #param ExceptionSlot $exceptionSlot
*/
public function removeExceptionSlot(ExceptionSlot $exceptionSlot)
{
$this->exceptionSlots->removeElement($exceptionSlot);
}
/**
* Get exceptionSlots
*
* #return ArrayCollection
*/
public function getExceptionSlots()
{
return $this->exceptionSlots;
}
/**
* Add slot
*
* #param Slot $slot
*
* #return Restaurant
*/
public function addSlot(Slot $slot)
{
$this->slots[] = $slot;
return $this;
}
/**
* Remove slot
*
* #param Slot $slot
*/
public function removeSlot(Slot $slot)
{
$this->slots->removeElement($slot);
}
/**
* Get slots
*
* #return ArrayCollection
*/
public function getSlots()
{
return $this->slots;
}
/**
* Add chef
*
* #param Chef $chef
*
* #return Restaurant
*/
public function addChef(Chef $chef)
{
$this->chefs[] = $chef;
return $this;
}
/**
* Remove chef
*
* #param Chef $chef
*/
public function removeChef(Chef $chef)
{
$this->chefs->removeElement($chef);
}
/**
* Get chefs
*
* #return ArrayCollection
*/
public function getChefs()
{
return $this->chefs;
}
/**
* Set city
*
* #param City $city
*
* #return Restaurant
*/
public function setCity(City $city = null)
{
$this->city = $city;
return $this;
}
/**
* Get city
*
* #return City
*/
public function getCity()
{
return $this->city;
}
/**
* #return bool
*/
public function getIsActivated()
{
return $this->isActivated;
}
/**
* #param bool $isActivated
*/
public function setIsActivated($isActivated)
{
$this->isActivated = $isActivated;
}
}
and the error that comes up when I upload a picture and click on submit button
To sum up it up all, this code works for only one picture when I set up multiple to false in my FormType. But then I am stuck for the multiple file upload and I can't get to find a way around that. Does someone know how to handle it with the code I given you?
Thank you

Because your file definition accept multiple uploads, you need to modify upload part of your controller:
// file upload
if ($request->files->get('restaurant')['picture'] != null) {
$files = $request->files->get('restaurant')['picture'];
foreach ($files as $file) {
$targetDir = $this->getParameter('uploaded_restaurants');
$filename = $this->get('app.uploader')->upload($file, $targetDir);
$mediaRestaurant = null;
if ($restaurant->getId() != null) {
$mediaRestaurant = $this->getDoctrine()->getRepository('AppBundle:Media')->findPictureByRestaurant($restaurant);
}
if ($mediaRestaurant) {
$media = $mediaRestaurant;
$fs = new Filesystem();
try {
$fs->remove($this->get('kernel')->getRootDir().'/../web/uploads/restaurants/'.$media->getName());
} catch (IOException $e) {
echo "error";
}
} else {
$media = new Media();
$media->setCreatedAt(new \DateTime());
}
$originalName = $file->getClientOriginalName();
$media->setName($filename)
->setOriginalName($originalName)
->setType('img')
->setContext('restaurant_picture')
->setUpdatedAt(new \DateTime())
;
$media->setRestaurant($restaurant);
$em->persist($media);
}
}
Notify that I've taken all files from form uploaded data first, and run your code in a foreach loop.

You need to handle an array in your upload method, as itll get that from the form, rather than an individual UploadedFile object.
/**
* #param UploadedFile $file
* #param $targetDir
* #return array
*/
public function upload($files, $targetDir)
{
if(!is_array($files)) {
$files = (array) $files; // cast to array in case of a form that isn't multiple.
}
$filenames = [];
foreach($files as $file) {
$filenames[] = md5(uniqid()).'.'.$file->guessExtension();
$file->move($targetDir, $fileName);
}
return $filenames;
}
youll need to twiddle whatever is getting the return filename variable, as it'll now be an array.
The other way, which in my opinion is a better UX, is to use a CollectionType and render a file input box per file. Heres a quick example.
$builder->add('file_uploads', CollectionType::class, [
'entry_type' => FileType::class,
'entry_options' => [
'label' => 'Photos du restaurant',
'multiple' => true,
'required' => false,
'mapped' => false,
'attr' => [
'accept' => '.jpg,.jpeg,.png',
],
'allow_add' => true,
'allow_delete' => true,
],
'prototype' => true,
]);
Youll then need to handle the resulting ArrayCollection in your upload handler. But this gives a much nicer interface for the user.
Ive not tested this snippet, so you might have to debug or adapt it to fit with what you're doing.

Related

Why isn't my property mapped to the entity

i got a entity named Listing, here an overview of the table:
I tried to map the field "promoted" as the same as the field "certified", however this isn't working even if symfony tells me all is up-to-date with the db:
here's what i need to do with the "promoted" boolean field (same as "certified" field"), configure form fields:
$formMapper
->with('admin.listing.title')
->add(
'status',
ChoiceType::class,
array(
'choices' => array_flip(Listing::$statusValues),
'placeholder' => 'admin.listing.status.label',
'translation_domain' => 'cocorico_listing',
'label' => 'admin.listing.status.label',
)
)
->add(
'adminNotation',
ChoiceType::class,
array(
'choices' => array_combine(
range(0, 10, 0.5),
array_map(
function ($num) {
return number_format($num, 1);
},
range(0, 10, 0.5)
)
),
'placeholder' => 'admin.listing.admin_notation.label',
'label' => 'admin.listing.admin_notation.label',
'required' => false,
)
)
->add(
'certified',
null,
array(
'label' => 'admin.listing.certified.label',
)
)
->add(
'promoted',
null,
array(
'label' => 'admin.listing.promoted.label',
'required' => false,
)
)
for the type of the certified it is "null" and it works, it find the type as a boolean, but for the promoted it does not find it i got this error:
request.CRITICAL: Uncaught PHP Exception RuntimeException: "Please define a type for field promoted in Cocorico\ListingBundle\Admin\ListingAdmin" at /var/www/Symfony/vendor/sonata-project/doctrine-orm-admin-bundle/src/Builder/FormContractor.php line 69 {"exception":"[object] (RuntimeException(code: 0): Please define a type for field promoted in Cocorico\\ListingBundle\\Admin\\ListingAdmin at /var/www/Symfony/vendor/sonata-project/doctrine-orm-admin-bundle/src/Builder/FormContractor.php:69)"} []
here's my classe BaseListing.php:
<?php
/*
* This file is part of the Cocorico package.
*
* (c) Cocolabs SAS <contact#cocolabs.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Cocorico\ListingBundle\Model;
use Cocorico\ListingBundle\Entity\Listing;
use Cocorico\ListingBundle\Validator\Constraints as CocoricoAssert;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Listing
*
* #CocoricoAssert\ListingConstraint()
*
* #ORM\MappedSuperclass
*/
abstract class BaseListing
{
/* Status */
const STATUS_NEW = 1;
const STATUS_PUBLISHED = 2;
const STATUS_INVALIDATED = 3;
const STATUS_SUSPENDED = 4;
const STATUS_DELETED = 5;
const STATUS_TO_VALIDATE = 6;
public static $statusValues = array(
self::STATUS_NEW => 'entity.listing.status.new',
self::STATUS_PUBLISHED => 'entity.listing.status.published',
self::STATUS_INVALIDATED => 'entity.listing.status.invalidated',
self::STATUS_SUSPENDED => 'entity.listing.status.suspended',
self::STATUS_DELETED => 'entity.listing.status.deleted',
self::STATUS_TO_VALIDATE => 'entity.listing.status.to_validate',
);
public static $visibleStatus = array(
self::STATUS_NEW,
self::STATUS_PUBLISHED,
self::STATUS_INVALIDATED,
self::STATUS_SUSPENDED,
self::STATUS_TO_VALIDATE,
);
/* Type */
const TYPE_ONE = 1;
const TYPE_TWO = 2;
const TYPE_THREE = 3;
public static $typeValues = array(
self::TYPE_ONE => 'entity.listing.type.one',
self::TYPE_TWO => 'entity.listing.type.two',
self::TYPE_THREE => 'entity.listing.type.three',
);
/* Cancellation policy */
const CANCELLATION_POLICY_FLEXIBLE = 1;
const CANCELLATION_POLICY_STRICT = 2;
public static $cancellationPolicyValues = array(
self::CANCELLATION_POLICY_FLEXIBLE => 'entity.listing.cancellation_policy.flexible',
self::CANCELLATION_POLICY_STRICT => 'entity.listing.cancellation_policy.strict',
);
public static $cancellationPolicyDescriptions = array(
self::CANCELLATION_POLICY_FLEXIBLE => 'entity.listing.cancellation_policy_desc.flexible',
self::CANCELLATION_POLICY_STRICT => 'entity.listing.cancellation_policy_desc.strict',
);
/**
* #ORM\Column(name="status", type="smallint", nullable=false)
*
* #var integer
*/
protected $status = self::STATUS_NEW;
/**
* #ORM\Column(name="type", type="smallint", nullable=true)
*
* #var integer
*/
protected $type;
/**
* #ORM\Column(name="price", type="decimal", precision=8, scale=0, nullable=false)
* #Assert\NotBlank(message="assert.not_blank")
*
* #var integer
*/
protected $price = 0;
/**
*
* #ORM\Column(name="certified", type="boolean", nullable=true)
*
* #var boolean
*/
protected $certified;
/**
* #var boolean $promoted
*
* #ORM\Column(name="promoted", type="boolean", nullable=true)
*
* #var boolean
*/
protected $promoted;
/**
*
* #ORM\Column(name="min_duration", type="smallint", nullable=true)
*
* #var integer
*/
protected $minDuration;
/**
*
* #ORM\Column(name="max_duration", type="smallint", nullable=true)
*
* #var integer
*/
protected $maxDuration;
/**
*
* #ORM\Column(name="cancellation_policy", type="smallint", nullable=false)
* #Assert\NotBlank(message="assert.not_blank")
*
* #var integer
*/
protected $cancellationPolicy = self::CANCELLATION_POLICY_FLEXIBLE;
/**
* #ORM\Column(name="average_rating", type="smallint", nullable=true)
*
* #var integer
*/
protected $averageRating;
/**
* #ORM\Column(name="comment_count", type="integer", nullable=true)
*
* #var integer
*/
protected $commentCount = 0;
/**
* Admin notation
*
* #ORM\Column(name="admin_notation", type="decimal", precision=3, scale=1, nullable=true)
*
* #var float
*/
protected $adminNotation;
/**
* #ORM\Column(name="availabilities_updated_at", type="datetime", nullable=true)
*
* #var \DateTime
*/
protected $availabilitiesUpdatedAt;
/**
* Translation proxy
*
* #param $method
* #param $arguments
* #return mixed
*/
public function __call($method, $arguments)
{
return $this->proxyCurrentLocaleTranslation($method, $arguments);
}
/**
* Set status
*
* #param integer $status
* #return $this
*/
public function setStatus($status)
{
if (!in_array($status, array_keys(self::$statusValues))) {
throw new \InvalidArgumentException(
sprintf('Invalid value for listing.status : %s.', $status)
);
}
$this->status = $status;
return $this;
}
/**
* Get status
*
* #return integer
*/
public function getStatus()
{
return $this->status;
}
/**
* Get Status Text
*
* #return string
*/
public function getStatusText()
{
return self::$statusValues[$this->getStatus()];
}
/**
* Return available status for current status
*
* #param int $status
*
* #return array
*/
public static function getAvailableStatusValues($status)
{
$availableStatus = array(self::STATUS_DELETED);
if ($status == self::STATUS_NEW) {
$availableStatus[] = self::STATUS_PUBLISHED;
} elseif ($status == self::STATUS_PUBLISHED) {
$availableStatus[] = self::STATUS_SUSPENDED;
} elseif ($status == self::STATUS_INVALIDATED) {
$availableStatus[] = self::STATUS_TO_VALIDATE;
} elseif ($status == self::STATUS_SUSPENDED) {
$availableStatus[] = self::STATUS_PUBLISHED;
}
//Prepend current status to visible status
array_unshift($availableStatus, $status);
//Construct associative array with keys equals to status values and values to label of status
$status = array_intersect_key(
self::$statusValues,
array_flip($availableStatus)
);
return $status;
}
/**
* Set price
*
* #param integer $price
* #return $this
*/
public function setPrice($price)
{
$this->price = $price;
return $this;
}
/**
* Get price
*
* #return string
*/
public function getPrice()
{
return $this->price;
}
/**
* Get price
*
* #return float
*/
public function getPriceDecimal()
{
return $this->price / 100;
}
/**
* Get offerer amount fees
*
* #param array $feeAsOfferer
*
* #return float
*/
public function getAmountFeeAsOffererDecimal($feeAsOfferer)
{
return $this->getPriceDecimal() * $feeAsOfferer['percent'] + $feeAsOfferer['fixed'] / 100;
}
/**
* Get amount to pay to offerer
*
* #param array $feeAsOfferer
*
* #return float
*/
public function getAmountToPayToOffererDecimal($feeAsOfferer)
{
return $this->getPriceDecimal() - $this->getAmountFeeAsOffererDecimal($feeAsOfferer);
}
/**
* Get amount to pay to offerer minus VAT when listing price is VAT excluded.
*
* Return the same result than getAmountToPayToOffererDecimal used with listing price VAT is included:
* amountToPayVATIncluded = PriceVATIncluded - (PriceVATIncluded * feeAsOfferer)
* amountToPayVATExcluded = amountToPayVATIncluded / (1 + vatRate)
*
* So :
* amountToPayVATIncluded = ((price * (1 + vatRate)) - (price * (1 + vatRate) * feeAsOfferer))
* amountToPayVATExcluded = amountToPayVATIncluded / (1 + vatRate)
* amountToPayVATExcluded = price - price * feeAsOfferer
* amountToPayVATExcluded = getAmountToPayToOffererDecimal
*
*
* #param array $feeAsOfferer
*
* #return int
*/
public function amountToPayToOffererForPriceExcludingVATDecimal($feeAsOfferer)
{
return $this->getAmountToPayToOffererDecimal($feeAsOfferer);
}
/**
* Get offerer amount fees when listing price is VAT excluded.
* Fees are computed on listing price VAT included
*
* #param array $feeAsOfferer
* #param float $vatRate
*
* #return int
*/
public function getAmountFeeAsOffererForPriceExcludingVATDecimal($feeAsOfferer, $vatRate)
{
return $this->getAmountFeeAsOffererDecimal($feeAsOfferer) * (1 + $vatRate);
}
/**
* Return the min listing price according to offerer fees and default min price.
*
* #param array $defaultFeeAsOfferer
* #param int $defaultMinPrice
* #return float
*/
public function getMinPrice($defaultFeeAsOfferer, $defaultMinPrice)
{
$result = $defaultMinPrice;
/** #var $this Listing */
$user = $this->getUser();
if ($user) {
$feeAsOfferer = $user->getFeeAsOfferer($defaultFeeAsOfferer);
$result = max(round($feeAsOfferer['fixed'] / (1 - $feeAsOfferer['percent']), 2), $defaultMinPrice);
}
return $result;
}
/**
* #param array $defaultFeeAsOfferer
* #param int $defaultMinPrice
* #return float
*/
public function getMinPriceDecimal($defaultFeeAsOfferer, $defaultMinPrice)
{
return $this->getMinPrice($defaultFeeAsOfferer, $defaultMinPrice) / 100;
}
/**
* Check if listing has correct min price according to offerer fees and default min price
*
* #param array $defaultFeeAsOfferer
* #param int $defaultMinPrice
* #return bool
*/
public function hasMinPrice($defaultFeeAsOfferer, $defaultMinPrice)
{
if ($defaultMinPrice > 0 || $this->getPrice() > 0) {//if listing is not free or min price > 0
$minPrice = $this->getMinPrice($defaultFeeAsOfferer, $defaultMinPrice);
if ($this->getPrice() < $minPrice) {
return false;
}
}
//else listing is free
return true;
}
/**
* #return boolean
*/
public function isCertified()
{
return $this->certified;
}
/**
* #param boolean $certified
*/
public function setCertified($certified)
{
$this->certified = $certified;
}
/**
* #return boolean
*/
public function isPromoted()
{
return $this->promoted;
}
/**
* #param boolean $promoted
*/
public function setPromoted($promoted)
{
$this->promoted = $promoted;
}
/**
* #return int
*/
public function getType()
{
return $this->type;
}
/**
* Set type
*
* #param integer $type
* #return $this
*/
public function setType($type)
{
if (!in_array($type, array_keys(self::$typeValues))) {
throw new \InvalidArgumentException(
sprintf('Invalid value for listing.type : %s.', $type)
);
}
$this->type = $type;
return $this;
}
/**
* Get Type Text
*
* #return string
*/
public function getTypeText()
{
return self::$typeValues[$this->getType()];
}
/**
* Get certified
*
* #return boolean
*/
public function getCertified()
{
return $this->certified;
}
/**
* Get promoted
*
* #return boolean
*/
public function getPromoted()
{
return $this->promoted;
}
/**
* #return int
*/
public function getMinDuration()
{
return $this->minDuration;
}
/**
* #param int $minDuration
*/
public function setMinDuration($minDuration)
{
$this->minDuration = $minDuration;
}
/**
* #return int
*/
public function getMaxDuration()
{
return $this->maxDuration;
}
/**
* #param int $maxDuration
*/
public function setMaxDuration($maxDuration)
{
$this->maxDuration = $maxDuration;
}
/**
* #return int
*/
public function getCancellationPolicy()
{
return $this->cancellationPolicy;
}
/**
* #param int $cancellationPolicy
*
* #return BaseListing
*/
public function setCancellationPolicy($cancellationPolicy)
{
if (!in_array($cancellationPolicy, array_keys(self::$cancellationPolicyValues))) {
throw new \InvalidArgumentException(
sprintf('Invalid value for listing.status : %s.', $cancellationPolicy)
);
//$cancellationPolicy = self::CANCELLATION_POLICY_FLEXIBLE;
}
$this->cancellationPolicy = $cancellationPolicy;
return $this;
}
/**
* Get Cancellation Policy Text
*
* #return string
*/
public function getCancellationPolicyText()
{
return self::$cancellationPolicyValues[$this->getCancellationPolicy()];
}
/**
* Get Cancellation Policy Description
*
* #return string
*/
public function getCancellationPolicyDescription()
{
return self::$cancellationPolicyDescriptions[$this->getCancellationPolicy()];
}
/**
* Set averageRating
*
* #param integer $averageRating
* #return $this
*/
public function setAverageRating($averageRating)
{
$this->averageRating = $averageRating;
return $this;
}
/**
* Get averageRating
*1
*
* #return integer
*/
public function getAverageRating()
{
return $this->averageRating;
}
/**
* Set commentCount
*
* #param integer $commentCount
* #return $this
*/
public function setCommentCount($commentCount)
{
$this->commentCount = $commentCount;
return $this;
}
/**
* Get commentCount
*1
*
* #return integer
*/
public function getCommentCount()
{
return $this->commentCount;
}
/**
* #return float
*/
public function getAdminNotation()
{
return $this->adminNotation;
}
/**
* #param float $adminNotation
*/
public function setAdminNotation($adminNotation)
{
$this->adminNotation = $adminNotation;
}
/**
* #return \DateTime
*/
public function getAvailabilitiesUpdatedAt()
{
return $this->availabilitiesUpdatedAt;
}
/**
* #param \DateTime $availabilitiesUpdatedAt
*/
public function setAvailabilitiesUpdatedAt($availabilitiesUpdatedAt)
{
$this->availabilitiesUpdatedAt = $availabilitiesUpdatedAt;
}
/**
* #return bool
*/
public function hasPrice()
{
return $this->getPrice() > 0;
}
}
Here's Entity\Listing.php:
<?php
namespace Cocorico\ListingBundle\Entity;
use Cocorico\BookingBundle\Entity\Booking;
use Cocorico\ListingBundle\Model\BaseListing;
use Cocorico\ListingBundle\Model\ListingOptionInterface;
use Cocorico\ListingCategoryBundle\Entity\ListingListingCategory;
use Cocorico\ListingCharacteristicBundle\Entity\ListingListingCharacteristic;
use Cocorico\ListingDiscountBundle\Entity\ListingDiscount;
use Cocorico\ListingImageBundle\Entity\ListingImage;
use Cocorico\ListingLocationBundle\Entity\ListingLocation;
use Cocorico\MessageBundle\Entity\Thread;
use Cocorico\UserBundle\Entity\User;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Listing
*
* #ORM\Entity(repositoryClass="Cocorico\ListingBundle\Repository\ListingRepository")
*
* #ORM\Table(name="listing",indexes={
* #ORM\Index(name="created_at_l_idx", columns={"created_at"}),
* #ORM\Index(name="status_l_idx", columns={"status"}),
* #ORM\Index(name="price_idx", columns={"price"}),
* #ORM\Index(name="type_idx", columns={"type"}),
* #ORM\Index(name="min_duration_idx", columns={"min_duration"}),
* #ORM\Index(name="max_duration_idx", columns={"max_duration"}),
* #ORM\Index(name="average_rating_idx", columns={"average_rating"}),
* #ORM\Index(name="admin_notation_idx", columns={"admin_notation"}),
* #ORM\Index(name="platform_notation_idx", columns={"platform_notation"}),
* })
*/
class Listing extends BaseListing
{
use ORMBehaviors\Timestampable\Timestampable;
use ORMBehaviors\Translatable\Translatable;
use \Cocorico\ListingSearchAdvancedBundle\Model\ListingSearchableTrait;
// use \Cocorico\ListingCategoryFieldBundle\Model\ListingCategoryFieldableTrait;
// use \Cocorico\DeliveryBundle\Model\ListingDeliverableTrait;
// use \Cocorico\ListingDepositBundle\Model\ListingDepositableTrait;
// use \Cocorico\ListingSessionBundle\Model\ListingSessionableTrait;
// use \Cocorico\ServiceBundle\Model\ListingTrait;
// use \Cocorico\ListingVideoBundle\Model\ListingVideoTrait;
// use \Cocorico\CarrierBundle\Model\ListingCarrierableTrait;
/**
* #ORM\Id
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\GeneratedValue(strategy="CUSTOM")
* #ORM\CustomIdGenerator(class="Cocorico\CoreBundle\Model\CustomIdGenerator")
*
* #var integer
*/
protected $id;
/**
* #Assert\NotBlank(message="assert.not_blank")
*
* #ORM\ManyToOne(targetEntity="Cocorico\UserBundle\Entity\User", inversedBy="listings", cascade={"persist"})
* #ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=false, onDelete="CASCADE")
*
* #var User
*/
protected $user;
/**
* #ORM\OneToOne(targetEntity="Cocorico\ListingLocationBundle\Entity\ListingLocation", inversedBy="listing", cascade={"persist", "remove"}, orphanRemoval=true)
* #ORM\JoinColumn(name="location_id", referencedColumnName="id", onDelete="CASCADE")
*
* #var ListingLocation
**/
protected $location;
/**
* #ORM\OneToMany(targetEntity="Cocorico\ListingCategoryBundle\Entity\ListingListingCategory", mappedBy="listing", cascade={"persist", "remove"}, orphanRemoval=true)//, fetch="EAGER"
*
*/
protected $listingListingCategories;
/**
* For Asserts #see \Cocorico\ListingBundle\Validator\Constraints\ListingValidator
*
* #ORM\OneToMany(targetEntity="Cocorico\ListingImageBundle\Entity\ListingImage", mappedBy="listing", cascade={"persist", "remove"}, orphanRemoval=true)
* #ORM\OrderBy({"position" = "asc"})
*/
protected $images;
/**
* #ORM\OneToMany(targetEntity="Cocorico\ListingCharacteristicBundle\Entity\ListingListingCharacteristic", mappedBy="listing", cascade={"persist", "remove"}, orphanRemoval=true) //, fetch="EAGER"
*
*/
protected $listingListingCharacteristics;
/**
*
* #ORM\OneToMany(targetEntity="Cocorico\ListingDiscountBundle\Entity\ListingDiscount", mappedBy="listing", cascade={"persist", "remove"}, orphanRemoval=true)
* #ORM\OrderBy({"fromQuantity" = "asc"})
*/
protected $discounts;
/**
* #ORM\OneToMany(targetEntity="Cocorico\BookingBundle\Entity\Booking", mappedBy="listing", cascade={"persist", "remove"}, orphanRemoval=true)
* #ORM\OrderBy({"createdAt" = "desc"})
*/
protected $bookings;
/**
* #ORM\OneToMany(targetEntity="Cocorico\MessageBundle\Entity\Thread", mappedBy="listing", cascade={"remove"}, orphanRemoval=true)
* #ORM\OrderBy({"createdAt" = "desc"})
*/
protected $threads;
/**
*
* #ORM\OneToMany(targetEntity="Cocorico\ListingBundle\Model\ListingOptionInterface", mappedBy="listing", cascade={"persist", "remove"}, orphanRemoval=true)
*/
protected $options;
public function __construct()
{
$this->images = new ArrayCollection();
$this->listingListingCharacteristics = new ArrayCollection();
$this->listingListingCategories = new ArrayCollection();
$this->discounts = new ArrayCollection();
$this->bookings = new ArrayCollection();
$this->threads = new ArrayCollection();
$this->options = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Add characteristics
*
* #param ListingListingCharacteristic $listingListingCharacteristic
* #return Listing
*/
public function addListingListingCharacteristic(ListingListingCharacteristic $listingListingCharacteristic)
{
$this->listingListingCharacteristics[] = $listingListingCharacteristic;
return $this;
}
/**
* Remove characteristics
*
* #param ListingListingCharacteristic $listingListingCharacteristic
*/
public function removeListingListingCharacteristic(ListingListingCharacteristic $listingListingCharacteristic)
{
$this->listingListingCharacteristics->removeElement($listingListingCharacteristic);
$listingListingCharacteristic->setListing(null);
}
/**
* Get characteristics
*
* #return \Doctrine\Common\Collections\Collection|ListingListingCharacteristic[]
*/
public function getListingListingCharacteristics()
{
return $this->listingListingCharacteristics;
}
/**
* Get characteristics ordered by Group and Characteristic
*
* #return ArrayCollection
*/
public function getListingListingCharacteristicsOrderedByGroup()
{
$iterator = $this->listingListingCharacteristics->getIterator();
$iterator->uasort(
function ($a, $b) {
/**
* #var ListingListingCharacteristic $a
* #var ListingListingCharacteristic $b
*/
$groupPosA = $a->getListingCharacteristic()->getListingCharacteristicGroup()->getPosition();
$groupPosB = $b->getListingCharacteristic()->getListingCharacteristicGroup()->getPosition();
$characteristicPosA = $a->getListingCharacteristic()->getPosition();
$characteristicPosB = $b->getListingCharacteristic()->getPosition();
if ($groupPosA == $groupPosB) {
if ($characteristicPosA == $characteristicPosB) {
return 0;
}
return ($characteristicPosA < $characteristicPosB) ? -1 : 1;
}
return ($groupPosA < $groupPosB) ? -1 : 1;
}
);
return new ArrayCollection(iterator_to_array($iterator));
}
/**
* Add characteristics
*
* #param ListingListingCharacteristic $listingListingCharacteristic
* #return Listing
*/
public function addListingListingCharacteristicsOrderedByGroup(
ListingListingCharacteristic $listingListingCharacteristic
) {
return $this->addListingListingCharacteristic($listingListingCharacteristic);
}
/**
* Remove characteristics
*
* #param ListingListingCharacteristic $listingListingCharacteristic
*/
public function removeListingListingCharacteristicsOrderedByGroup(
ListingListingCharacteristic $listingListingCharacteristic
) {
$this->removeListingListingCharacteristic($listingListingCharacteristic);
}
/**
* Add category
*
* #param ListingListingCategory $listingListingCategory
* #return Listing
*/
public function addListingListingCategory(ListingListingCategory $listingListingCategory)
{
$listingListingCategory->setListing($this);
$this->listingListingCategories[] = $listingListingCategory;
return $this;
}
/**
* Remove category
*
* #param ListingListingCategory $listingListingCategory
*/
public function removeListingListingCategory(ListingListingCategory $listingListingCategory)
{
// foreach ($listingListingCategory->getValues() as $value) {
// $listingListingCategory->removeValue($value);
// }
$this->listingListingCategories->removeElement($listingListingCategory);
}
/**
* Get categories
*
* #return \Doctrine\Common\Collections\Collection|ListingListingCategory[]
*/
public function getListingListingCategories()
{
return $this->listingListingCategories;
}
/**
* Set user
*
* #param \Cocorico\UserBundle\Entity\User $user
* #return Listing
*/
public function setUser(User $user = null)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* #return \Cocorico\UserBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
}
i have done the migration and validate schem, doctrine says it's all good:
However i can replace the 'null' for my field "promoted" by CheckBoxType::class, then i got no error and it looks like the certified:
But this is not working with the db, not persisiting the boolean in the db like Certified.. if someone know something that can help i'll be very happy, been stuck on this for a while..
EDIT: i found that BaseListing isn't included in the mapping such as BaseUser or BaseGroup:
This is maybe the cause, how could i include this please ?

Doctrine - Perform select with relationship 1:N

I have a number of entities (automatically generated with Symfony2 Console) that are structured as follows in the database:
The entity generated is as follows:
class Offers
{
/**
* #var string
* #Assert\Length(
* min = 5,
* max = 64,
* minMessage = "El nombre de la oferta debe de tener al menos {{ limit }} caracteres.",
* maxMessage = "El nombre de la oferta no puede superar los {{ limit }} caracteres."
* )
*/
private $name;
/**
* #var string
*/
private $description;
/**
* #var string
* #Assert\Url(message = "La url '{{ value }}' no es válida")
*/
private $url;
/**
* #var string
*/
private $img;
/**
* #var \DateTime
*/
private $dateFrom;
/**
* #var \DateTime
*/
private $dateTo;
/**
* #var \DateTime
*/
private $registered;
/**
* #var boolean
*/
private $active;
/**
* #var integer
*/
private $availableFor;
/**
* #var integer
*/
private $id;
/**
* #var \Doctrine\Common\Collections\Collection
*/
private $idState;
/**
* Constructor
*/
public function __construct()
{
$this->idState = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Set name
*
* #param string $name
* #return Offers
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set description
*
* #param string $description
* #return Offers
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set url
*
* #param string $url
* #return Offers
*/
public function setUrl($url)
{
$this->url = $url;
return $this;
}
/**
* Get url
*
* #return string
*/
public function getUrl()
{
return $this->url;
}
/**
* Set img
*
* #param string $img
*/
public function setImg($img = null)
{
if ( $img != null)
$this->img = $img;
}
/**
* Get img
*
* #return string
*/
public function getImg()
{
return $this->img;
}
/**
* Set dateFrom
*
* #param \DateTime $dateFrom
* #return Offers
*/
public function setDateFrom($dateFrom)
{
$this->dateFrom = $dateFrom;
return $this;
}
/**
* Get dateFrom
*
* #return \DateTime
*/
public function getDateFrom()
{
return $this->dateFrom;
}
/**
* Set dateTo
*
* #param \DateTime $dateTo
* #return Offers
*/
public function setDateTo($dateTo)
{
$this->dateTo = $dateTo;
return $this;
}
/**
* Get dateTo
*
* #return \DateTime
*/
public function getDateTo()
{
return $this->dateTo;
}
/**
* Set registered
*
* #param \DateTime $registered
* #return Offers
*/
public function setRegistered($registered)
{
$this->registered = $registered;
return $this;
}
/**
* Get registered
*
* #return \DateTime
*/
public function getRegistered()
{
return $this->registered;
}
/**
* Set active
*
* #param boolean $active
* #return Offers
*/
public function setActive($active)
{
$this->active = $active;
return $this;
}
/**
* Get active
*
* #return boolean
*/
public function getActive()
{
return $this->active;
}
/**
* Set availableFor
*
* #param integer $availableFor
* #return Offers
*/
public function setAvailableFor($availableFor)
{
$this->availableFor = $availableFor;
return $this;
}
/**
* Get availableFor
*
* #return integer
*/
public function getAvailableFor()
{
return $this->availableFor;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Add idState
*
* #param \Consolidador\PanelBundle\Entity\States $idState
* #return Offers
*/
public function addIdState(\Consolidador\PanelBundle\Entity\States $idState)
{
$this->idState[] = $idState;
return $this;
}
/**
* Remove idState
*
* #param \Consolidador\PanelBundle\Entity\States $idState
*/
public function removeIdState(\Consolidador\PanelBundle\Entity\States $idState)
{
$this->idState->removeElement($idState);
}
/**
* Get idState
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getIdState()
{
return $this->idState;
}
/**
* Set idState
* #param \Consolidador\PanelBundle\Entity\States $idState
*/
public function setIdState($idState)
{
$this->idState[] = $idState;
}
/**
* Cadena de texto a devolver.
* #return string
*/
public function __toString()
{
return $this->name;
}
It turns out that I select tenders belonging to a particular state, and what I do is this:
$dql = $em->createQuery("SELECT o FROM PanelBundle:Offers o WHERE o.idState = :state");
$dql->setParameter('state', $this->getUser()->getIdAgency()->getIdZone()->getIdState());
$offersState = $dql->getResult();
But I returned the following error:
[Semantical Error] line 0, col 43 near 'idState = :s': Error: Invalid PathExpression. StateFieldPathExpression or SingleValuedAssociationField expected.
Does anyone has thought of something? Do you know how to consult in such institutions?
Greetings and thank you
SOLVED:
Here are the DQL queries used for offerings of a particular state and for all offers that do not belong to any (independent). There may be a more simple way, if anyone knows, you publish it.
SELECT o FROM PanelBundle:Offers o JOIN o.idState os WHERE os.id = :state
SELECT o FROM PanelBundle:Offers o WHERE o.id NOT IN (SELECT x.id FROM PanelBundle:Offers x JOIN x.idState os)
You should JOIN to states table.
$qb
->from('PanelBundle:Offers', 'o')
->select('o')
->join('PanelBundle:States', 's')
->andWhere('o.state = :state');
// ....

Doctrine persist entity with inverse relation not work

I'm trying to save two entities linked. Product entity may have any or many entities ProviderRate. When I try to save the product entity, it tells me that ProviderRate related entity has not assigned one of their required fields. I need to save a product with no need to assign a ProviderRate.
The error message showing me is:
Entity of type AppBundle\Entity\ProviderRate is missing an assigned ID for field 'provider'.
The identifier generation strategy for this entity requires the ID field to be populated before EntityManager#persist() is called.
If you want automatically generated identifiers instead you need to adjust the metadata mapping accordingly.
My entitdades code is as follows:
Product Entity
/**
* Products
*
* #ORM\Table(name="products", uniqueConstraints={#ORM\UniqueConstraint(name="id_producto_UNIQUE", columns={"id"})}, indexes={#ORM\Index(name="fk_id_productos_id_categorias1_idx", columns={"category_id"}), #ORM\Index(name="fk_id_productos_id_producto_tipo1_idx", columns={"type"}), #ORM\Index(name="fk_id_productos_id_moneda1_idx", columns={"currency_id"})})
* #ORM\Entity(repositoryClass="AppBundle\Repository\ProductsRepository")
*/
class Products {
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=45, nullable=false)
* #Assert\NotBlank(message="Por favor, escriba el nombre del producto.")
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="description", type="string", length=255, nullable=false)
*/
private $description;
/**
* #var string
*
* #ORM\Column(name="code", type="string", length=45, nullable=false)
*/
private $code;
/**
* #var string
*
* #ORM\Column(name="description_long", type="text", nullable=false)
*/
private $descriptionLong;
/**
* #var integer
*
* #ORM\Column(name="amount_per_unit", type="integer", nullable=false)
*/
private $amountPerUnit;
/**
* #var string
*
* #ORM\Column(name="weight", type="decimal", precision=11, scale=3, nullable=false)
*/
private $weight;
/**
* #var string
*
* #ORM\Column(name="web", type="string", length=100, nullable=false)
*/
private $web;
/**
* #var boolean
*
* #ORM\Column(name="isActive", type="boolean", nullable=false)
*/
private $isactive;
/**
* #var \DateTime
*
* #ORM\Column(name="createdtime", type="datetime", nullable=false)
* #Assert\DateTime()
*/
private $createdtime;
/**
* #var \DateTime
*
* #ORM\Column(name="modifiedtime", type="datetime", nullable=false)
* #Assert\DateTime()
*/
private $modifiedtime;
/**
* #var \DateTime
*
* #ORM\Column(name="deletedtime", type="datetime", nullable=true)
*/
private $deletedtime;
/**
* #var boolean
*
* #ORM\Column(name="isDeleted", type="boolean", nullable=false)
*/
private $isdeleted;
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var \AppBundle\Entity\Categories
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Categories")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="category_id", referencedColumnName="id")
* })
*/
private $category;
/**
* #var \AppBundle\Entity\ProductTypes
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\ProductTypes")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="type", referencedColumnName="id")
* })
*/
private $type;
/**
* #var \AppBundle\Entity\Currencies
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Currencies")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="currency_id", referencedColumnName="id")
* })
*/
private $currency;
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Sets", inversedBy="product")
* #ORM\JoinTable(name="products_sets",
* joinColumns={
* #ORM\JoinColumn(name="product_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="set_id", referencedColumnName="id")
* }
* )
*/
private $set;
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Products", mappedBy="productParentid")
*/
private $product;
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Documents", inversedBy="product")
* #ORM\JoinTable(name="product_attachments",
* joinColumns={
* #ORM\JoinColumn(name="product_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="document_id", referencedColumnName="id")
* }
* )
*/
private $document;
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Images", inversedBy="product")
* #ORM\JoinTable(name="products_images",
* joinColumns={
* #ORM\JoinColumn(name="product_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="image_id", referencedColumnName="id")
* }
* )
*/
private $image;
// CUSTOM CODE
/**
* #ORM\OneToMany(targetEntity="AppBundle\Entity\ProviderRate", mappedBy="product", cascade={"persist"})
*/
private $providerRate;
/**
* Constructor
*/
public function __construct() {
$this->createdtime = new \DateTime();
$this->modifiedtime = new \DateTime();
$this->set = new \Doctrine\Common\Collections\ArrayCollection();
$this->product = new \Doctrine\Common\Collections\ArrayCollection();
$this->document = new \Doctrine\Common\Collections\ArrayCollection();
$this->image = new \Doctrine\Common\Collections\ArrayCollection();
$this->providerRate = new \Doctrine\Common\Collections\ArrayCollection();
$this->descriptionLong = '';
$this->amountPerUnit = 1;
$this->web = '';
$this->weight = 0;
$this->isdeleted = 0;
}
/**
* Set name
*
* #param string $name
* #return Products
*/
public function setName($name) {
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName() {
return $this->name;
}
/**
* Set description
*
* #param string $description
* #return Products
*/
public function setDescription($description) {
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription() {
return $this->description;
}
/**
* Set code
*
* #param string $code
* #return Products
*/
public function setCode($code) {
$this->code = $code;
return $this;
}
/**
* Get code
*
* #return string
*/
public function getCode() {
return $this->code;
}
/**
* Set descriptionLong
*
* #param string $descriptionLong
* #return Products
*/
public function setDescriptionLong($descriptionLong) {
$this->descriptionLong = $descriptionLong;
return $this;
}
/**
* Get descriptionLong
*
* #return string
*/
public function getDescriptionLong() {
return $this->descriptionLong;
}
/**
* Set amountPerUnit
*
* #param integer $amountPerUnit
* #return Products
*/
public function setAmountPerUnit($amountPerUnit) {
$this->amountPerUnit = $amountPerUnit;
return $this;
}
/**
* Get amountPerUnit
*
* #return integer
*/
public function getAmountPerUnit() {
return $this->amountPerUnit;
}
/**
* Set weight
*
* #param string $weight
* #return Products
*/
public function setWeight($weight) {
$this->weight = $weight;
return $this;
}
/**
* Get weight
*
* #return string
*/
public function getWeight() {
return $this->weight;
}
/**
* Set web
*
* #param string $web
* #return Products
*/
public function setWeb($web) {
$this->web = $web;
return $this;
}
/**
* Get web
*
* #return string
*/
public function getWeb() {
return $this->web;
}
/**
* Set isactive
*
* #param boolean $isactive
* #return Products
*/
public function setIsactive($isactive) {
$this->isactive = $isactive;
return $this;
}
/**
* Get isactive
*
* #return boolean
*/
public function getIsactive() {
return $this->isactive;
}
/**
* Set createdtime
*
* #param \DateTime $createdtime
* #return Products
*/
public function setCreatedtime($createdtime) {
$this->createdtime = $createdtime;
return $this;
}
/**
* Get createdtime
*
* #return \DateTime
*/
public function getCreatedtime() {
return $this->createdtime;
}
/**
* Set modifiedtime
*
* #param \DateTime $modifiedtime
* #return Products
*/
public function setModifiedtime($modifiedtime) {
$this->modifiedtime = $modifiedtime;
return $this;
}
/**
* Get modifiedtime
*
* #return \DateTime
*/
public function getModifiedtime() {
return $this->modifiedtime;
}
/**
* Set deletedtime
*
* #param \DateTime $deletedtime
* #return Products
*/
public function setDeletedtime($deletedtime) {
$this->deletedtime = $deletedtime;
return $this;
}
/**
* Get deletedtime
*
* #return \DateTime
*/
public function getDeletedtime() {
return $this->deletedtime;
}
/**
* Set isdeleted
*
* #param boolean $isdeleted
* #return Products
*/
public function setIsdeleted($isdeleted) {
$this->isdeleted = $isdeleted;
return $this;
}
/**
* Get isdeleted
*
* #return boolean
*/
public function getIsdeleted() {
return $this->isdeleted;
}
/**
* Get id
*
* #return integer
*/
public function getId() {
return $this->id;
}
/**
* Set category
*
* #param \AppBundle\Entity\Categories $category
* #return Products
*/
public function setCategory(\AppBundle\Entity\Categories $category = null) {
$this->category = $category;
return $this;
}
/**
* Get category
*
* #return \AppBundle\Entity\Categories
*/
public function getCategory() {
return $this->category;
}
/**
* Set type
*
* #param \AppBundle\Entity\ProductTypes $type
* #return Products
*/
public function setType(\AppBundle\Entity\ProductTypes $type = null) {
$this->type = $type;
return $this;
}
/**
* Get type
*
* #return \AppBundle\Entity\ProductTypes
*/
public function getType() {
return $this->type;
}
/**
* Set currency
*
* #param \AppBundle\Entity\Currencies $currency
* #return Products
*/
public function setCurrency(\AppBundle\Entity\Currencies $currency = null) {
$this->currency = $currency;
return $this;
}
/**
* Get currency
*
* #return \AppBundle\Entity\Currencies
*/
public function getCurrency() {
return $this->currency;
}
/**
* Add set
*
* #param \AppBundle\Entity\Sets $set
* #return Products
*/
public function addSet(\AppBundle\Entity\Sets $set) {
$this->set[] = $set;
return $this;
}
/**
* Remove set
*
* #param \AppBundle\Entity\Sets $set
*/
public function removeSet(\AppBundle\Entity\Sets $set) {
$this->set->removeElement($set);
}
/**
* Get set
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getSet() {
return $this->set;
}
/**
* Add product
*
* #param \AppBundle\Entity\Products $product
* #return Products
*/
public function addProduct(\AppBundle\Entity\Products $product) {
$this->product[] = $product;
return $this;
}
/**
* Remove product
*
* #param \AppBundle\Entity\Products $product
*/
public function removeProduct(\AppBundle\Entity\Products $product) {
$this->product->removeElement($product);
}
/**
* Get product
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getProduct() {
return $this->product;
}
/**
* Add document
*
* #param \AppBundle\Entity\Documents $document
* #return Products
*/
public function addDocument(\AppBundle\Entity\Documents $document) {
$this->document[] = $document;
return $this;
}
/**
* Remove document
*
* #param \AppBundle\Entity\Documents $document
*/
public function removeDocument(\AppBundle\Entity\Documents $document) {
$this->document->removeElement($document);
}
/**
* Get document
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getDocument() {
return $this->document;
}
/**
* Add image
*
* #param \AppBundle\Entity\Images $image
* #return Products
*/
public function addImage(\AppBundle\Entity\Images $image) {
$this->image[] = $image;
return $this;
}
/**
* Remove image
*
* #param \AppBundle\Entity\Images $image
*/
public function removeImage(\AppBundle\Entity\Images $image) {
$this->image->removeElement($image);
}
/**
* Get image
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getImage() {
return $this->image;
}
// CUSTOM CODE
/**
* Set providerRate
*
* #param \AppBundle\Entity\ProviderRate $providerRate
* #return Products
*/
/* public function setProviderRate(\AppBundle\Entity\ProviderRate $providerRate = null)
{
$this->providerRate = $providerRate;
return $this;
}
*/
/**
* Add providerRate
*
* #param \AppBundle\Entity\ProviderRate $providerRate
* #return Products
*/
public function addProviderRate(\AppBundle\Entity\ProviderRate $providerRate) {
$this->providerRate[] = $providerRate;
return $this;
}
/**
* Remove providerRate
*
* #param \AppBundle\Entity\ProviderRate $providerRate
*/
public function removeProviderRate(\AppBundle\Entity\ProviderRate $providerRate) {
$this->providerRate->removeElement($providerRate);
}
/**
* Get providerRate
*
* #return \AppBundle\Entity\ProviderRate
*/
public function getProviderRate()
{
return $this->providerRate;
}
}
ProviderRate Entity
/**
* ProviderRate
*
* #ORM\Table(name="provider_rate", indexes={#ORM\Index(name="fk_proveedor_has_producto_compra_producto_compra1_idx", columns={"product_id"}), #ORM\Index(name="fk_id_tarifa_proveedor_id_moneda1_idx", columns={"currency_id"}), #ORM\Index(name="IDX_3A645C45A53A8AA", columns={"provider_id"})})
* #ORM\Entity(repositoryClass="AppBundle\Repository\ProviderRateRepository")
*/
class ProviderRate
{
/**
* #var string
*
* #ORM\Column(name="reference", type="string", length=45, nullable=false)
*/
private $reference;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=45, nullable=false)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="description", type="string", length=255, nullable=false)
*/
private $description;
/**
* #var integer
*
* #ORM\Column(name="amount_per_unit", type="integer", nullable=true)
*/
private $amountPerUnit;
/**
* #var string
*
* #ORM\Column(name="unit_price", type="decimal", precision=25, scale=3, nullable=false)
*/
private $unitPrice;
/**
* #var string
*
* #ORM\Column(name="discount", type="decimal", precision=25, scale=3, nullable=false)
*/
private $discount;
/**
* #var \AppBundle\Entity\Providers
*
* #ORM\Id
* #ORM\GeneratedValue(strategy="NONE")
* #ORM\OneToOne(targetEntity="AppBundle\Entity\Providers")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="provider_id", referencedColumnName="id")
* })
*/
private $provider;
/**
* #var \AppBundle\Entity\Products
*
* #ORM\Id
* #ORM\GeneratedValue(strategy="NONE")
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Products", inversedBy="providerRate")
* #ORM\JoinColumn(name="product_id", referencedColumnName="id")
*
*/
private $product;
/**
* Set provider
*
* #param \AppBundle\Entity\Providers $provider
* #return ProviderRate
*/
public function setProvider(\AppBundle\Entity\Providers $provider)
{
$this->provider = $provider;
return $this;
}
/**
* Get provider
*
* #return \AppBundle\Entity\Providers
*/
public function getProvider()
{
return $this->provider;
}
/**
* Set product
*
* #param \AppBundle\Entity\Products $product
* #return ProviderRate
*/
public function setProduct(\AppBundle\Entity\Products $product)
{
$this->product = $product;
return $this;
}
/**
* Get product
*
* #return \AppBundle\Entity\Products
*/
public function getProduct()
{
return $this->product;
}
}
The code to run on the controller is as follows:
public function ajaxNewProductAction() {
$request = $this->getRequest();
$product = new Products();
$form = $this->createForm(new ProductsType(), $product);
$form->handleRequest($request);
if ($request->getMethod() == 'POST') {
if ($form->isSubmitted() && $form->isValid()) { // Se procesa el formulario
$em = $this->getDoctrine()->getManager();
$providerId = $request->get('provider');
$productVals = $request->get('Products');
$currency = $em->getRepository('AppBundle:Currencies')->findOneByName("Euro");
$product->setCurrency($currency);
$product->setType($em->getRepository('AppBundle:ProductTypes')->findOneById(1));
$product->setIsactive(1);
$em->persist($product);
$em->flush();
$response['success'] = true;
$response['data'] = 0;
$response['providerId'] = $providerId;
}
else {
$response['success'] = false;
$response['cause'] = 'whatever';
}
return new JsonResponse($response);
}
return $this->render(':products/ajax:newProduct.html.twig', array("form" => $form->createView(), "edit" => false));
}
SOLVE:
I can solve it. The code of my entities thats ok. I change the controller function.
First I create the product object, set the providerRate to null and them persist it.
After I create the providerRate object and set the product object.
public function ajaxNewProductAction() {
$request = $this->getRequest();
$product = new Products();
$form = $this->createForm(new ProductsType(), $product);
$form->handleRequest($request);
if ($request->getMethod() == 'POST') {
if ($form->isSubmitted() && $form->isValid()) { // Se procesa el formulario
$em = $this->getDoctrine()->getManager();
$providerId = $request->get('provider');
$productVal = $request->get('Products');
$currency = $em->getRepository('AppBundle:Currencies')->findOneByName("Euro");
$product->setCurrency($currency);
$product->setType($em->getRepository('AppBundle:ProductTypes')->findOneById(1));
$product->setProviderRate(null);
$em->persist($product);
$em->flush();
$providerRate = new ProviderRate();
$providerRate->setProvider($em->getRepository('AppBundle:Providers')->findOneById($providerId));
$providerRate->setProduct($product);
$providerRate->setReference($productVal["providerRate"][1]["reference"]);
$providerRate->setName($productVal["name"]);
$providerRate->setDescription($productVal["description"]);
$providerRate->setAmountPerUnit(1);
$providerRate->setUnitPrice(0);
$providerRate->setDiscount(0);
$providerRate->setCurrency($currency);
$providerRate->setProduct($product);
$em->persist($providerRate);
$em->flush();
$response['success'] = true;
}
else {
$response['success'] = false;
$response['cause'] = 'Algo ocurrió';
}
return new JsonResponse($response);
}
return $this->render(':products/ajax:newProduct.html.twig', array("form" => $form->createView(), "edit" => false));
}

Error on update query symfony2

I generated the CRUD for the entity Evenement(event) , which is working. But now I want to update a field in another entity called notification everytime an Evenement is added. Each Evenement has a categorie
Evenement.php:
<?php
namespace Mql14\mqlmeBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Mql14\mqlmeBundle\Entity\Evenement
*
* #ORM\Table(name="evenement")
* #ORM\Entity
*/
class Evenement
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string $nom
*
* #ORM\Column(name="nom", type="string", length=45, nullable=true)
*/
private $nom;
/**
* #var datetime $date
*
* #ORM\Column(name="date", type="datetime", nullable=true)
*/
private $date;
/**
* #var string $description
*
* #ORM\Column(name="description", type="string", length=400, nullable=true)
*/
private $description;
/**
* #var integer $ticket
*
* #ORM\Column(name="Ticket", type="integer", nullable=true)
*/
private $ticket;
/**
* #var User
*
* #ORM\ManyToMany(targetEntity="User", mappedBy="evenement")
*/
private $user;
/**
* #var Categorie
*
* #ORM\ManyToOne(targetEntity="Categorie", inversedBy="evenement")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="categorie_id", referencedColumnName="id")
* })
*/
private $categorie;
/**
* #var Lieu
*
* #ORM\ManyToOne(targetEntity="Lieu")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="lieu_id", referencedColumnName="id")
* })
*/
private $lieu;
public function __construct()
{
$this->user = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set nom
*
* #param string $nom
*/
public function setNom($nom)
{
$this->nom = $nom;
}
/**
* Get nom
*
* #return string
*/
public function getNom()
{
return $this->nom;
}
/**
* Set date
*
* #param datetime $date
*/
public function setDate($date)
{
$this->date = $date;
}
/**
* Get date
*
* #return datetime
*/
public function getDate()
{
return $this->date;
}
/**
* Set description
*
* #param string $description
*/
public function setDescription($description)
{
$this->description = $description;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set ticket
*
* #param integer $ticket
*/
public function setTicket($ticket)
{
$this->ticket = $ticket;
}
/**
* Get ticket
*
* #return integer
*/
public function getTicket()
{
return $this->ticket;
}
/**
* Add user
*
* #param Mql14\mqlmeBundle\Entity\User $user
*/
public function addUser(\Mql14\mqlmeBundle\Entity\User $user)
{
$this->user[] = $user;
}
/**
* Get user
*
* #return Doctrine\Common\Collections\Collection
*/
public function getUser()
{
return $this->user;
}
/**
* Set categorie
*
* #param Mql14\mqlmeBundle\Entity\Categorie $categorie
*/
public function setCategorie(\Mql14\mqlmeBundle\Entity\Categorie $categorie)
{
$this->categorie = $categorie;
}
/**
* Get categorie
*
* #return Mql14\mqlmeBundle\Entity\Categorie
*/
public function getCategorie()
{
return $this->categorie;
}
/**
* Set lieu
*
* #param Mql14\mqlmeBundle\Entity\Lieu $lieu
*/
public function setLieu(\Mql14\mqlmeBundle\Entity\Lieu $lieu)
{
$this->lieu = $lieu;
}
/**
* Get lieu
*
* #return Mql14\mqlmeBundle\Entity\Lieu
*/
public function getLieu()
{
return $this->lieu;
}
public function getCategorieId(\Mql14\mqlmeBundle\Entity\Categorie $categorie)
{
$idc= $categorie->getId();
return $idc;
}
}
Categorie.php:
<?php
namespace Mql14\mqlmeBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Mql14\mqlmeBundle\Entity\Categorie
*
* #ORM\Table(name="categorie")
* #ORM\Entity
*/
class Categorie
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string $nomcat
*
* #ORM\Column(name="nomCat", type="string", length=45, nullable=true)
*/
private $nomcat;
/**
* #var string $photo
*
* #ORM\Column(name="photo", type="string", length=45, nullable=true)
*/
private $photo;
/**
* #var $evenement
*
* #ORM\OneToMany(targetEntity="Evenement", mappedBy="categorie")
*/
private $evenement;
/**
* #var User
*
* #ORM\ManyToMany(targetEntity="User", mappedBy="categorie")
*/
private $user;
public function __construct()
{
$this->user = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set nomcat
*
* #param string $nomcat
*/
public function setNomcat($nomcat)
{
$this->nomcat = $nomcat;
}
/**
* Get nomcat
*
* #return string
*/
public function getNomcat()
{
return $this->nomcat;
}
/**
* Set photo
*
* #param string $photo
*/
public function setPhoto($photo)
{
$this->photo = $photo;
}
/**
* Get photo
*
* #return string
*/
public function getPhoto()
{
return $this->photo;
}
/**
* Add user
*
* #param Mql14\mqlmeBundle\Entity\User $user
*/
public function addUser(\Mql14\mqlmeBundle\Entity\User $user)
{
$this->user[] = $user;
}
/**
* Get user
*
* #return Doctrine\Common\Collections\Collection
*/
public function getUser()
{
return $this->user;
}
/**
* Add evenement
*
* #param Mql14\mqlmeBundle\Entity\Categorie $evenement
*/
public function addEvenement(\Mql14\mqlmeBundle\Entity\Evenement $evenement)
{
$this->evenement[] = $evenement;
}
/**
* Get evenement
*
* #return Doctrine\Common\Collections\Collection
*/
public function getEvenement()
{
return $this->evenement;
}
}
Notification.php:
<?php
namespace Mql14\mqlmeBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Mql14\mqlmeBundle\Entity\Notification
*
* #ORM\Table(name="notification")
* #ORM\Entity
*/
class Notification
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string $etat
*
* #ORM\Column(name="etat", type="integer", nullable=true)
*/
private $etat;
/**
* #var User
*
* #ORM\ManyToOne(targetEntity="User")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="User_id", referencedColumnName="id")
*
* })
*/
private $user;
/**
* #var Categorie
*
* #ORM\ManyToOne(targetEntity="Categorie")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="Categorie_id", referencedColumnName="id")
*
* })
*/
private $categorie;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set etat
*
* #param string $etat
*/
public function setEtat($etat)
{
$this->etat = $etat;
}
/**
* Get etat
*
* #return string
*/
public function getEtat()
{
return $this->etat;
}
/**
* Set user
*
* #param Mql14\mqlmeBundle\Entity\User $user
*/
public function setUser(\Mql14\mqlmeBundle\Entity\User $user)
{
$this->user = $user;
}
/**
* Get user
*
* #return Mql14\mqlmeBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
/**
* Set categorie
*
* #param Mql14\mqlmeBundle\Entity\Categorie $categorie
*/
public function setCategorie(\Mql14\mqlmeBundle\Entity\Categorie $categorie)
{
$this->categorie = $categorie;
}
/**
* Get categorie
*
* #return Mql14\mqlmeBundle\Entity\Categorie
*/
public function getCategorie()
{
return $this->categorie;
}
}
In the createAction that was generated after the execution of the CRUD for the Evenement entity I added the update query :
public function createAction(Request $request)
{
$entity = new Evenement();
$request = $this->getRequest();
$form = $this->createForm(new EvenementType(), $entity);
$form->bindRequest($request);
$entity->upload();
$cat=$entity->getCategorie();
if ($cat) {
$catn = $cat->getNomCat();
$query = $this->container->get('doctrine')->getEntityManager()->createQuery( 'UPDATE Mql14mqlmeBundle:Notification n SET n.etat=1 WHERE n.categorie LIKE :catn ' );
$query->setParameter('categorie', $catn);
$query->execute();
}
if ($form->isValid()) {
$em = $this->getDoctrine()->getEntityManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('mql14mqlme_adminshow', array('id' => $entity->getId())));
}
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
And the error I'm getting is this:
[Semantical Error] line 0, col 61 near 'categorie LIKE': Error:
Invalid PathExpression. Must be a StateFieldPathExpression.
You set the wrong parameter in the update query.
On this line:
$query = $this->container->get('doctrine')->getEntityManager()->createQuery(
'UPDATE Mql14mqlmeBundle:Notification n SET n.etat=1
WHERE n.categorie LIKE :catn' );
$query->setParameter('categorie', $catn);
$query->execute();
It should be:
$query = $this->container->get('doctrine')->getEntityManager()->createQuery(
'UPDATE Mql14mqlmeBundle:Notification n SET n.etat=1
WHERE n.categorie LIKE :catn' );
$query->setParameter('catn', $catn);
$query->execute();
n.categorie is an entity (of type Mql14\mqlmeBundle\Entity\Categorie) and you can't compare entities using LIKE.
Try replacing LIKE with =.
Change
UPDATE Mql14mqlmeBundle:Notification n SET n.etat=1 WHERE n.categorie LIKE :catn
To
UPDATE Mql14mqlmeBundle:Notification n SET n.etat=1 WHERE n.categorie = :catn

File Uploads with Doctrine

I am trying to upload files with Doctrine in Symfony2.
I followed all the steps in this tutorial tutorial but whene I submit my form I get no errors but the file is not uploaded and the path in the table "document" is null.
This is my entity
<?php
namespace projet\ClasseBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Projet
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="projet\ClasseBundle\Entity\ProjetRepository")
* #ORM\HasLifecycleCallbacks
*/
class Projet
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var integer
*
* #ORM\Column(name="idMembre", type="integer")
*/
private $idMembre;
/**
* #var integer
*
* #ORM\Column(name="idAssociation", type="integer")
*/
private $idAssociation;
/**
* #var integer
*
* #ORM\Column(name="StatutProjet", type="integer")
*/
private $StatutProjet;
/**
* #var string
*
* #ORM\Column(name="nomProjet", type="string", length=255)
*/
private $nomProjet;
/**
* #var boolean
*
* #ORM\Column(name="visibilite", type="boolean")
*/
private $visibilite;
/**
* #var string
*
* #ORM\Column(name="dateDebut", type="string", length=255)
*/
private $dateDebut;
/**
* #var string
*
* #ORM\Column(name="dateFin", type="string", length=255)
*/
private $dateFin;
/**
* #var float
*
* #ORM\Column(name="budgetActuel", type="float", nullable=true)
*/
private $budgetActuel;
/**
* #var float
*
* #ORM\Column(name="budget", type="float")
*/
private $budget;
/**
* #var string
*
* #ORM\Column(name="description", type="text")
*/
private $description;
/**
* #var string
*
* #ORM\Column(name="ficheProjet", type="string", length=255, nullable=true)
*/
private $ficheProjet;
/**
* #Assert\File(maxSize="6000000")
*/
public $file;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set idMembre
*
* #param integer $idMembre
* #return Projet
*/
public function setIdMembre($idMembre)
{
$this->idMembre = $idMembre;
return $this;
}
/**
* Get idMembre
*
* #return integer
*/
public function getIdMembre()
{
return $this->idMembre;
}
/**
* Set idAssociation
*
* #param integer $idAssociation
* #return Projet
*/
public function setIdAssociation($idAssociation)
{
$this->idAssociation = $idAssociation;
return $this;
}
/**
* Get idAssociation
*
* #return integer
*/
public function getIdAssociation()
{
return $this->idAssociation;
}
/**
* Set StatutProjet
*
* #param integer $StatutProjet
* #return Tache
*/
public function setStatutProjet($StatutProjet)
{
$this->StatutProjet = $StatutProjet;
return $this;
}
/**
* Get StatutProjet
*
* #return integer
*/
public function getStatutProjet()
{
return $this->StatutProjet;
}
/**
* Set nomProjet
*
* #param string $nomProjet
* #return Projet
*/
public function setNomProjet($nomProjet)
{
$this->nomProjet = $nomProjet;
return $this;
}
/**
* Get nomProjet
*
* #return string
*/
public function getNomProjet()
{
return $this->nomProjet;
}
/**
* Set visibilite
*
* #param boolean $visibilite
* #return Projet
*/
public function setVisibilite($visibilite)
{
$this->visibilite = $visibilite;
return $this;
}
/**
* Get visibilite
*
* #return boolean
*/
public function getVisibilite()
{
return $this->visibilite;
}
/**
* Set dateDebut
*
* #param string $dateDebut
* #return Projet
*/
public function setDateDebut($dateDebut)
{
$this->dateDebut = $dateDebut;
return $this;
}
/**
* Get dateDebut
*
* #return string
*/
public function getDateDebut()
{
return $this->dateDebut;
}
/**
* Set dateFin
*
* #param string $dateFin
* #return Projet
*/
public function setDateFin($dateFin)
{
$this->dateFin = $dateFin;
return $this;
}
/**
* Get dateFin
*
* #return string
*/
public function getDateFin()
{
return $this->dateFin;
}
/**
* Set budget
*
* #param float $budget
* #return Projet
*/
public function setBudget($budget)
{
$this->budget = $budget;
return $this;
}
/**
* Get budget
*
* #return float
*/
public function getBudget()
{
return $this->budget;
}
/**
* Set budgetActuel
*
* #param float $budgetActuel
* #return Projet
*/
public function setBudgetActuel($budgetActuel)
{
$this->budgetActuel = $budgetActuel;
return $this;
}
/**
* Get budgetActuel
*
* #return float
*/
public function getBudgetActuel()
{
return $this->budgetActuel;
}
/**
* Set description
*
* #param string $description
* #return Projet
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set ficheProjet
*
* #param string $ficheProjet
* #return Projet
*/
public function setFicheProjet($ficheProjet)
{
$this->ficheProjet = $ficheProjet;
return $this;
}
/**
* Get ficheProjet
*
* #return string
*/
public function getFicheProjet()
{
return $this->ficheProjet;
}
public function getAbsolutePath()
{
return null === $this->ficheProjet ? null : $this->getUploadRootDir().'/'.$this->ficheProjet;
}
public function getWebPath()
{
return null === $this->ficheProjet ? null : $this->getUploadDir().'/'.$this->ficheProjet;
}
protected function getUploadRootDir()
{
// le chemin absolu du répertoire où les documents uploadés doivent être sauvegardés
return __DIR__.'/../../../../web/'.$this->getUploadDir();
}
protected function getUploadDir()
{
// on se débarrasse de « __DIR__ » afin de ne pas avoir de problème lorsqu'on affiche
// le document/image dans la vue.
return 'uploads/documents';
}
/**
* #ORM\PrePersist()
* #ORM\PreUpdate()
*/
public function preUpload()
{
if (null !== $this->file) {
// faites ce que vous voulez pour générer un nom unique
$this->ficheProjet = sha1(uniqid(mt_rand(), true)).'.'.$this->file->guessExtension();
}
}
/**
* #ORM\PostPersist()
* #ORM\PostUpdate()
*/
public function upload()
{
if (null === $this->file) {
return;
}
// s'il y a une erreur lors du déplacement du fichier, une exception
// va automatiquement être lancée par la méthode move(). Cela va empêcher
// proprement l'entité d'être persistée dans la base de données si
// erreur il y a
$this->file->move($this->getUploadRootDir(), $this->ficheProjet);
unset($this->file);
}
/**
* #ORM\PostRemove()
*/
public function removeUpload()
{
if ($file = $this->getAbsolutePath()) {
unlink($file);
}
}
}
NB : I mean ficheProjet by path.
Anny suggestion ? And thanks.
You should try to use Doctrine Uploadable Extension
You have to install the StofDoctrineExtensionBundle
After you should be able to add on your entity :
namespace My\Bundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Validator\Constraints as Assert;
/**
* MyEntity
*
* #ORM\Table(name="my_entity")
* #ORM\Entity()
* #Gedmo\Uploadable(
* path="uploads/my_entity",
* allowOverwrite=true,
* allowedTypes="image/jpeg,image/pjpeg,image/png,image/x-png"
* )
*/
class MyEntity
{
//...
/**
* #var string
*
* #ORM\Column(name="picture", type="string", length=255, nullable=true)
* #Gedmo\UploadableFilePath
* #Assert\File(
* mimeTypes={"image/jpeg", "image/pjpeg", "image/png", "image/x-png"}
* )
*/
private $picture;
//...
}
Don't forget to create the upload folder and set right permissions:
mkdir -p web/uploads/my_entity
chmod -R 777 web/uploads

Resources