FosUserBundle and doctrine request - symfony

When I execute this query
public function SearchByfournisseur($keyWord)
{
$qb = $this->createQueryBuilder('p')->distinct()->select('p');
$qb ->leftJoin('p.Fournisseur', 'f');
$qb ->where($qb->expr()->eq('f.username', $keyWord));
$query = $qb->getQuery();
$products = $query->getResult();
return $products;
}
I got this error:
[Semantical Error] line 0, col 110 near 'test': Error: 'test' is not defined.
But this one works perfectly:
public function SearchByfournisseur($keyWord)
{
$qb = $this->createQueryBuilder('p')->distinct()->select('p');
$qb ->leftJoin('p.Fournisseur', 'f');
$qb ->where($qb->expr()->eq('f.id', $keyWord));
$query = $qb->getQuery();
$products = $query->getResult();
return $products;
}
That means that I can't access to the user's attributes except his id.
Is there any away to solve this problem?
EDIT:
This is the concerned entities :
<?php
namespace Ecommerce\boutiqueBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use FS\SolrBundle\Doctrine\Annotation as Solr;
/**
* Ecommerce\boutiqueBundle\Entity\Produit
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="Ecommerce\boutiqueBundle\Entity\ProduitRepository")
*/
class Produit
{
/**
* #var integer $id
*#Solr\Id
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Ecommerce\UserBundle\Entity\User",inversedBy="Produits")
*
* #ORM\JoinColumn(name="Fournisseur_id", referencedColumnName="id")
*/
private $Fournisseur;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set Fournisseur
*
* #param string $Fournisseur
*/
public function setFournisseur( $Fournisseur)
{
$this->Fournisseur = $Fournisseur;
}
/**
* Get Fournisseur
*
* #return string
*/
public function getFournisseur()
{
return $this->Fournisseur;
}
}
Fournisseur entity:
<?php
namespace Ecommerce\UserBundle\Entity;
use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="Ecommerce_user")
*/
class User extends BaseUser
{
public function __construct()
{
parent::__construct();
$this->Produits = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\OneToMany(targetEntity="Ecommerce\boutiqueBundle\Entity\Produit",
* mappedBy="Fournisseur")
*/
protected $Produits;
public function addProduit(\Ecommerce\boutiqueBundle\Entity\Produit $Produit)
{
$this->Produits[] = $Produit;
$Produit->setCategorie($this);
}
public function getProduits()
{
return $this->Produits;
}
}

You have to specify the join condition within the leftJoin() call.
public function SearchByfournisseur($keyWord)
{
$qb = $this->createQueryBuilder('p')->distinct()->select('p');
$qb ->leftJoin('p.Fournisseur', 'f', 'WITH', $qb->expr()->eq('f.username = ?', $keyWord));
$products = $query->getResult();
return $products;
}
I suggest you to read the Doctrine documentation chapter dealing about the QueryBuilder.

Related

How to retrieve associated ManyToOne entity?

In controller I try to retrieve all order products:
$products = $this->getDoctrine()->getRepository('AppBundle:Ordr')->find(1)->getOrdrProducts();
var_dump($products);
... but $products contain no products.
I try to imitate this.
Entity\Ordr.php :
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Table(name="ordr")
* #ORM\Entity
*/
class Ordr
{
public function __construct()
{
$this->ordr_products = new ArrayCollection();
}
/**
* #ORM\Column(name="idOrdr", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $idordr;
/**
* #ORM\Column(type="string")
*/
private $name;
/**
* #ORM\OneToMany(targetEntity="OrdrProduct", mappedBy="ordr")
*/
protected $ordr_products;
/**
* #return \Doctrine\Common\Collections\Collection
*/
public function getOrdrProducts()
{
return $this->ordr_products;
}
public function getIdordr()
{
return $this->idordr;
}
public function addOrdrProducts(\AppBundle\Entity\OrdrProduct $ordrProducts)
{
$this->ordr_products[] = $ordrProducts;
return $this;
}
public function removeOrdrProducts(\AppBundle\Entity\OrdrProduct $ordrProducts)
{
$this->ordr_products->removeElement($ordrProducts);
}
}
Entity\OrdrProduct.php :
/**
* #ORM\Table(name="ordr_products", indexes={#ORM\Index(name="idOrdr_idx", columns={"idOrdr"})})
* #ORM\Entity
*/
class OrdrProduct
{
/**
* #ORM\Column(name="idOrdrProduct", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $idordrproduct;
/**
* #ORM\Column(type="string")
*/
private $name;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Ordr", inversedBy="ordr_products")
* #ORM\JoinColumn(name="idOrdr", referencedColumnName="idOrdr")
*/
private $ordr;
public function getIdordrproduct()
{
return $this->idordrproduct;
}
public function setOrdr(\AppBundle\Entity\Ordr $ordr = null)
{
$this->ordr = $ordr;
return $this;
}
public function getOrdr()
{
return $this->ordr;
}
}
My post is mostly code, I apologize for that. I dont know what to add more about the issue.
I can add something more about something else.
Hope this will help you:
Try this to get one order by id (with all order products related to it)
#AppBundle\Repository\OrderRepository.php
public function findOrderById($id)
{
$qb = $this->createQueryBuilder('o')
->join('o.ordr_products', 'r')
->addSelect('r')
->where('o.id = :id')
->setParameter(':id', $id)
;
return $qb->getQuery()
->getOneOrNullResult();
;
}

How to search ManyToOne side by OneToMany

I have Four Entities:
Batch
BachGroup
BachGroupApplication
Application
Entity 1(Batch) has OneToMany Bidirectional relationship with Entity 2(BatchGroup).
Entity 2(BatchGroup) has OneToMany Bidirectional relationship with Entity 3(BachGroupApplication).
Entity 3(BachGroupApplication) has ManyToOne Bidirectional relationship with Entity 4(Application).
DETAIL ON ABOVE ENTITIES:
Each batch has it's groups which i'm storing in bachGroup entity with batch reference column in it, now each batchGroup can have multiple applications so i have created BatchGroupApplication entity which holds reference to batchGroup and Application.
TODO:
I want to be able to search applications by individual batch group which i'm not able to do i searched the web and stackoverflow but failed to get it working! i don't know if my mind has stopped somewhere! my entities are listed below please help:
Batch Entity
<?php
namespace ModelBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Batch
*
* #ORM\Table(name="batch")
* #ORM\Entity(repositoryClass="ModelBundle\Repository\BatchRepository")
*/
class Batch
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
// ..............
/**
* If a Batch is removed all it's associated Groups will be deleted as well..
*
* #ORM\OneToMany(targetEntity="BatchGroup", mappedBy="batch", cascade={"remove"})
**/
private $batchGroups;
public function __construct() {
$this->batchGroups = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
// ...............
/**
* Add batchGroups
*
* #param \ModelBundle\Entity\BatchGroup $batchGroups
* #return Batch
*/
public function addBatchGroup(\ModelBundle\Entity\BatchGroup $batchGroups)
{
$this->batchGroups[] = $batchGroups;
return $this;
}
/**
* Remove batchGroups
*
* #param \ModelBundle\Entity\BatchGroup $batchGroups
*/
public function removeBatchGroup(\ModelBundle\Entity\BatchGroup $batchGroups)
{
$this->batchGroups->removeElement($batchGroups);
}
/**
* Get batchGroups
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getBatchGroups()
{
return $this->batchGroups;
}
}
BatchGroup Entity
<?php
namespace ModelBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* BatchGroup
*
* #ORM\Table(name="batch_group")
* #ORM\Entity()
*/
class BatchGroup
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=128)
*/
private $title;
/**
* #ORM\ManyToOne(targetEntity="Batch", inversedBy="batchGroups")
* #ORM\JoinColumn(name="batch_id", referencedColumnName="id")
**/
private $batch;
/**
* #ORM\OneToMany(targetEntity="BatchGroupApplication", mappedBy="batchGroup", cascade={"remove"})
**/
private $batchGroupApplications;
public function __construct() {
$this->batchGroupApplications = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
// ............
/**
* Set batch
*
* #param \ModelBundle\Entity\Batch $batch
* #return BatchGroup
*/
public function setBatch(\ModelBundle\Entity\Batch $batch = null)
{
$this->batch = $batch;
return $this;
}
/**
* Get batch
*
* #return \ModelBundle\Entity\Batch
*/
public function getBatch()
{
return $this->batch;
}
/**
* Add batchGroupApplications
*
* #param \ModelBundle\Entity\BatchGroupApplication $batchGroupApplications
* #return BatchGroup
*/
public function addBatchGroupApplication(\ModelBundle\Entity\BatchGroupApplication $batchGroupApplications)
{
$this->batchGroupApplications[] = $batchGroupApplications;
return $this;
}
/**
* Remove batchGroupApplications
*
* #param \ModelBundle\Entity\BatchGroupApplication $batchGroupApplications
*/
public function removeBatchGroupApplication(\ModelBundle\Entity\BatchGroupApplication $batchGroupApplications)
{
$this->batchGroupApplications->removeElement($batchGroupApplications);
}
/**
* Get batchGroupApplications
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getBatchGroupApplications()
{
return $this->batchGroupApplications;
}
}
BatchGroupApplication Entity
<?php
namespace ModelBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* BatchGroupApplication
*
* Table generated through this entity class will hold all application and can be filtered through BatchGroup
*
* #ORM\Table(name="batch_group_application")
* #ORM\Entity()
*/
class BatchGroupApplication
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="BatchGroup", inversedBy="batchGroupApplications")
* #ORM\JoinColumn(name="batch_group_id", referencedColumnName="id")
**/
private $batchGroup;
/**
* #ORM\ManyToOne(targetEntity="Application", inversedBy="batchGroupApplications")
* #ORM\JoinColumn(name="application_id", referencedColumnName="id")
**/
private $application;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set batchGroup
*
* #param \ModelBundle\Entity\BatchGroup $batchGroup
* #return BatchGroupApplication
*/
public function setBatchGroup(\ModelBundle\Entity\BatchGroup $batchGroup = null)
{
$this->batchGroup = $batchGroup;
return $this;
}
/**
* Get batchGroup
*
* #return \ModelBundle\Entity\BatchGroup
*/
public function getBatchGroup()
{
return $this->batchGroup;
}
/**
* Set application
*
* #param \ModelBundle\Entity\Application $application
* #return BatchGroupApplication
*/
public function setApplication(\ModelBundle\Entity\Application $application = null)
{
$this->application = $application;
return $this;
}
/**
* Get application
*
* #return \ModelBundle\Entity\Application
*/
public function getApplication()
{
return $this->application;
}
}
Application Entity
<?php
namespace ModelBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Application
*
* #ORM\Table(name="application")
* #ORM\Entity(repositoryClass="ModelBundle\Repository\ApplicationRepository")
*/
class Application
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
// ............
/**
* #ORM\OneToMany(targetEntity="BatchGroupApplication", mappedBy="application", cascade={"remove"})
**/
private $batchGroupApplications;
public function __construct()
{
$this->batchGroupApplications = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
// ............
/**
* Add batchGroupApplications
*
* #param \ModelBundle\Entity\BatchGroupApplication $batchGroupApplications
* #return Application
*/
public function addBatchGroupApplication(\ModelBundle\Entity\BatchGroupApplication $batchGroupApplications)
{
$this->batchGroupApplications[] = $batchGroupApplications;
return $this;
}
/**
* Remove batchGroupApplications
*
* #param \ModelBundle\Entity\BatchGroupApplication $batchGroupApplications
*/
public function removeBatchGroupApplication(\ModelBundle\Entity\BatchGroupApplication $batchGroupApplications)
{
$this->batchGroupApplications->removeElement($batchGroupApplications);
}
/**
* Get batchGroupApplications
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getBatchGroupApplications()
{
return $this->batchGroupApplications;
}
}
ApplicationRepository
Search function in this repository is being called from controller and from data is being sent to it via parameter that is in key value pair format, because form may have more properties so i'm checking if user is searching through batchGroup as well if yes it should combine the result from there as well.
namespace ModelBundle\Repository;
use Doctrine\ORM\EntityRepository;
/**
* ApplicationRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class ApplicationRepository extends EntityRepository
{
/**
* Search Applications
*
* data: search form data in key => value fashion
*
*
*/
public function search($data)
{
$em = $this->getEntityManager();
$applicationRepository = $em->getRepository('ModelBundle:Application');
$qb = $applicationRepository->createQueryBuilder('a');
foreach ($data as $field => $value) {
if($field=="batchGroupApplications"){
$qb->andWhere(":value_$field MEMBER OF a.batchGroupApplications")->setParameter("value_$field", $value);
}else{
$qb->andWhere("a.$field = :value_$field")->setParameter("value_$field", $value);
}
}
$query = $qb->getQuery();
$result = $query->getResult();
return $result;
}
}
Controller
Here i'm creating a search form with batchGroupApplications dropdown, where user will choose any batch group and submit the form, once submitted user should be able to see all applications which are in that group but i'm getting nothing!
namespace SISBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use ModelBundle\Entity\Batch;
use SISBundle\Form\BatchType;
use ModelBundle\Entity\Application;
use DefaultBundle\Form\ApplicationType;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use SISBundle\Form\SearchApplicationType;
use ModelBundle\Entity\Group;
use ModelBundle\Entity\BatchGroup;
/**
* Admission controller.
*
* #Route("/admission")
*/
class AdmissionController extends Controller
{
// ..............
/**
* List Applications for selected Batch
*
* #Route("/{batch}/applications")
*
* #Method({"GET", "POST"})
* #Template()
*/
public function applicationsAction(Request $request, Batch $batch)
{
$em = $this->getDoctrine()->getManager();
if( $batch != null ){
$applications = $batch->getApplications();
/*
* Search Applications
*
*/
$searchForm = $this->createForm(SearchApplicationType::class, null, array(
'action' => $this->generateUrl('sis_admission_applications', array('batch'=>$batch->getId())),
'method' => 'POST',
'attr' => array(
'novalidate' => 'novalidate',
'id' => 'sis_application_search_form',
),
));
// Manually Populating groups dropdown based on their availability for current loaded batch
$searchForm->add('batchGroupApplications', ChoiceType::class, array(
'choices' => $batch->getBatchGroups(),
'choices_as_values' => true,
'multiple'=>false,
'choice_label'=>'title',
'placeholder'=>' - Select Group..',
)
);
$searchForm->handleRequest($request);
if ($searchForm->isSubmitted()) {
// data is an array with "firstname", "middlename", and "lastname" keys etc
$data = $searchForm->getData();
$applications = $em->getRepository('ModelBundle:Application')->search($data);
}
/*********************************** end: Search Applications ***************************************/
return array(
'batch' => $batch,
'applications' => $applications,
'searchForm' => $searchForm->createView(),
);
}
}
}
Again, please suggest how can i search applications through batchGroup in andWhere fashion as search form may have some more fields which are available in application entity, for other fields it's working fine but this search by BatchGroup is somewhat tricky may be because of complicated associations etc.
Looking forward to solution..

