Guest User

Untitled

a guest
Jan 21st, 2018
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.89 KB | None | 0 0
  1. class ChildListener
  2. {
  3. public function preFlush(Child $child, PreFlushEventArgs $args)
  4. {
  5. $uow = $args->getEntityManager()->getUnitOfWork();
  6. // Add an entry to the change set of the parent so that the PreUpdateEventArgs can be constructed without errors
  7. $uow->propertyChanged($child->getParent(), 'children', 0, 1);
  8. // Schedule for update the parent entity so that the preUpdate event can be triggered
  9. $uow->scheduleForUpdate($child->getParent());
  10. }
  11. }
  12.  
  13. namespace AppBundleEntity;
  14.  
  15. use DoctrineCommonNotifyPropertyChanged;
  16. use DoctrineCommonPropertyChangedListener;
  17.  
  18. /**
  19. * ... other annotations ...
  20. * @ORMEntityListeners({"AppBundleListenerParentListener"})
  21. * @ORMChangeTrackingPolicy("NOTIFY")
  22. */
  23. class Parent implements NotifyPropertyChanged
  24. {
  25. // Add the implementation satisfying the NotifyPropertyChanged interface
  26. use AppBundleDoctrineTraitsNotifyPropertyChangedTrait;
  27.  
  28. /* ... other properties ... */
  29.  
  30. /**
  31. * @ORMColumn(name="basic_property", type="string")
  32. */
  33. private $basicProperty;
  34.  
  35. /**
  36. * @ORMOneToMany(targetEntity="AppBundleEntityChild", mappedBy="parent", cascade={"persist", "remove"})
  37. */
  38. private $children;
  39.  
  40. /**
  41. * @ORMColumn(name="other_field", type="string")
  42. */
  43. private $otherField;
  44.  
  45. public function __construct()
  46. {
  47. $this->children = new DoctrineCommonCollectionsArrayCollection();
  48. }
  49.  
  50. public function notifyChildChanged()
  51. {
  52. $this->onPropertyChanged('children', 0, 1);
  53. }
  54.  
  55. public function setBasicProperty($value)
  56. {
  57. if($this->basicProperty != $value)
  58. {
  59. $this->onPropertyChanged('basicProperty', $this->basicProperty, $value);
  60. $this->basicProperty = $value;
  61. }
  62. }
  63.  
  64. public function addChild(Child $child)
  65. {
  66. $this->notifyChildChanged();
  67. $this->children[] = $child;
  68. $child->setParent($this);
  69. return $this;
  70. }
  71.  
  72. public function removeChild(Child $child)
  73. {
  74. $this->notifyChildChanged();
  75. $this->children->removeElement($child);
  76. }
  77.  
  78. /* ... other methods ... */
  79. }
  80.  
  81. namespace AppBundleDoctrineTraits;
  82.  
  83. use DoctrineCommonPropertyChangedListener;
  84.  
  85. trait NotifyPropertyChangedTrait
  86. {
  87. private $listeners = [];
  88.  
  89. public function addPropertyChangedListener(PropertyChangedListener $listener)
  90. {
  91. $this->listeners[] = $listener;
  92. }
  93.  
  94. /** Notifies listeners of a change. */
  95. private function onPropertyChanged($propName, $oldValue, $newValue)
  96. {
  97. if ($this->listeners)
  98. {
  99. foreach ($this->listeners as $listener)
  100. {
  101. $listener->propertyChanged($this, $propName, $oldValue, $newValue);
  102. }
  103. }
  104. }
  105.  
  106. }
  107.  
  108. namespace AppBundleEntity;
  109.  
  110. class Child
  111. {
  112.  
  113. /* .. other properties .. */
  114.  
  115. /**
  116. * @ORMManyToOne(targetEntity="AppBundleEntityParent", inversedBy="children")
  117. */
  118. private $parentEntity;
  119.  
  120. /**
  121. * @ORMColumn(name="attribute", type="string")
  122. */
  123. private $attribute;
  124.  
  125. public function setAttribute($attribute)
  126. {
  127. // Check if the parentEntity is not null to handle the case where the child entity is created before being attached to its parent
  128. if($this->attribute != $attribute && $this->parentEntity)
  129. {
  130. $this->parentEntity->notifyAliasChanged();
  131. $this->attribute = $attribute;
  132. }
  133. }
  134.  
  135. /* ... other methods ... */
  136. }
  137.  
  138. namespace AppBundleUtilsTraits;
  139.  
  140. trait MagicSettersTrait
  141. {
  142. /** Returns an array with the names of properties for which magic setters can be used */
  143. abstract protected function getMagicSetters();
  144.  
  145. /** Override if needed in the class using this trait to perform actions before set operations */
  146. private function _preSetCallback($property, $newValue) {}
  147. /** Override if needed in the class using this trait to perform actions after set operations */
  148. private function _postSetCallback($property, $newValue) {}
  149.  
  150. /** Returns true if the method name starts by "set" */
  151. private function isSetterMethodCall($name)
  152. {
  153. return substr($name, 0, 3) == 'set';
  154. }
  155.  
  156. /** Can be overriden by the class using this trait to allow other magic calls */
  157. public function __call($name, array $args)
  158. {
  159. $this->handleSetterMethodCall($name, $args);
  160. }
  161.  
  162. /**
  163. * @param string $name Name of the method being called
  164. * @param array $args Arguments passed to the method
  165. * @throws BadMethodCallException if the setter is not handled or if the number of arguments is not 1
  166. */
  167. private function handleSetterMethodCall($name, array $args)
  168. {
  169. $property = lcfirst(substr($name, 3));
  170. if(!$this->isSetterMethodCall($name) || !in_array($property, $this->getMagicSetters()))
  171. {
  172. throw new BadMethodCallException('Undefined method ' . $name . ' for class ' . get_class($this));
  173. }
  174.  
  175. if(count($args) != 1)
  176. {
  177. throw new BadMethodCallException('Method ' . $name . ' expects 1 argument (' . count($args) . ' given)');;
  178. }
  179.  
  180. $this->_preSetCallback($property, $args[0]);
  181. $this->$property = $args[0];
  182. $this->_postSetCallback($property, $args[0]);
  183. }
  184. }
  185.  
  186. /**
  187. * @ORMTable(name="tag")
  188. * @ORMEntityListeners({"AppBundleListenerTagTagListener"})
  189. * @ORMChangeTrackingPolicy("NOTIFY")
  190. */
  191. class Tag implements NotifyPropertyChanged
  192. {
  193. use AppBundleDoctrineTraitsNotifyPropertyChangedTrait;
  194. use AppBundleUtilsTraitsMagicSettersTrait;
  195.  
  196. /* ... attributes ... */
  197.  
  198. protected function getMagicSetters() { return ['slug', 'reviewed', 'translations']; }
  199.  
  200. /** Called before the actuel set operation in the magic setters */
  201. public function _preSetCallback($property, $newValue)
  202. {
  203. if($this->$property != $newValue)
  204. {
  205. $this->onPropertyChanged($property, $this->$property, $newValue);
  206. }
  207. }
  208.  
  209. public function notifyAliasChanged()
  210. {
  211. $this->onPropertyChanged('aliases', 0, 1);
  212. }
  213.  
  214. /* ... methods ... */
  215.  
  216. public function addAlias(AppBundleEntityTagTagAlias $alias)
  217. {
  218. $this->notifyAliasChanged();
  219. $this->aliases[] = $alias;
  220. $alias->setTag($this);
  221. return $this;
  222. }
  223.  
  224. public function removeAlias(AppBundleEntityTagTagAlias $alias)
  225. {
  226. $this->notifyAliasChanged();
  227. $this->aliases->removeElement($alias);
  228. }
  229. }
  230.  
  231. class TagAlias
  232. {
  233. use AppBundleUtilsTraitsMagicSettersTrait;
  234.  
  235. /* ... attributes ... */
  236.  
  237. public function getMagicSetters() { return ['alias', 'main', 'locale']; }
  238.  
  239. /** Called before the actuel set operation in the magic setters */
  240. protected function _preSetCallback($property, $newValue)
  241. {
  242. if($this->$property != $newValue && $this->tag)
  243. {
  244. $this->tag->notifyAliasChanged();
  245. }
  246. }
  247.  
  248. /* ... methods ... */
  249. }
  250.  
  251. property_accessor:
  252. class: %property_accessor.class%
  253. arguments: [true]
Add Comment
Please, Sign In to add comment