Simple example:
I've got two users Admin and Client (both implements UserInterface) and Cart - three entity classes at a. Admin and Client can have his own carts. How to configure/resolve Cart entity relation to have method 'getUser()' which returns Admin or Client user?
Maybe I can have column user_id and second column with user entity name in Cart (something similar as DiscriminatorMapping can do)?
class Admin implements UserInterface
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #var Collection
* #ORM\OneToMany(targetEntity="Cart", mappedBy="???")
*/
private $carts;
....
class Client implements UserInterface
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #var Collection
* #ORM\OneToMany(targetEntity="Cart", mappedBy="???")
*/
private $carts;
....
class Cart
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #var UserInterface
* #ORM\ManyToOne(targetEntity="UserInterface", ???)
*/
private $user;
....
I tried this Doctrine feature, also tried DisciminatorMapping and composite keys (join by multiple columns) option with no luck.
Any help?
I think you were almost there. DiscriminatorMapping is probably the way to go. However, you need to bind Client and Admin to a Parent class. So consider this hierarchy:
User (parent class)
Admin (extends User)
Client (extends User)
Then in your Cart entity you bind the relation to the User entity.
Related
I have this entity
/**
* #ApiResource()
* #ORM\Entity(repositoryClass="App\Repository\FeedRepository")
*/
class Feed implements AuthoredEntityInterface
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="myFeeds")
* #ORM\JoinColumn(nullable=false)
*/
private $user;
/**
* #ORM\Column(type="string", length=255)
*/
private $name;
/**
* #ORM\Column(type="string", length=2083, unique=true)
*/
private $url;
// various getters and setters
}
using the AuthoredEntityInterface I made I can automatically set the user to the logged user.
I'd need to know how to set the collectionOperations so when I am logged in as the user with id = 1, when I call /api/feeds I will only retrieve items with user = 1. If this is possible I would like to do this with an annotation, otherwise any other method is ok.
thanks.
If it is just for connected user, what you need is a current user extension (doctrine extension). Else, you need to create a "subresource' link.
Link to Extension, and to Subresource.
Enjoy :) (and thank you timisorean for the review)
I have a class that extends fos_user class from FOSUserBundle.
Every user have some roles.
If user has role "BASIC" he has a OneToMany relation with entity Entry (one basic user has many entries).
If user has role "MASTER" he has a ManyToMany relation with entity House (many master users have many houses).
I done this:
/**
* #ORM\Entity
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\ManyToMany(targetEntity="House", inversedBy="users")
*/
protected $houses;
/**
* #ORM\OneToMany(targetEntity="Entry", mappedBy="user")
*/
protected $entries;
}
But it doesn't sound fine.
Is there a design pattern for this scenario?
As #lxg wrote a possible pattern is single table inheritance.
You can look an example here.
In my web application, I want my user's to be able to create roles and add users to them dynamically. The only thing I imagine, is to edit the security.yml every time, but this can't be the best solution, can it? It would be very nice, if there is something like a User Provider for roles, so I can define one which loads the roles from a database (doctrine).
Thanks for your help, hice3000.
Then, you should want to add a role Entity to your model Hice.
You have to know that Symfony2 provides support for dynamic roles too. You have a getRoles() method in the Symfony2 User spec in the API Doc, that your User entity should implement, that forces him to return Roles. These roles must either implement the role interface that specifies a getRole() method that returns, most usually, the role name itself.
You can then add the newly created role directly to your user role list that the getRoles() user method will then return.
Here is an example using annotations :
First role class
/**
* Role class
*
* #ORM\Entity()
*/
class Role implements RoleInterface, \Serializable
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #ORM\ManyToMany(targetEntity="User", mappedBy="userRoles")
*/
private $users;
public function __construct()
{
$this->users = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getRole()
{
return $this->name;
}
}
And the User class
/**
* User
*
* #ORM\Entity()
*/
class User implements UserInterface, \Serializable
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="username", type="string", length=255)
*/
private $username;
/**
* #ORM\ManyToMany(targetEntity="Role", inversedBy="users")
* #ORM\JoinTable(name="user_roles")
*/
private $userRoles;
public function __construct()
{
$this->userRoles = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getRoles()
{
return $this->userRoles->toArray();
}
I've skipped imports and methods to simplify the approach.
EDIT : There is something to know about serialization too. As Sharom commented on github, you musn't serialize users in roles neither roles in users. Just read his post and I think you'll understand :)
I have an entity called Item as above:
<?php
/**
* Item
* #ORM\Table(name="item")
* #ORM\Entity
*/
class Item {
/**
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var \Acme\UserBundle\Entity\User
* ???
*/
private $user;
.....
How can I inject logged User object into $user property via annotation in the easiest way?
If you are trying to save the created/updated timestamps and the user who performed these actions with your entity ... this is called blameable and timestampable behavior!
Have a look at Knp\DoctrineBehaviors including blameable and timestampable behaviors. (PHP 5.4+ needed)
Gedmo\DoctrineExtensions also provides blameable and timestampable. (PHP >=5.3.2)
I have several bundles in my app and I would like to have relations between tables.
One is my User(StoreOwner) which is in UserBundle, and the second is Store in StoreBundle.
The relation between them is OneToMany (User -> is owner of -> Store).
Store
/**
* Description of Store
*
* #ORM\Table(name="Store")
* #ORM\Entity(repositoryClass="Traffic\StoreBundle\Repository\StoreRepository")
* #author bart
*/
class Store extends StoreModel {
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string $name
*
* #ORM\Column(type="string", length=255)
* #Assert\NotBlank(
* message="Please provide your shop name"
* )
*/
protected $name;
/**
* #ORM\ManyToOne(targetEntity="Application\Sonata\UserBundle\Entity\StoreOwner", inversedBy="stores")
*
*/
protected $owner;
}
StoreOwner
/**
* #ORM\Entity
*
*/
class StoreOwner extends User implements StoreOwnerInterface {
/**
* #var type ArrayCollection()
*
* #ORM\OneToMany(targetEntity="Traffic\StoreBundle\Entity\Store", mappedBy="owner", cascade={"persist"})
*/
protected $stores;
}
My question is:
Is there any solution to avoid dependency between StoreBundle and UserBundle and keep relations between Entities in Doctrine?
This is a valid concern in my opinion. Two-way dependencies between bundles are a smell.
One way of solving the dependency issue is moving your entities out of the bundles into a more general namespace. This way both bundles will depend on the same "library" but won't depend on each other directly.
I recently wrote a blog post on how to do it: How to store Doctrine entities outside of a Symfony bundle?