dql query error class is not defined

Trying to conver my sql queries into dql, seems im doing something wrong.
I need basic joins, something like this.
SELECT a.id, a.title, u.name FROM articles JOIN users ON a.author_id = u.id
Tried
SELECT a.id, a.title, u.name FROM Article a JOIN User u WITH a.author_id = u.id
Getting error
[Semantical Error] line 0, col 34 near 'Article a JOIN': Error: Class 'Article' is not defined.
How should i define? Could you give me please a right solution?
Edit:
Article Entity
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="articles")
*/
class Article
{
/**
* #var integer $id
*
* #ORM\Id
* #ORM\Column(name="id", type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string")
*/
protected $title;
/**
* #ORM\Column(type="integer", name="author_id")
*/
protected $authorId;
/**
* #ORM\Column(type="datetime", name="creation_date")
*/
protected $creationDate;
/**
* #ORM\Column(type="string", name="short_content")
*/
protected $shortContent;
/**
* #ORM\Column(type="string")
*/
protected $content;
public function getId()
{
return $this->id;
}
public function getTitle()
{
return $this->title;
}
public function getAuthorId()
{
return $this->authorId;
}
public function getCreationDate()
{
return $this->creationDate;
}
public function getShortContent()
{
return $this->shortContent;
}
public function getContent()
{
return $this->content;
}
}
User Entity
<?php
namespace AppBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="bigint")
*/
protected $phone;
/**
* #ORM\Column(type="string")
*/
protected $gender;
/**
* #ORM\Column(type="string")
*/
protected $about;
public function getPhone()
{
return $this->phone;
}
public function getGender()
{
return $this->gender;
}
public function getAbout()
{
return $this->about;
}
}
Refer to the entities in your DQL by their namespaces, i.e. AppBundle:Article and AppBundle:User, that should make the error go away.
Use association mapping (old docs) instead of authorId in your entity, this way Doctrine will take care of loading the author:
/**
* #ORM\ManyToOne(targetEntity="User")
* #ORM\JoinColumn(name="author_id", referencedColumnName="id")
**/
private $author;
public function getAuthor() {
return $this->author;
}
public function setAuthor($author) {
$this->author = $author;
}
Your query would be reduced to:
SELECT a FROM AppBundle:Article a ORDER BY a.creationDate DESC
Once you have loaded an article, you can conveniently access the author:
...
$author = $article->getAuthor();

