abstract class PersistentObject in Plug 7
PersistentObject base class that implements getter/setter methods for all mapped fields and associations by overriding __call.
This class is a forward compatible implementation of the PersistentObject trait.
Limitations:
1. All persistent objects have to be associated with a single ObjectManager, multiple ObjectManagers are not supported. You can set the ObjectManager with `PersistentObject#setObjectManager()`. 2. Setters and getters only work if a ClassMetadata instance was injected into the PersistentObject. This is either done on `postLoad` of an object or by accessing the global object manager. 3. There are no hooks for setters/getters. Just implement the method yourself instead of relying on __call(). 4. Slower than handcoded implementations: An average of 7 method calls per access to a field and 11 for an association. 5. Only the inverse side associations get autoset on the owning side as well. Setting objects on the owning side will not set the inverse side associations.
@example
PersistentObject::setObjectManager($em);
class Foo extends PersistentObject { private $id; }
$foo = new Foo(); $foo->getId(); // method exists through __call
@author Benjamin Eberlei <kontakt@beberlei.de>
Hierarchy
- class \Doctrine\Common\Persistence\PersistentObject implements ObjectManagerAware
Expanded class hierarchy of PersistentObject
1 file declares its use of PersistentObject
- PersistentObjectTest.php in lib/
doctrine/ common/ tests/ Doctrine/ Tests/ Common/ Persistence/ PersistentObjectTest.php
File
- lib/
doctrine/ common/ lib/ Doctrine/ Common/ Persistence/ PersistentObject.php, line 57
Namespace
Doctrine\Common\PersistenceView source
abstract class PersistentObject implements ObjectManagerAware {
/**
* @var ObjectManager|null
*/
private static $objectManager = null;
/**
* @var ClassMetadata|null
*/
private $cm = null;
/**
* Sets the object manager responsible for all persistent object base classes.
*
* @param ObjectManager|null $objectManager
*
* @return void
*/
public static function setObjectManager(ObjectManager $objectManager = null) {
self::$objectManager = $objectManager;
}
/**
* @return ObjectManager|null
*/
public static function getObjectManager() {
return self::$objectManager;
}
/**
* Injects the Doctrine Object Manager.
*
* @param ObjectManager $objectManager
* @param ClassMetadata $classMetadata
*
* @return void
*
* @throws \RuntimeException
*/
public function injectObjectManager(ObjectManager $objectManager, ClassMetadata $classMetadata) {
if ($objectManager !== self::$objectManager) {
throw new \RuntimeException("Trying to use PersistentObject with different ObjectManager instances. " . "Was PersistentObject::setObjectManager() called?");
}
$this->cm = $classMetadata;
}
/**
* Sets a persistent fields value.
*
* @param string $field
* @param array $args
*
* @return void
*
* @throws \BadMethodCallException When no persistent field exists by that name.
* @throws \InvalidArgumentException When the wrong target object type is passed to an association.
*/
private function set($field, $args) {
$this
->initializeDoctrine();
if ($this->cm
->hasField($field) && !$this->cm
->isIdentifier($field)) {
$this->{$field} = $args[0];
}
else {
if ($this->cm
->hasAssociation($field) && $this->cm
->isSingleValuedAssociation($field)) {
$targetClass = $this->cm
->getAssociationTargetClass($field);
if (!$args[0] instanceof $targetClass && $args[0] !== null) {
throw new \InvalidArgumentException("Expected persistent object of type '" . $targetClass . "'");
}
$this->{$field} = $args[0];
$this
->completeOwningSide($field, $targetClass, $args[0]);
}
else {
throw new \BadMethodCallException("no field with name '" . $field . "' exists on '" . $this->cm
->getName() . "'");
}
}
}
/**
* Gets a persistent field value.
*
* @param string $field
*
* @return mixed
*
* @throws \BadMethodCallException When no persistent field exists by that name.
*/
private function get($field) {
$this
->initializeDoctrine();
if ($this->cm
->hasField($field) || $this->cm
->hasAssociation($field)) {
return $this->{$field};
}
else {
throw new \BadMethodCallException("no field with name '" . $field . "' exists on '" . $this->cm
->getName() . "'");
}
}
/**
* If this is an inverse side association, completes the owning side.
*
* @param string $field
* @param ClassMetadata $targetClass
* @param object $targetObject
*
* @return void
*/
private function completeOwningSide($field, $targetClass, $targetObject) {
// add this object on the owning side as well, for obvious infinite recursion
// reasons this is only done when called on the inverse side.
if ($this->cm
->isAssociationInverseSide($field)) {
$mappedByField = $this->cm
->getAssociationMappedByTargetField($field);
$targetMetadata = self::$objectManager
->getClassMetadata($targetClass);
$setter = ($targetMetadata
->isCollectionValuedAssociation($mappedByField) ? "add" : "set") . $mappedByField;
$targetObject
->{$setter}($this);
}
}
/**
* Adds an object to a collection.
*
* @param string $field
* @param array $args
*
* @return void
*
* @throws \BadMethodCallException
* @throws \InvalidArgumentException
*/
private function add($field, $args) {
$this
->initializeDoctrine();
if ($this->cm
->hasAssociation($field) && $this->cm
->isCollectionValuedAssociation($field)) {
$targetClass = $this->cm
->getAssociationTargetClass($field);
if (!$args[0] instanceof $targetClass) {
throw new \InvalidArgumentException("Expected persistent object of type '" . $targetClass . "'");
}
if (!$this->{$field} instanceof Collection) {
$this->{$field} = new ArrayCollection($this->{$field} ?: array());
}
$this->{$field}
->add($args[0]);
$this
->completeOwningSide($field, $targetClass, $args[0]);
}
else {
throw new \BadMethodCallException("There is no method add" . $field . "() on " . $this->cm
->getName());
}
}
/**
* Initializes Doctrine Metadata for this class.
*
* @return void
*
* @throws \RuntimeException
*/
private function initializeDoctrine() {
if ($this->cm !== null) {
return;
}
if (!self::$objectManager) {
throw new \RuntimeException("No runtime object manager set. Call PersistentObject#setObjectManager().");
}
$this->cm = self::$objectManager
->getClassMetadata(get_class($this));
}
/**
* Magic methods.
*
* @param string $method
* @param array $args
*
* @return mixed
*
* @throws \BadMethodCallException
*/
public function __call($method, $args) {
$command = substr($method, 0, 3);
$field = lcfirst(substr($method, 3));
if ($command == "set") {
$this
->set($field, $args);
}
else {
if ($command == "get") {
return $this
->get($field);
}
else {
if ($command == "add") {
$this
->add($field, $args);
}
else {
throw new \BadMethodCallException("There is no method " . $method . " on " . $this->cm
->getName());
}
}
}
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
PersistentObject:: |
private | property | ||
PersistentObject:: |
private static | property | ||
PersistentObject:: |
private | function | Adds an object to a collection. | |
PersistentObject:: |
private | function | If this is an inverse side association, completes the owning side. | |
PersistentObject:: |
private | function | Gets a persistent field value. | |
PersistentObject:: |
public static | function | ||
PersistentObject:: |
private | function | Initializes Doctrine Metadata for this class. | |
PersistentObject:: |
public | function |
Injects the Doctrine Object Manager. Overrides ObjectManagerAware:: |
|
PersistentObject:: |
private | function | Sets a persistent fields value. | |
PersistentObject:: |
public static | function | Sets the object manager responsible for all persistent object base classes. | |
PersistentObject:: |
public | function | Magic methods. |