Whats is the use of annotation group in doctrine - php

I am new to doctrine, In my symfony project all the entity annotation linked with groups but I am not getting what is the use of Groups.
/**
* #ORM\Column(type="string", length=64)
* #Groups({"public","details"})
*/
I have newly added the field in my entity file, while executing the schema update getting (newly added field) was never imported.
What is groups and how it's useful.

Groups is not part of doctrine, and is not necessary unless you need serialize objects to use json or xml (Rest API, etc)
http://symfony.com/doc/current/components/serializer.html#attributes-groups
http://symfony.com/blog/new-in-symfony-2-7-serialization-groups

It allows to serialize just selected group of attributes (eg. to skip internal ones).
Read more here: http://symfony.com/blog/new-in-symfony-2-7-serialization-groups

Related

"Real" orphan removal with Doctrine/MySQL

I have two entities linked together by a ManyToMany relationship in a Doctrine/MySQL project.
A Client entity:
class Client
{
[...]
/**
* #ORM\ManyToMany(targetEntity="ClientTag")
* #ORM\JoinTable(name="clients_tags")
*/
protected $tags;
}
And a ClientTag entity:
class ClientTag
{
[...]
/**
* #ORM\Column(type="string", length=45)
*/
protected $label;
/**
* #ORM\Column(type="string", length=7)
*/
protected $color;
}
So I have the ability to associate multiple clients to one tag, and vice-versa, great.
But I can't find a way to automatically remove a tag when there is no more clients referencing it.
I tried to use orphanRemoval on the ManyToMany annotation but it doesn't do what I thought.. Orphan removal should imply exactly what I described above but it removes the tag when the reference to its parent is removed, not considering other entities like I need to.
If a client removes a tag but this tag is still used by 2 other clients, I don't consider it "orphan" as it still has one or more entities referencing it.
Of course I could solve the case by doing a query and removing it myself if I don't find any parent, but I wonder if Doctrine or MySQL have a built in way to do this (that will be far more optimized) ?
Any idea?
Thanks for your help.
Officially orphanRemoval isn't supported for ManyToMany relations in doctrine.
http://docs.doctrine-project.org/en/latest/reference/annotations-reference.html#annref-manytomany
The orphan removal in this case is ambiguous.
You can either just understand the relations (the jointable entries) to the deleted entity as the orphans or the related entity.
From a database point of view it would be the jointable entries.
From an ORM point of view it's the related entities.
Thing is both ways are correct depending on the use case. For example in an Article <-> Category relation you would want to remove the article from all associated categories on deletion, but you wouldn't want to throw away the whole category just because it's empty at this moment.
I'm guessing that's the reason why Doctrine doesn't officially mention the orphanRemoval option for ManyToMany because it's unclear and to fully support both variants the current implementation isn't enough.
Hope that was somehow understandable.
In your case though you'll probably need to clean up unused tags yourself.

How can I implement a Zend Form entity with an array of elements, using Annotations?