Symfony 2 many to one cannot null

I have :
An exception occurred while executing 'INSERT INTO image (image_name, artiste_id) VALUES (?, ?)' with params ["537bd9df69db9.png", null]:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'artiste_id' cannot be null
I have a many-to-one relationship with the companies 'image' and 'artist'. I do not really see where the problem is.
My entity Image :
<?php
namespace Acme\ArtisteBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Acme\ArtisteBundle\Entity\Artiste;
/**
* Acme\ArtisteBundle\Entity\Image
*
* #ORM\Table(name="image")
* #ORM\Entity(repositoryClass="Acme\ArtisteBundle\Entity\ImageRepository")
* #ORM\HasLifecycleCallbacks
* #Vich\Uploadable
*/
class Image
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #Assert\File(
* maxSize="1M",
* mimeTypes={"image/png", "image/jpeg", "image/pjpeg"}
* )
* #Vich\UploadableField(mapping="product_image", fileNameProperty="imageName")
*
* #var File $image
*/
public $image;
/**
* #var string $imageName
* #ORM\Column(type="string", length=255, name="image_name", type="integer", nullable=false)
*/
protected $imageName;
/**
* #ORM\ManyToOne(targetEntity="Acme\ArtisteBundle\Entity\Artiste", inversedBy="image", cascade={"remove"})
* #ORM\JoinColumn(name="artiste_id", referencedColumnName="id", nullable=false)
*/
private $artiste;
/**
* Set artiste
*
* #param \Acme\ArtisteBundle\Entity\Artiste $artiste
*/
public function setArtiste(\Acme\ArtisteBundle\Entity\Artiste $artiste)
{
$this->artiste = $artiste;
}
/**
* Get artiste
*
* #return \Acme\ArtisteBundle\Entity\Artiste
*/
public function getArtiste()
{
return $this->artiste;
}
/**
* #param File|\Symfony\Component\HttpFoundation\File\UploadedFile $image
*/
public function setImage(File $image)
{
$this->image = $image;
}
/**
* Get Image
* #return File
*/
public function getImage()
{
return $this->image;
}
/**
* #param string $imageName
*/
public function setImageName($imageName)
{
$this->imageName = $imageName;
}
/**
* #return string
*/
public function getImageName()
{
return $this->imageName;
}
}
and my entity Artiste
<?php
namespace Acme\ArtisteBundle\Entity;
use FOS\UserBundle\Entity\User as BaseUser;
use Acme\ArtisteBundle\Entity\Image;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* Artiste
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="Acme\ArtisteBundle\Entity\ArtisteRepository")
* #ORM\HasLifecycleCallbacks()
*/
class Artiste extends BaseUser
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
*
* #ORM\Column(name="valideAdmin", type="boolean", nullable=true)
*/
private $valideAdmin = '0';
/**
* #ORM\OneToMany(targetEntity="Acme\ArtisteBundle\Entity\Image", mappedBy="artiste", cascade={"persist", "remove"})
*/
protected $image;
public function __construct()
{
trigger_error(sprintf('%s is deprecated. Extend FOS\UserBundle\Model\User directly.', __CLASS__), E_USER_DEPRECATED);
parent::__construct();
$this->image = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get image
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getImage() {
return $this->image;
}
/**
* Set image
*
* #param \Doctrine\Common\Collections\Collection $image
*/
public function setImage(\Doctrine\Common\Collections\Collection $image)
{
$this->image = $image;
}
/**
* Add image
*
* #param \Acme\ArtisteBundle\Entity\Image $image
*/
public function addImage(\Acme\ArtisteBundle\Entity\Image $image)
{
$this->image[] = $image;
}
/**
* Remove image
*
* #param \Acme\ArtisteBundle\Entity\Artiste $image
*/
public function removeImage(\Acme\ArtisteBundle\Entity\Artiste $image)
{
$this->image->removeElement($image);
}
}
and my register action of FOS
namespace Unikness\ArtisteBundle\Controller;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Event\FormEvent;
use FOS\UserBundle\Event\GetResponseUserEvent;
use FOS\UserBundle\Event\UserEvent;
use FOS\UserBundle\Event\FilterUserResponseEvent;
use Symfony\Component\DependencyInjection\ContainerAware;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use FOS\UserBundle\Model\UserInterface;
use Acme\ArtisteBundle\Entity\Image;
use FOS\UserBundle\Controller\RegistrationController as BaseController;
class RegistrationController extends ContainerAware
{
public function registerAction(Request $request)
{
/** #var $formFactory \FOS\UserBundle\Form\Factory\FactoryInterface */
$formFactory = $this->container->get('fos_user.registration.form.factory');
/** #var $userManager \FOS\UserBundle\Model\UserManagerInterface */
$userManager = $this->container->get('fos_user.user_manager');
/** #var $dispatcher \Symfony\Component\EventDispatcher\EventDispatcherInterface */
$dispatcher = $this->container->get('event_dispatcher');
$user = $userManager->createUser();
$user->setEnabled(true);
$event = new GetResponseUserEvent($user, $request);
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_INITIALIZE, $event);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
$form = $formFactory->createForm();
$form->setData($user);
$image = new Image();
if ('POST' === $request->getMethod()) {
$form->bind($request);
if ($form->isValid()) {
$event = new FormEvent($form, $request);
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event);
$userManager->updateUser($user);
$image->setArtiste($user);
$em = $this->container->get('doctrine')->getEntityManager();
$em->persist($image);
$em->flush();
if (null === $response = $event->getResponse()) {
$url = $this->container->get('router')->generate('fos_user_registration_confirmed');
$response = new RedirectResponse($url);
}
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response));
return $response;
}
}
return $this->container->get('templating')->renderResponse('FOSUserBundle:Registration:register.html.'.$this->getEngine(), array(
'form' => $form->createView(),
));
}
I have persisted but I always null. Any help would be appreciated :)
Try adding "persist" option in ManyToOne annotation
/**
* #ORM\ManyToOne(targetEntity="Acme\ArtisteBundle\Entity\Artiste", inversedBy="image", cascade={"remove","persist"})
* #ORM\JoinColumn(name="artiste_id", referencedColumnName="id", nullable=false)
*/
private $artiste;
To ensure bidirectional relation there is a trick :
in your class Artiste, modify your setter setImage like this :
public function setImage(\Doctrine\Common\Collections\Collection $image)
{
foreach ($image as $img) {
$img->setArtiste($this);
}
$this->image = $image;
}
Further more, just for a better read of your code, I recommend to rename "image" field in your class Artiste to "images" as this field is a collection of entities Image.
I also read in this post doctrine2: in a one-to-many bidirectional relationship, how to save from the inverse side? that you can do like this (choose on of these two solutions, this second solution is interesting if you create Images, and then attach Artiste to the Image created = "save from the inverse side") :
in your class Image modify the setter setArtiste like this :
public function setArtiste($artiste)
{
$this->artiste = $artiste;
$artiste->addImage($this);
}
This should work
public function addImage(\Acme\ArtisteBundle\Entity\Image $image)
{
if(!$this->image->contains($image)){
$this->image[] = $image;
$image->setArtiste($this);
}
}

