Symfony: how to sort One2Many/Many2One of an entity? - php

I've three entities: Product, ProductPicture and Picture.
I'd like to sort the pictures by it's position and tried this, code below.
Result: it's not sorting the joined pictures by position. It's sorting the products by the pictures' position.
I'm confused. As far as I can see, I followed the docs, but get a weird result. Cache was cleared.
Any ideas? Thanks in advance!
Entity: Product
// ...
class Product {
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue
*/
protected $id;
/**
* #ORM\OneToMany(targetEntity="ProductPicture", mappedBy="product")
* #ORM\OrderBy({"position" = "DESC"}) // <------ !!!
*/
protected $pictures;
// ...
}
Entity: ProductPicture
// ...
class ProductPicture {
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue
*/
protected $id;
/**
* #ORM\Column(type="integer")
*/
protected $position;
/**
* #ORM\ManyToOne(targetEntity="Product", inversedBy="pictures")
* #ORM\JoinColumn(name="product_id", referencedColumnName="id")
*/
protected $product;
/**
* #ORM\ManyToOne(targetEntity="Picture")
* #ORM\JoinColumn(name="picture_id", referencedColumnName="id")
*/
protected $picture;
// ...
}
Entity: Picture
// ...
class Picture {
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue
*/
protected $id;
/**
* #ORM\Column(name="path", type="string")
*/
protected $path;
// ...
}

The docs are right:
<?php
/** #Entity **/
class User
{
// ...
/**
* #ManyToMany(targetEntity="Group")
* #OrderBy({"name" = "ASC"})
**/
private $groups;
}
In my case the findAll()-method of the repository was overwritten which led to this mess. Make sure, your customized queries are not in conflict with the doctrine defaults, if you've the same issue. :-)

Related

Relationship ManyToMany, the extra field ignored

I have a problem certainly very stupid .
I have 3 entities : activity , category and categorieActivite which the following codes :
/**
* Class Activite
* #ORM\Entity
* #ORM\Table(name="activite")
*/
class Activite{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string",length=255)
*/
protected $nom;
/**
* #ORM\OneToMany(targetEntity="CategorieActivite",mappedBy="activite")
*/
protected $categorieList;
}
class Categorie{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string",length=255)
*/
protected $nom;
/**
* #ORM\OneToMany(targetEntity="CategorieActivite",mappedBy="categorie")
*/
protected $activiteList;
}
class CategorieActivite{
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Categorie",inversedBy="activiteList")
* #ORM\JoinColumn(name="categorie_id", referencedColumnName="id", nullable=false)
*/
protected $categorie;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Activite",inversedBy="categorieList")
* #ORM\JoinColumn(name="activite_id", referencedColumnName="id", nullable=false)
*/
protected $activite;
/**
* ORM\Column(type="string",length=50)
* #Assert\Choice(choices = {"Intense", "Douce", "Moyenne"}, message = "Veuillez choisir une valeur")
* #Assert\NotNull()
*/
protected $intensite;
}
So far all working properly. But the problem is that the intensity of CategorieActivite entity does not appear in the database , there are only foreign keys that appear. Do you have an idea of the problem?
Thank you in advance for your help.
Thibault.
On your $intensite property
* ORM\Column(type="string",length=50)
Should be:
* #ORM\Column(type="string",length=50)
Pretty sure that'll fix it for you. You'll need to run a doctrine:migrations:diff once you fix the annotation.

Symfony ManyToOne Form add, delete in DB

