Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class ChildListener
- {
- public function preFlush(Child $child, PreFlushEventArgs $args)
- {
- $uow = $args->getEntityManager()->getUnitOfWork();
- // Add an entry to the change set of the parent so that the PreUpdateEventArgs can be constructed without errors
- $uow->propertyChanged($child->getParent(), 'children', 0, 1);
- // Schedule for update the parent entity so that the preUpdate event can be triggered
- $uow->scheduleForUpdate($child->getParent());
- }
- }
- namespace AppBundleEntity;
- use DoctrineCommonNotifyPropertyChanged;
- use DoctrineCommonPropertyChangedListener;
- /**
- * ... other annotations ...
- * @ORMEntityListeners({"AppBundleListenerParentListener"})
- * @ORMChangeTrackingPolicy("NOTIFY")
- */
- class Parent implements NotifyPropertyChanged
- {
- // Add the implementation satisfying the NotifyPropertyChanged interface
- use AppBundleDoctrineTraitsNotifyPropertyChangedTrait;
- /* ... other properties ... */
- /**
- * @ORMColumn(name="basic_property", type="string")
- */
- private $basicProperty;
- /**
- * @ORMOneToMany(targetEntity="AppBundleEntityChild", mappedBy="parent", cascade={"persist", "remove"})
- */
- private $children;
- /**
- * @ORMColumn(name="other_field", type="string")
- */
- private $otherField;
- public function __construct()
- {
- $this->children = new DoctrineCommonCollectionsArrayCollection();
- }
- public function notifyChildChanged()
- {
- $this->onPropertyChanged('children', 0, 1);
- }
- public function setBasicProperty($value)
- {
- if($this->basicProperty != $value)
- {
- $this->onPropertyChanged('basicProperty', $this->basicProperty, $value);
- $this->basicProperty = $value;
- }
- }
- public function addChild(Child $child)
- {
- $this->notifyChildChanged();
- $this->children[] = $child;
- $child->setParent($this);
- return $this;
- }
- public function removeChild(Child $child)
- {
- $this->notifyChildChanged();
- $this->children->removeElement($child);
- }
- /* ... other methods ... */
- }
- namespace AppBundleDoctrineTraits;
- use DoctrineCommonPropertyChangedListener;
- trait NotifyPropertyChangedTrait
- {
- private $listeners = [];
- public function addPropertyChangedListener(PropertyChangedListener $listener)
- {
- $this->listeners[] = $listener;
- }
- /** Notifies listeners of a change. */
- private function onPropertyChanged($propName, $oldValue, $newValue)
- {
- if ($this->listeners)
- {
- foreach ($this->listeners as $listener)
- {
- $listener->propertyChanged($this, $propName, $oldValue, $newValue);
- }
- }
- }
- }
- namespace AppBundleEntity;
- class Child
- {
- /* .. other properties .. */
- /**
- * @ORMManyToOne(targetEntity="AppBundleEntityParent", inversedBy="children")
- */
- private $parentEntity;
- /**
- * @ORMColumn(name="attribute", type="string")
- */
- private $attribute;
- public function setAttribute($attribute)
- {
- // Check if the parentEntity is not null to handle the case where the child entity is created before being attached to its parent
- if($this->attribute != $attribute && $this->parentEntity)
- {
- $this->parentEntity->notifyAliasChanged();
- $this->attribute = $attribute;
- }
- }
- /* ... other methods ... */
- }
- namespace AppBundleUtilsTraits;
- trait MagicSettersTrait
- {
- /** Returns an array with the names of properties for which magic setters can be used */
- abstract protected function getMagicSetters();
- /** Override if needed in the class using this trait to perform actions before set operations */
- private function _preSetCallback($property, $newValue) {}
- /** Override if needed in the class using this trait to perform actions after set operations */
- private function _postSetCallback($property, $newValue) {}
- /** Returns true if the method name starts by "set" */
- private function isSetterMethodCall($name)
- {
- return substr($name, 0, 3) == 'set';
- }
- /** Can be overriden by the class using this trait to allow other magic calls */
- public function __call($name, array $args)
- {
- $this->handleSetterMethodCall($name, $args);
- }
- /**
- * @param string $name Name of the method being called
- * @param array $args Arguments passed to the method
- * @throws BadMethodCallException if the setter is not handled or if the number of arguments is not 1
- */
- private function handleSetterMethodCall($name, array $args)
- {
- $property = lcfirst(substr($name, 3));
- if(!$this->isSetterMethodCall($name) || !in_array($property, $this->getMagicSetters()))
- {
- throw new BadMethodCallException('Undefined method ' . $name . ' for class ' . get_class($this));
- }
- if(count($args) != 1)
- {
- throw new BadMethodCallException('Method ' . $name . ' expects 1 argument (' . count($args) . ' given)');;
- }
- $this->_preSetCallback($property, $args[0]);
- $this->$property = $args[0];
- $this->_postSetCallback($property, $args[0]);
- }
- }
- /**
- * @ORMTable(name="tag")
- * @ORMEntityListeners({"AppBundleListenerTagTagListener"})
- * @ORMChangeTrackingPolicy("NOTIFY")
- */
- class Tag implements NotifyPropertyChanged
- {
- use AppBundleDoctrineTraitsNotifyPropertyChangedTrait;
- use AppBundleUtilsTraitsMagicSettersTrait;
- /* ... attributes ... */
- protected function getMagicSetters() { return ['slug', 'reviewed', 'translations']; }
- /** Called before the actuel set operation in the magic setters */
- public function _preSetCallback($property, $newValue)
- {
- if($this->$property != $newValue)
- {
- $this->onPropertyChanged($property, $this->$property, $newValue);
- }
- }
- public function notifyAliasChanged()
- {
- $this->onPropertyChanged('aliases', 0, 1);
- }
- /* ... methods ... */
- public function addAlias(AppBundleEntityTagTagAlias $alias)
- {
- $this->notifyAliasChanged();
- $this->aliases[] = $alias;
- $alias->setTag($this);
- return $this;
- }
- public function removeAlias(AppBundleEntityTagTagAlias $alias)
- {
- $this->notifyAliasChanged();
- $this->aliases->removeElement($alias);
- }
- }
- class TagAlias
- {
- use AppBundleUtilsTraitsMagicSettersTrait;
- /* ... attributes ... */
- public function getMagicSetters() { return ['alias', 'main', 'locale']; }
- /** Called before the actuel set operation in the magic setters */
- protected function _preSetCallback($property, $newValue)
- {
- if($this->$property != $newValue && $this->tag)
- {
- $this->tag->notifyAliasChanged();
- }
- }
- /* ... methods ... */
- }
- property_accessor:
- class: %property_accessor.class%
- arguments: [true]
Add Comment
Please, Sign In to add comment