Little innerJoin-Query

Old Query in symfony 1.4 and doctrine 1.2
$user = Doctrine_Query::create()
->from('User.u')
->innerJoin('u.State s')
->where('u.id = ?', $id)
->andWhere('u.state_id = ?', $state_id)
->fetchOne();
Now my Query in symfony2:
$repository = $this->getDoctrine()
->getRepository('FrontendAccountBundle:User');
$user = $repository->findBy(array(
'activationId' => $activation_id),
array('state' => 3));
My error is comming up:
Unrecognized field: state
What is the problem?
Edit: reformatted code
Update
User-Entity:
namespace Frontend\AccountBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* User
*
* #ORM\Table(name="user")
* #ORM\Entity
*/
class User implements UserInterface, \Serializable
{
/**
* #var string
*
* #ORM\Column(name="activation_id", type="string", length=255, nullable=true)
*/
private $activationId;
/**
* #var \State
*
* #ORM\ManyToOne(targetEntity="State")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="state_id", referencedColumnName="id")
* })
*/
private $state;
/**
* Set activationId
*
* #param string $activationId
* #return User
*/
public function setActivationId($activationId)
{
$this->activationId = $activationId;
return $this;
}
/**
* Get activationId
*
* #return string
*/
public function getActivationId()
{
return $this->activationId;
}
/**
* Set state
*
* #param \Frontend\AccountBundle\Entity\State $state
* #return User
*/
public function setState(\Frontend\AccountBundle\Entity\State $state = null)
{
$this->state = $state;
return $this;
}
/**
* Get state
*
* #return \Frontend\AccountBundle\Entity\State
*/
public function getState()
{
return $this->state;
}
public function __construct()
{
$this->isActive = true;
$this->salt = md5(uniqid(null, true));
}
/**
* #inheritDoc
*/
public function getUsername()
{
return $this->email;
}
/**
* #see \Serializable::serialize()
*/
public function serialize()
{
return serialize(array(
$this->id,
));
}
/**
* #see \Serializable::unserialize()
*/
public function unserialize($serialized)
{
list (
$this->id,
) = unserialize($serialized);
}
}
User-Entity:
namespace Frontend\AccountBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* State
*
* #ORM\Table(name="state")
* #ORM\Entity
*/
class State
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="state", type="string", length=255, nullable=false)
*/
private $state;
/**
* #var string
*
* #ORM\Column(name="description", type="string", length=255, nullable=false)
*/
private $description;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set state
*
* #param string $state
* #return State
*/
public function setState($state)
{
$this->state = $state;
return $this;
}
/**
* Get state
*
* #return string
*/
public function getState()
{
return $this->state;
}
/**
* Set description
*
* #param string $description
* #return State
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
}
The problem is that the variable in the User entity is "state" not "stateId". You must always use the names from the entity, not the database. The join from User to State also needs to be done since the stateId is in the State entity.
When joins are needed you are probably better off using queryBuilder or DQL.
Here's a post about joins in Doctrine 2 queryBuilder: doctrine 2 query builder and join tables
Here's the documentation from the Symfony Book for Doctrine: http://symfony.com/doc/current/book/doctrine.html#entity-relationships-associations
Here's an example from my project that is very similar to your problem:
$uid = 2;
$rep = $this->getDoctrine()->getRepository('DevondevTrackRTimeBundle:Activity');
$q = $rep->createQueryBuilder('a')
->select ('a.activityId, a.startTime, a.endTime, u.username')
->join('a.login','u')
->where('u.id = :uid')
->setParameter('uid', $uid)
->getQuery();
$acts = $q->getResult();
If I didn't need anything from the user table the query could be written as
$uid = 2;
$rep = $this->getDoctrine()->getRepository('DevondevTrackRTimeBundle:Activity');
$q = $rep->createQueryBuilder('a')
->where('a.login = :uid')
->setParameter('uid', $uid)
->getQuery();
$acts = $q->getResult();
This is your query reworked in the same way:
$rep = $this->getDoctrine()->getRepository('FrontendAccountBundle:User');
$q = $rep->createQueryBuilder('u')
->join('u.state','s')
->where ('u.id = :uid')
->andWhere ('s.stateId = :sid')
->setParameters(array('uid' => $id, 'sid' => $state_id))
->getQuery();
$user = $q->getSingleResult();
Thanks to Peter to light me up a little bit!!!
If you don't want again a the stupid solution from symfony2(-docs) and doctrine2, because you need much more code than in symfony1.4, like that way http://symfony.com/doc/current/book/doctrine.html#joining-to-related-records. Try my solution.
Here is the result.
$em = $this->getDoctrine()->getEntityManager();
$user = $em->createQuery('SELECT u FROM FrontendAccountBundle:User u
INNER JOIN FrontendAccountBundle:State s
WHERE
u.activation_id=:activation_id
and
u.state=:state_id
')
->setParameter('activation_id', $activation_id)
->setParameter('state_id', 3)
->getSingleResult();

Resources