I have entity developer and comment and relationship Many comment to One developer. And I need form when I see all comment for developer and edit - add, delete in DB . What are the solutions to this problem
entity Comment:
class Comments
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Developer", inversedBy="comments")
* #ORM\JoinColumn(name="talent_id", nullable = true, referencedColumnName="id")
* */
protected $talent;
/**
* #var string
*
* #ORM\Column(name="added_by", type="string", length=10, nullable=true)
*/
private $added_by;
/**
* #var string
*
* #ORM\Column(name="comment", type="string", length=10, nullable=true)
*/
private $comment;
entity Developer:
class Developer extends CustomUser
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/////
/**
* #ORM\OneToMany(targetEntity="Comments", mappedBy="talent", cascade={"persist", "remove"})
*/
protected $comments;
Maybe need form in form but how to do this?
You are looking for field type collection.
Example usage of collection type
class Comments
{
....
/**
*
*#ORM\ManyToOne(targetEntity="Developer", inversedBy="developer_to_comments")
* #ORM\JoinColumn(name="developer_to_comments_id", referencedColumnName="id", nullable=false)
*
*/
private $comments_to_developer;
...
}
And class Developer
class Developer extends CustomUser
{
....
/**
*
* #var ArrayCollection
* #ORM\OneToMany(targetEntity="Comments", mappedBy="comments_to_developer", cascade={"remove"})
*/
private $developer_to_comments;
public function __construct()
{
$this->developer_to_comments = new ArrayCollection();
}
....
}
And don't forget use Doctrine\Common\Collections\ArrayCollection

Nested jointable joincolumns in symfony 2 with doctrine 2

So given the entity Comment, what is the cleanest way to get the CommentPerson to find out if the CommentPerson isModerator()?
Without getting your fingers dirty using a repository.
/**
* #ORM\Entity(repositoryClass="MyApp\MyBundle\Repository\CommentRepository")
* #ORM\Table(name="comment")
*/
class Comment
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="integer")
*/
protected $user_id; //id of entity User
/**
* #ORM\ManyToOne(targetEntity="User")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
**/
protected $user; //a user can have many comments
/**
* #ORM\Column(type="text")
*/
protected $commentText;
}
/**
* #ORM\Entity(repositoryClass="MyApp\MyBundle\Repository\UserRepository")
* #ORM\Table(name="user")
*/
class User //this is the web user
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="integer")
*/
protected $person_id; //id of entity Person
/**
* #ORM\ManyToOne(targetEntity="Person")
* #ORM\JoinColumn(name="person_id", referencedColumnName="id")
**/
protected $person; //many web users can map to one actual person
public function getPerson()
{
return $this->person;
}
}
/**
* #ORM\Entity(repositoryClass="MyApp\MyBundle\Repository\PersonRepository")
* #ORM\Table(name="person")
*/
class Person
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="text")
*/
protected $email;
/**
* #ORM\OneToMany(targetEntity="CommentPerson", mappedBy="person")
* #ORM\JoinColumn(name="id", referencedColumnName="person_id")
*/
private $commentPersons; //one person can have many commentPersons (since one person can be part in many different comment sections, not shown in code here, but take it as a fact)
}
/**
* #ORM\Entity(repositoryClass="MyApp\MyBundle\Repository\CommentPersonRepository")
* #ORM\Table(name="comment_Person")
*/
class CommentPerson
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="integer")
*/
protected $person_id; //this is the id of the entity Person
/**
* #ORM\Column(type="boolean")
*/
protected $isModerator;
}

Doctrine2 cascade delete doesn't work with Abstract Class