I have a need for a form to record "sets of data", where each set consists of a few numbers. User has an option to add additional sets, up to however many is needed. In some cases up to 70 such sets are entered, introducing a need for an array.
Looking up Zend Form, I liked the approach where a form is created using the Annotations feature (https://docs.zendframework.com/zend-form/quick-start/#using-annotations), since it gives me a neat "object", which I can use for things like saving it directly to the database via i.e. using Doctrine, and then also retrieving it.
Question
How can I define a form in PHP using Zend Form, where the form has expandable set of elements, where I can manage that entity using Doctrine?
Use
/**
* #Annotation\ComposedObject({
* "target_object":"Namespace\Entity\ElementInput",
* "is_collection":"true"
* });
*
* #var ElementInput[]
*/
private $elements;
Later to define the number of elements to show:
$form->get("elements")->setCount($count);

Doctrine ORM ArrayCollection in PostgreSQL

I noticed some weird things using Doctrine ORM's ArrayCollection in a PostgreSQL database (using this in a Symfony 3 project).
Take my User class with roles, It's initiated with a default role ROLE_USER and must be of type array.
class User implements UserInterface, Serializable
{
/**
* #var ArrayCollection
*
* #ORM\Column(name="roles", type="array")
*/
private $roles;
public function __construct()
{
$this->roles = new ArrayCollection();
$this->roles->add('ROLE_USER');
}
}
This is stored in the database as follows.
O:43:"Doctrine\Common\Collections\ArrayCollection":1:{s:53:"
Which will give a Serialization error when trying to logon as a User because clearly part of the ArrayCollection is missing in the database.
After googling for a solution I came across this Github issue. As I understand it, it's a bug and you can't use the ArrayCollection in a PostgreSQL environment.
Not defining the type in the #ORM\Column tag doesn't help either, it then stores the following in the database and Symfony can't work with it to retrieve roles. Doctrine\Common\Collections\ArrayCollection#000000002300d10300000000545301a6
And using simple_array or json as type doesn't return an object so both are no-go's
Does anyone have a workaround or solution for this? I'm really starting to regret switching from MySQL to PostgreSQL
NOTE: the code was working fine in MySQL, I just switched databases.
You can always create your own mapping-type specially for ArrayCollection properties. The Doctrine DBAL docs and ORM cookbook describe how to create one. The Symfony documentation describes how to activate/register it.
You could for example extract the array and json-encode it when converting to a DB value:
json_encode($value->toArray())
And json-decode and wrap it back into an ArrayCollection when converting to a PHP value:
new ArrayCollection(json_decode($value))
But it's your mapping type, you can do whatever you want :)
I also had this problem myself, I'm not sure exactly why postgresql truncates the serialized string, even tho the field is marked as text. My suggestion is that you convert the column type to json_array because postgresql has a native type for that. Else you can also use custom types which

Best Way To Handle Removing Records in Symfony2

I have a lot of entities that have ManyToOne and OneToMany associations in Symfony2. As all know if you remove a record and it doesnt set a null value on the association in the other tables, things start to go haywire. So, what is the best way in Symfony2 to handle setting the value as null in other tables when a record is removed in Symfony2?
What do I need to set in my entities to ensure it persists across all associations.
First of all you can manually set ON DELETE behavior for the FK by using onDelete property for the joinColumn annotation in your entity:
/**
* #OneToOne(targetEntity="SomeEntity")
* #JoinColumn(name="some_entity_id", referencedColumnName="id", onDelete="cascade")
*/
private $someEntity;
Secondly, you always can implement event listener for the entity removing event. For example:
public function preRemove(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
if (!$entity instanceof SomeEntity) {
return;
}
// Here you can do whatever you want before
// entity record is removed from the DB.
}
You can read about the doctrine event system using following links:
Doctrine events (official manual)
How to Register Doctrine Event Listeners and Subscribers (Symfony2 cookbook)
The difference between them is that the first method works on the database layer. In other words, it would work even if you delete record using raw sql query in the console. Second one is more powerfull because you can also run any php code when entity is removed (for example you can send emails, etc.) but it will only be fired if record is removed via doctrine.

Doctrine possible to reverse engineer inverse associations?

I have database with about 100 tables and I'm using Doctrine 2 as my Data Mapper. I successfully generated entities for my tables, however, I noticed that many-to-one relationships didn't generate bidirectionally. Only many-to-one part of the relation generates, the one-to-many does not.
For instance in my Company entity I have
/**
* #var \User
*
* #ManyToOne(targetEntity="User")
* #JoinColumns({
* #JoinColumn(name="user_id", referencedColumnName="id")
* })
*/
private $user;
but I don't have anything pointing to the Company entity in User.
I am aware that Doctrine doesn't do this OOTB it says so in their documentation but I was wondering if there is a way to get around this limitation.
Writing 300+ relations by hand is a task I don't want to undertake.
Is there perhaps an alternative Data Mapper library for PHP that can solve this for me?
Thanks in advance.
I ended up using Propel because it generated everything wonderfully, albeit I ended up with some very large files (14k LoC).
It seems there simply isn't a PHP ORM that does everything right.

Categories