Here is the deal. Using Doctrine ORM for PHP and I need to "decouple" model from entity persistent layer. Say we have UserEntity which holds all the pretty stuff for db mapping, as: annotations, properties, setters/getters and so on. From the other hand i'd like to have a separate User class which only holds business related logic, for instance: User::getFullName(). Furthermore i want User to extend UserEntity so User inherits all the access methods.
Possible solutions i've checked through don't work for me:
any ideas ?
Gotcha ! (>= PHP 5.4 solution)
Short: make entity a trait, use entity trait in model class. Checkout this doc page: http://doctrine-orm.readthedocs.org/en/latest/tutorials/override-field-association-mappings-in-subclasses.html.
Example: Suppose we have user model. First create user entity:
/**
* @ORM\Table(name="user")
*/
trait UserEntity {
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* @var string
*
* @ORM\Column(name="first_name", type="string", length=100, nullable=true)
*/
protected $firstName;
/**
* @var string
*
* @ORM\Column(name="last_name", type="string", length=100, nullable=true)
*/
protected $lastName;
// other mapping here...
}
Then create a model and use an entity trait in it:
/**
* @ORM\Entity
*/
class User {
use UserEntity;
public function getFullName() {
return $this->firstName . ' ' . $this->lastName;
}
}
Mind @Entity annotation in User model. This is required in order to use model directly in entity manager.
Now suppose we need an Admin model which extends User one. This is a bit tricky. We have to change @Entity to @MappedSuperclass in User so it can be extended. Then create Admin model, declare it as @Entity and also redeclare a table name on it using @Table annotation (otherwise Doctrine will be confused from which table to fetch for some reason). Look like this:
/**
* @ORM\MappedSuperclass
*/
class User {
use UserEntity;
public function getFullName() {
return $this->firstName . ' ' . $this->lastName;
}
}
/**
* @ORM\Entity
* @ORM\Table(name="user")
*/
class Admin extends User {
public function getFullName() {
return parent::getFullName() . ' (admin)';
}
}
This way both User and Admin models (=entities) can be used in Doctrine.
And no we can do whatever we would normally do with entities: find() them via entity manager, use models directly in queries, etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With