2010-11-01 23:16:12 +03:00
|
|
|
Implementing the Notify ChangeTracking Policy
|
|
|
|
=============================================
|
2010-04-06 22:36:40 +04:00
|
|
|
|
2010-12-03 22:13:10 +03:00
|
|
|
.. sectionauthor:: Roman Borschel (roman@code-factory.org)
|
|
|
|
|
2010-11-01 23:16:12 +03:00
|
|
|
The NOTIFY change-tracking policy is the most effective
|
|
|
|
change-tracking policy provided by Doctrine but it requires some
|
|
|
|
boilerplate code. This recipe will show you how this boilerplate
|
|
|
|
code should look like. We will implement it on a
|
|
|
|
`Layer Supertype <http://martinfowler.com/eaaCatalog/layerSupertype.html>`_
|
|
|
|
for all our domain objects.
|
2010-04-06 22:36:40 +04:00
|
|
|
|
2010-11-01 23:16:12 +03:00
|
|
|
Implementing NotifyPropertyChanged
|
|
|
|
----------------------------------
|
2010-04-06 22:36:40 +04:00
|
|
|
|
2010-11-01 23:16:12 +03:00
|
|
|
The NOTIFY policy is based on the assumption that the entities
|
|
|
|
notify interested listeners of changes to their properties. For
|
|
|
|
that purpose, a class that wants to use this policy needs to
|
|
|
|
implement the ``NotifyPropertyChanged`` interface from the
|
|
|
|
``Doctrine\Common`` namespace.
|
2010-04-06 22:36:40 +04:00
|
|
|
|
2010-12-03 22:13:10 +03:00
|
|
|
.. code-block:: php
|
2010-11-01 23:16:12 +03:00
|
|
|
|
|
|
|
<?php
|
2013-04-21 22:43:48 +04:00
|
|
|
use Doctrine\Common\NotifyPropertyChanged;
|
|
|
|
use Doctrine\Common\PropertyChangedListener;
|
2010-04-06 22:36:40 +04:00
|
|
|
|
|
|
|
abstract class DomainObject implements NotifyPropertyChanged
|
|
|
|
{
|
2013-04-21 22:43:48 +04:00
|
|
|
private $listeners = array();
|
2010-11-01 23:16:12 +03:00
|
|
|
|
2010-04-06 22:36:40 +04:00
|
|
|
public function addPropertyChangedListener(PropertyChangedListener $listener) {
|
2013-04-21 22:43:48 +04:00
|
|
|
$this->listeners[] = $listener;
|
2010-04-06 22:36:40 +04:00
|
|
|
}
|
2010-11-01 23:16:12 +03:00
|
|
|
|
2010-04-06 22:36:40 +04:00
|
|
|
/** Notifies listeners of a change. */
|
2013-04-21 22:43:48 +04:00
|
|
|
protected function onPropertyChanged($propName, $oldValue, $newValue) {
|
|
|
|
if ($this->listeners) {
|
|
|
|
foreach ($this->listeners as $listener) {
|
2010-04-06 22:36:40 +04:00
|
|
|
$listener->propertyChanged($this, $propName, $oldValue, $newValue);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-01 23:16:12 +03:00
|
|
|
Then, in each property setter of concrete, derived domain classes,
|
2013-04-21 22:55:54 +04:00
|
|
|
you need to invoke onPropertyChanged as follows to notify
|
2010-11-01 23:16:12 +03:00
|
|
|
listeners:
|
2010-04-06 22:36:40 +04:00
|
|
|
|
2010-12-03 22:13:10 +03:00
|
|
|
.. code-block:: php
|
2010-11-01 23:16:12 +03:00
|
|
|
|
|
|
|
<?php
|
2010-04-06 22:36:40 +04:00
|
|
|
// Mapping not shown, either in annotations, xml or yaml as usual
|
|
|
|
class MyEntity extends DomainObject
|
|
|
|
{
|
|
|
|
private $data;
|
|
|
|
// ... other fields as usual
|
2010-11-01 23:16:12 +03:00
|
|
|
|
2010-04-06 22:36:40 +04:00
|
|
|
public function setData($data) {
|
|
|
|
if ($data != $this->data) { // check: is it actually modified?
|
2013-04-21 22:43:48 +04:00
|
|
|
$this->onPropertyChanged('data', $this->data, $data);
|
2010-04-06 22:36:40 +04:00
|
|
|
$this->data = $data;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-01 23:16:12 +03:00
|
|
|
The check whether the new value is different from the old one is
|
|
|
|
not mandatory but recommended. That way you can avoid unnecessary
|
|
|
|
updates and also have full control over when you consider a
|
|
|
|
property changed.
|
|
|
|
|
2010-04-06 22:36:40 +04:00
|
|
|
|