In my web application, which is built with Symfony2, contains the following entities:
/**
* #ORM\Entity
* #ORM\Table
*/
class Entity
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(name="id", type="integer")
*/
private $id;
/**
* #ORM\OneToMany(targetEntity="MappedSuperclass", mappedBy="entity", cascade={"persist", "remove"})
*/
private $mappedSuperclasses;
}
/**
* #ORM\MappedSuperclass
*/
abstract class MappedSuperclass
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(name="id", type="integer")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="Entity", inversedBy="mappedSuperclasses")
* #ORM\JoinColumn(name="entity_id", referencedColumnName="id", nullable=false)
*/
protected $entity;
}
/**
* #ORM\Entity
* #ORM\Table(name="table_1")
*/
class Subclass1 extends MappedSuperclass
{
/**
* #ORM\Column(name="unique_member", type="string")
*/
private $uniqueMember;
}
/**
* #ORM\Entity
* #ORM\Table(name="table_2")
*/
class Subclass2 extends MappedSuperclass
{
/**
* #ORM\Column(name="unique_member", type="string")
*/
private $uniqueMember; // This is different from Subclass1
}
I'll explain this a bit. An Entity has a collection of MappedSuperclass. MappedSuperclass is an abstract class which contains some common variables for its subclasses. Subclass1 and Subclass2 are subclasses of MappedSuperclass. When an Entity is removed from database, the items in $mappedSuperclasses should be removed together, that's why the cascade={"persist", "remove"} is set.
However, when I try to delete an Entity, I got the following error:
ContextErrorException: Notice: Undefined index: entity in C:\project\vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\BasicEntityPersister.php line 1753
If I change the targetEntity of Entity::$mappedSuperclasses to Subclass1 or Subclass2, it will work. Is my set up impossible to achieve ON DELETE CASCADE? What am I missing?
I solved this problem by setting the ON DELETE action to database level:
/**
* #ORM\Entity
* #ORM\Table
*/
class Entity
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(name="id", type="integer")
*/
private $id;
}
/**
* #ORM\MappedSuperclass
*/
abstract class MappedSuperclass
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(name="id", type="integer")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="Entity")
* #ORM\JoinColumn(name="entity_id", referencedColumnName="id", nullable=false, onDelete="CASCADE")
*/
protected $entity;
}
Sources: [1] [2]
Im answering year after the issue was resolved but I had the same problem. Error occurs when I tried to empty count arrayCollection.
So the solution was to check if $this->entity is array and then return its length.

OneToOne relationship in Doctrine2 ORM and Symfony

I have two entity called PictureTag and Tag, here's the relationship:
/**
* #ORM\Entity
* #ORM\Table(name="picture_tag")
* #ORM\HasLifecycleCallbacks()
*/
class PictureTag
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
*
* #ORM\OneToOne(targetEntity="App\MainBundle\Entity\Tag", inversedBy="id")
* #ORM\JoinColumn(name="tag_id", referencedColumnName="id", nullable=false)
*/
private $tag;
}
/**
* #ORM\Entity
* #ORM\Table(name="tag")
* #ORM\HasLifecycleCallbacks()
*/
class Tag
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\ManyToOne(targetEntity="App\MainBundle\Entity\PictureTag", inversedBy="tag")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
* #ORM\Column(name="tag", type="string", nullable=true)
*/
private $tag;
}
Basically I wanted the tag table to contain all the unique tags, so there are no duplicate in the tag. And i wanted picturetag to have a joincolumn that points to the id of the tag. So here's my code in the controller:
foreach ($image->tags as $tag) {
$existingTag = $em->getRepository('AppMainBundle:InstagramTag')->findOneByTag($tag);
$instaPictureTag = new PictureTag();
if ($existingTag) {
$instaPictureTag->setTag($existingTag);
} else {
$instagramTag = new Tag();
$instagramTag->setTag($tag);
$em->persist($instagramTag);
$instaPictureTag->setTag($instagramTag);
}
$instaPictureTag->setPicture($instaShopPicture);
$em->persist($instaPictureTag);
}
So the relationship is basically:
One picture is going to have many tags. And one tag will belong to many pictures.
Picture tag here is the intermediary table.
Basically I am doing a check if the tag already exists in the tag table, if it is then I set the picturetag to be associated with this tag, if not then create one. However doing so generates the following error:
Fatal error: Call to a member function setValue() on a non-object in /Users/MyName/Sites/App/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php on line 2625
Any idea why this is?
As I understand, you want implement OneToMany bidirectional relation between PictureTag and Tag.
Please try:
/**
* #ORM\Entity
* #ORM\Table(name="picture_tag")
* #ORM\HasLifecycleCallbacks()
*/
class PictureTag
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="DynamicSolutions\Bundle\ProsAndConsBundle\Entity\Tag", inversedBy="pictureTags")
* #ORM\JoinColumn(name="tag_id", referencedColumnName="id", nullable=false)
*/
private $tag;
}
/**
* #ORM\Entity
* #ORM\Table(name="tag")
* #ORM\HasLifecycleCallbacks()
*/
class Tag
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\OneToMany(targetEntity="PictureTag", mappedBy="tag")
*/
private $pictureTags;
/**
* #var string
* #ORM\Column(name="tag", type="string", nullable=true)
*/
private $tag;
}

Categories