Simplify Doctrine code in Controller - symfony

(sorry for my bad english)
I'm a newbie to Symfony2/Doctrine, and currently doing my first project. Is there a way to simplify the below code?
I have two Entities, one contains Orders and other entity that contain Order Status (NEW, IN PROGRESS, SENT, ....). Order have a field 'Status' which is one to many with the 'Status' id field in Status entity.
When I create a new Order, I must assign a status to the order, with this code:
$order = new Order();
$order->setStatus($this->getDoctrine()->getEntityManager()->getRepository('OrderBundle:Status')->findOneByStatus(0));
'0' means for status 'NEW'. I think that this code can be simplified, but can't find how to do this.
Any ideas ?
Thanks!

What you need is to introduce relations between entities (many-to-one, for example). Check official Doctrine documentation.
Another option, if you don't want to limit your entities with relations, you may put the logic into custom entity repositories. This will reduce the amount of code a bit.

Related

Symfony CollectionType update Entities

I can't believe this hasn't come up for other people, but I'm unable to find a solution.
Let's say I have two entity types, A and B with a one-to-many relationship. A has a collection of Bs.
The form for A has a CollectionType for the Bs, with a custom entry_type for B, allow_add and allow_delete set to true. When the form is created/populated/rendered, the Bs' fields are identified by their index in the collection. When the form is posted back, the fields are mapped back onto the B entities according to the index again.
What if the database in the mean time decided to return the Bs in a different order? Then the values get swapped around on the Bs! I can't have that, as other entities will reference the Bs and now they've changed their meaning!
Even if the database doesn't change the order, the same issue appears when a B is deleted: The fields get shifted through the Bs and a different one deleted! (Ok, I'm not a 100% certain this happens, as there's a gap then in the numbering of the posted fields.) I've found this similar question where it does happen when another one is created (Symfony CollectionType regards deletion+creation as a modification of an item), but that sort of drifted from the issue and there's no usable answer.
How do I make sure the form is updating the entities the user actually edited?
I already tried to render the Bs' IDs as a HiddenType, but then the form rightfully complains that the ID has no setter. It would probably force an ID on the wrong B anyways and Doctrine doesn't like that. I suppose I could add the Bs as unmapped and copy the values over to the correct objects manually, but that would defeat a good chunk of Symfony's form system.
I've used CollectionType before, but not for entities that are referenced elsewhere. I would then delete all of the previous entities and create the collection anew from the posted data. But I can't do that now, can I?
Since doctrine 2.1, it's possible to change how associations are indexed. This will allow you to use the id as the collection key (as the field has to be unique):
#OneToMany(targetEntity="B", mappedBy="A", indexBy="id")
You might also need to enable orphanRemoval so that the data is actually removed instead of the relation just set to null.

Is there anyway to pass dql to doctrine criteria

I am using Symfony3 framework, and I have user entity, and file entity. I wanted to present in sonata administration user list with sum of all size files which are uploaded by user. When I want to make that field sortable I am getting error:
`Catchable Fatal Error: Argument 1 passed to Sonata\DoctrineORMAdminBundle\Datagrid\ProxyQuery::entityJoin() must be of the type array, null given, called in /home/milos/sites/coinaphoto/vendor/sonata-project/doctrine-orm-admin-bundle/Datagrid/ProxyQuery.php on line 143 and defined`
I have custom function in User entity which is calculating sum of files. It returns string.
My question will be can I somehow pass dql to criteria in order to get sum. Or can you suggest some other way to implement this?
` public function getStoragge(){
$criteria = Criteria::create()
->where(Criteria::expr()->someexpression...);
$matches = $this->file->matching($criteria);
}`
Something similar like when you need to aggregate fields
` $dql = "SELECT SUM(e.amount) AS balance FROM Bank\Entities\Entry e " .
"WHERE e.account = ?1";
$balance = $em->createQuery($dql)
->setParameter(1, $myAccountId)
->getSingleScalarResult();`
I don't know about your dql thing, but some fact about sorting in Sonata Admin table views. The problem is, that sorting actions still be made in the background with database operations, no matter what you are doing "virtual" in your model. If you are adding just a method to your model, the datagrid is not able to involve this method/property in sorting.
My experience is, that you can't sort by fields which are not physically available in the corresponding table. Even if you write the whole query for yourself, if you click on the sort buttons, a complete other query is fired which is ignoring your request.
I'll be pleased if somebody tell me the contrary ...
See also this issue https://github.com/sonata-project/SonataAdminBundle/issues/1077

Symfony2 dynamic relationship with a field

I am building a social website and I am laying out how the feed will work. I want to use the answer here: How to implement the activity stream in a social network and implement the database design mentioned:
id
user_id (int)
activity_type (tinyint)
source_id (int)
parent_id (int)
parent_type (tinyint)
time (datetime but a smaller type like int would be better)
The problem is I don't know how I would map the source_id based off activity_type. If a user registers, I want the source_id to be the user that registered. If someone creates a group the source_id will be the group. I know I can just use simple IDs without keys I just wanted to know if Symfony had some sort of way to do this built in.
If I fetch the feed and the activity_type is user_register I would like to be able to do this to get the source (user) without running an additional query:
$feedEntity->getSource()->getUsername(); //getSource() being the User entity
And if the source_typeis "user_post":
$feedEntity->getSource()->getMessage(); //getSource() being the UserPost entity
I basically just want to find the best way to store this data and make it the fastest.
Not easy to deal with doctrine and i think it cannot achieved 100% automatically
However, the keyword is table inheritance
http://docs.doctrine-project.org/en/2.0.x/reference/inheritance-mapping.html#single-table-inheritance
I think you could achieve your goal by doing something like this :
You create a discriminator map by the type column of the table which tells doctrine to load this entity a UserSource (for example)
This UserSource can be an own entity (can be inherited from a base class if you want) where you can decide to map the source_id column to the real User Entity
You can use instanceof matching against the namespace of the different entities mapped inside your discriminator map to define different behaviours for the different sources

configure entitydatasource with entity set that includes multiple tables

I have an entity data model with two entities. One entity called Posts contains blog posts and another entity called Comment contains comments. I set up the association as a one to many relationship and the primary keys are both postid in both Posts and Comment.
However, when I try to bind this to an entitydatasource control it only lets me select either the Posts or the Comment entity set not both. What I want to do is to be able to bind the post with its comments to the data source, but I can't seem to figure out a way to do this.
Any help would be appreciated!

Subsonic many-to-many relationship

I have 3 tables, one is called Users, one is called Categories and one is a linking table called User_Categories_Map to link users to categories in a many-to-many relationship. The linking table consists of UserId's and CategoryId's. After generating the subsonic classes, I would assume I'd be able to then type User.singleOrDefault(x => x.ID == 1).Categories to select all the categories for a user. However, this doesn't work. If you can understand what I'm trying to accomplish here, can anyone tell me how I can make this work in subsonic? Consequently, I cannot find any documentation on subsonic. Subsonicproject.com only has a short page a few articles about how to set it up. Is there documentation somewhere for subsonic?
int lUserID =1; // suppose 1 is Id of user
CategoriesCollection lCategories = DB.Select().From<Categories>()
.InnerJoin(User_Categories_Map)
.InnerJoin(Users)
.Where(Users.Columns.Id).IsEqualTo(lUserID)
.ExecuteAsCollection<CategoriesCollection>();
It will return collection of categories associated to a specific user..

Resources