commit
e2a67c2f1c
@ -20,12 +20,12 @@ manager.
|
|||||||
$evm = new EventManager();
|
$evm = new EventManager();
|
||||||
|
|
||||||
Now we can add some event listeners to the ``$evm``. Let's create a
|
Now we can add some event listeners to the ``$evm``. Let's create a
|
||||||
``EventTest`` class to play around with.
|
``TestEvent`` class to play around with.
|
||||||
|
|
||||||
.. code-block:: php
|
.. code-block:: php
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
class EventTest
|
class TestEvent
|
||||||
{
|
{
|
||||||
const preFoo = 'preFoo';
|
const preFoo = 'preFoo';
|
||||||
const postFoo = 'postFoo';
|
const postFoo = 'postFoo';
|
||||||
@ -52,15 +52,15 @@ Now we can add some event listeners to the ``$evm``. Let's create a
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a new instance
|
// Create a new instance
|
||||||
$test = new EventTest($evm);
|
$test = new TestEvent($evm);
|
||||||
|
|
||||||
Events can be dispatched by using the ``dispatchEvent()`` method.
|
Events can be dispatched by using the ``dispatchEvent()`` method.
|
||||||
|
|
||||||
.. code-block:: php
|
.. code-block:: php
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
$evm->dispatchEvent(EventTest::preFoo);
|
$evm->dispatchEvent(TestEvent::preFoo);
|
||||||
$evm->dispatchEvent(EventTest::postFoo);
|
$evm->dispatchEvent(TestEvent::postFoo);
|
||||||
|
|
||||||
You can easily remove a listener with the ``removeEventListener()``
|
You can easily remove a listener with the ``removeEventListener()``
|
||||||
method.
|
method.
|
||||||
@ -133,13 +133,12 @@ several reasons:
|
|||||||
- It is easy to read.
|
- It is easy to read.
|
||||||
- Simplicity.
|
- Simplicity.
|
||||||
- Each method within an EventSubscriber is named after the
|
- Each method within an EventSubscriber is named after the
|
||||||
corresponding constant. If constant name and constant value differ,
|
corresponding constant's value. If the constant's name and value differ
|
||||||
you MUST use the new value and thus, your code might be subject to
|
it contradicts the intention of using the constant and makes your code
|
||||||
codechanges when the value changes. This contradicts the intention
|
harder to maintain.
|
||||||
of a constant.
|
|
||||||
|
|
||||||
An example for a correct notation can be found in the example
|
An example for a correct notation can be found in the example
|
||||||
``EventTest`` above.
|
``TestEvent`` above.
|
||||||
|
|
||||||
.. _reference-events-lifecycle-events:
|
.. _reference-events-lifecycle-events:
|
||||||
|
|
||||||
@ -159,7 +158,7 @@ the life-time of their registered entities.
|
|||||||
- prePersist - The prePersist event occurs for a given entity
|
- prePersist - The prePersist event occurs for a given entity
|
||||||
before the respective EntityManager persist operation for that
|
before the respective EntityManager persist operation for that
|
||||||
entity is executed. It should be noted that this event is only triggered on
|
entity is executed. It should be noted that this event is only triggered on
|
||||||
*initial* persist of an entity
|
*initial* persist of an entity (i.e. it does not trigger on future updates).
|
||||||
- postPersist - The postPersist event occurs for an entity after
|
- postPersist - The postPersist event occurs for an entity after
|
||||||
the entity has been made persistent. It will be invoked after the
|
the entity has been made persistent. It will be invoked after the
|
||||||
database insert operations. Generated primary key values are
|
database insert operations. Generated primary key values are
|
||||||
@ -205,12 +204,14 @@ ORM package.
|
|||||||
These can be hooked into by two different types of event
|
These can be hooked into by two different types of event
|
||||||
listeners:
|
listeners:
|
||||||
|
|
||||||
|
|
||||||
- Lifecycle Callbacks are methods on the entity classes that are
|
- Lifecycle Callbacks are methods on the entity classes that are
|
||||||
called when the event is triggered. They receives some kind of ``EventArgs``.
|
called when the event is triggered. As of v2.4 they receive some kind
|
||||||
|
of ``EventArgs`` instance.
|
||||||
- Lifecycle Event Listeners and Subscribers are classes with specific callback
|
- Lifecycle Event Listeners and Subscribers are classes with specific callback
|
||||||
methods that receives some kind of ``EventArgs`` instance which
|
methods that receives some kind of ``EventArgs`` instance.
|
||||||
give access to the entity, EntityManager or other relevant data.
|
|
||||||
|
The EventArgs instance received by the listener gives access to the entity,
|
||||||
|
EntityManager and other relevant data.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
@ -224,10 +225,11 @@ listeners:
|
|||||||
Lifecycle Callbacks
|
Lifecycle Callbacks
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
A lifecycle event is a regular event with the additional feature of
|
Lifecycle Callbacks are defined on an entity class. They allow you to
|
||||||
providing a mechanism to register direct callbacks inside the
|
trigger callbacks whenever an instance of that entity class experiences
|
||||||
corresponding entity classes that are executed when the lifecycle
|
a relevant lifecycle event. More than one callback can be defined for each
|
||||||
event occurs.
|
lifecycle event. Lifecycle Callbacks are best used for simple operations
|
||||||
|
specific to a particular entity class's lifecycle.
|
||||||
|
|
||||||
.. code-block:: php
|
.. code-block:: php
|
||||||
|
|
||||||
@ -277,8 +279,9 @@ event occurs.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Note that when using annotations you have to apply the
|
Note that the methods set as lifecycle callbacks need to be public and,
|
||||||
@HasLifecycleCallbacks marker annotation on the entity class.
|
when using these annotations, you have to apply the
|
||||||
|
``@HasLifecycleCallbacks`` marker annotation on the entity class.
|
||||||
|
|
||||||
If you want to register lifecycle callbacks from YAML or XML you
|
If you want to register lifecycle callbacks from YAML or XML you
|
||||||
can do it with the following.
|
can do it with the following.
|
||||||
@ -292,9 +295,13 @@ can do it with the following.
|
|||||||
name:
|
name:
|
||||||
type: string(50)
|
type: string(50)
|
||||||
lifecycleCallbacks:
|
lifecycleCallbacks:
|
||||||
prePersist: [ doStuffOnPrePersist, doOtherStuffOnPrePersistToo ]
|
prePersist: [ doStuffOnPrePersist, doOtherStuffOnPrePersist ]
|
||||||
postPersist: [ doStuffOnPostPersist ]
|
postPersist: [ doStuffOnPostPersist ]
|
||||||
|
|
||||||
|
In YAML the ``key`` of the lifecycleCallbacks entry is the event that you
|
||||||
|
are triggering on and the value is the method (or methods) to call. The allowed
|
||||||
|
event types are the ones listed in the previous Lifecycle Events section.
|
||||||
|
|
||||||
XML would look something like this:
|
XML would look something like this:
|
||||||
|
|
||||||
.. code-block:: xml
|
.. code-block:: xml
|
||||||
@ -317,9 +324,14 @@ XML would look something like this:
|
|||||||
|
|
||||||
</doctrine-mapping>
|
</doctrine-mapping>
|
||||||
|
|
||||||
You just need to make sure a public ``doStuffOnPrePersist()`` and
|
In XML the ``type`` of the lifecycle-callback entry is the event that you
|
||||||
``doStuffOnPostPersist()`` method is defined on your ``User``
|
are triggering on and the ``method`` is the method to call. The allowed event
|
||||||
model.
|
types are the ones listed in the previous Lifecycle Events section.
|
||||||
|
|
||||||
|
When using YAML or XML you need to remember to create public methods to match the
|
||||||
|
callback names you defined. E.g. in these examples ``doStuffOnPrePersist()``,
|
||||||
|
``doOtherStuffOnPrePersist()`` and ``doStuffOnPostPersist()`` methods need to be
|
||||||
|
defined on your ``User`` model.
|
||||||
|
|
||||||
.. code-block:: php
|
.. code-block:: php
|
||||||
|
|
||||||
@ -335,15 +347,17 @@ model.
|
|||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function doOtherStuffOnPrePersist()
|
||||||
|
{
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
public function doStuffOnPostPersist()
|
public function doStuffOnPostPersist()
|
||||||
{
|
{
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
The ``key`` of the lifecycleCallbacks is the name of the method and
|
|
||||||
the value is the event type. The allowed event types are the ones
|
|
||||||
listed in the previous Lifecycle Events section.
|
|
||||||
|
|
||||||
Lifecycle Callbacks Event Argument
|
Lifecycle Callbacks Event Argument
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
@ -375,8 +389,10 @@ Listening and subscribing to Lifecycle Events
|
|||||||
|
|
||||||
Lifecycle event listeners are much more powerful than the simple
|
Lifecycle event listeners are much more powerful than the simple
|
||||||
lifecycle callbacks that are defined on the entity classes. They
|
lifecycle callbacks that are defined on the entity classes. They
|
||||||
allow to implement re-usable behaviors between different entity
|
sit at a level above the entities and allow you to implement re-usable
|
||||||
classes, yet require much more detailed knowledge about the inner
|
behaviors across different entity classes.
|
||||||
|
|
||||||
|
Note that they require much more detailed knowledge about the inner
|
||||||
workings of the EntityManager and UnitOfWork. Please read the
|
workings of the EntityManager and UnitOfWork. Please read the
|
||||||
*Implementing Event Listeners* section carefully if you are trying
|
*Implementing Event Listeners* section carefully if you are trying
|
||||||
to write your own listener.
|
to write your own listener.
|
||||||
@ -476,8 +492,8 @@ data and lost updates/persists/removes.
|
|||||||
|
|
||||||
For the described events that are also lifecycle callback events
|
For the described events that are also lifecycle callback events
|
||||||
the restrictions apply as well, with the additional restriction
|
the restrictions apply as well, with the additional restriction
|
||||||
that you do not have access to the EntityManager or UnitOfWork APIs
|
that (prior to version 2.4) you do not have access to the
|
||||||
inside these events.
|
EntityManager or UnitOfWork APIs inside these events.
|
||||||
|
|
||||||
prePersist
|
prePersist
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
@ -501,10 +517,10 @@ The following restrictions apply to ``prePersist``:
|
|||||||
- If you are using a PrePersist Identity Generator such as
|
- If you are using a PrePersist Identity Generator such as
|
||||||
sequences the ID value will *NOT* be available within any
|
sequences the ID value will *NOT* be available within any
|
||||||
PrePersist events.
|
PrePersist events.
|
||||||
- Doctrine will not recognize changes made to relations in a pre
|
- Doctrine will not recognize changes made to relations in a prePersist
|
||||||
persist event called by "reachability" through a cascade persist
|
event called by "reachability" through a cascade persist unless you
|
||||||
unless you use the internal ``UnitOfWork`` API. We do not recommend
|
use the internal ``UnitOfWork`` API. We do not recommend such
|
||||||
such operations in the persistence by reachability context, so do
|
operations in the persistence by reachability context, so do
|
||||||
this at your own risk and possibly supported by unit-tests.
|
this at your own risk and possibly supported by unit-tests.
|
||||||
|
|
||||||
preRemove
|
preRemove
|
||||||
@ -593,13 +609,13 @@ mentioned sets. See this example:
|
|||||||
The following restrictions apply to the onFlush event:
|
The following restrictions apply to the onFlush event:
|
||||||
|
|
||||||
|
|
||||||
- If you create and persist a new entity in "onFlush", then
|
- If you create and persist a new entity in ``onFlush``, then
|
||||||
calling ``EntityManager#persist()`` is not enough.
|
calling ``EntityManager#persist()`` is not enough.
|
||||||
You have to execute an additional call to
|
You have to execute an additional call to
|
||||||
``$unitOfWork->computeChangeSet($classMetadata, $entity)``.
|
``$unitOfWork->computeChangeSet($classMetadata, $entity)``.
|
||||||
- Changing primitive fields or associations requires you to
|
- Changing primitive fields or associations requires you to
|
||||||
explicitly trigger a re-computation of the changeset of the
|
explicitly trigger a re-computation of the changeset of the
|
||||||
affected entity. This can be done by either calling
|
affected entity. This can be done by calling
|
||||||
``$unitOfWork->recomputeSingleEntityChangeSet($classMetadata, $entity)``.
|
``$unitOfWork->recomputeSingleEntityChangeSet($classMetadata, $entity)``.
|
||||||
|
|
||||||
postFlush
|
postFlush
|
||||||
@ -699,7 +715,8 @@ Restrictions for this event:
|
|||||||
recognized by the flush operation anymore.
|
recognized by the flush operation anymore.
|
||||||
- Changes to fields of the passed entities are not recognized by
|
- Changes to fields of the passed entities are not recognized by
|
||||||
the flush operation anymore, use the computed change-set passed to
|
the flush operation anymore, use the computed change-set passed to
|
||||||
the event to modify primitive field values.
|
the event to modify primitive field values, e.g. use
|
||||||
|
``$eventArgs->setNewValue($field, $value);`` as in the Alice to Bob example above.
|
||||||
- Any calls to ``EntityManager#persist()`` or
|
- Any calls to ``EntityManager#persist()`` or
|
||||||
``EntityManager#remove()``, even in combination with the UnitOfWork
|
``EntityManager#remove()``, even in combination with the UnitOfWork
|
||||||
API are strongly discouraged and don't work as expected outside the
|
API are strongly discouraged and don't work as expected outside the
|
||||||
@ -769,9 +786,10 @@ An ``Entity Listener`` could be any class, by default it should be a class with
|
|||||||
|
|
||||||
- Different from :ref:`reference-events-implementing-listeners` an ``Entity Listener`` is invoked just to the specified entity
|
- Different from :ref:`reference-events-implementing-listeners` an ``Entity Listener`` is invoked just to the specified entity
|
||||||
- An entity listener method receives two arguments, the entity instance and the lifecycle event.
|
- An entity listener method receives two arguments, the entity instance and the lifecycle event.
|
||||||
- A callback method could be defined by naming convention or specifying a method mapping.
|
- The callback method can be defined by naming convention or specifying a method mapping.
|
||||||
- When the listener mapping is not given the parser will lookup for methods that match with the naming convention.
|
- When a listener mapping is not given the parser will use the naming convention to look for a matching method,
|
||||||
- When the listener mapping is given the parser won't lookup for any naming convention.
|
e.g. it will look for a public ``preUpdate()`` method if you are listening to the ``preUpdate`` event.
|
||||||
|
- When a listener mapping is given the parser will not look for any methods using the naming convention.
|
||||||
|
|
||||||
.. code-block:: php
|
.. code-block:: php
|
||||||
|
|
||||||
@ -784,8 +802,8 @@ An ``Entity Listener`` could be any class, by default it should be a class with
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
To define a specific event listener method
|
To define a specific event listener method (one that does not follow the naming convention)
|
||||||
you should map the listener method using the event type mapping.
|
you need to map the listener method using the event type mapping:
|
||||||
|
|
||||||
.. configuration-block::
|
.. configuration-block::
|
||||||
|
|
||||||
@ -863,9 +881,9 @@ you should map the listener method using the event type mapping.
|
|||||||
|
|
||||||
Entity listeners resolver
|
Entity listeners resolver
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
Doctrine invoke the listener resolver to get the listener instance.
|
Doctrine invokes the listener resolver to get the listener instance.
|
||||||
|
|
||||||
- An resolver allows you register a specific ``Entity Listener`` instance.
|
- A resolver allows you register a specific entity listener instance.
|
||||||
- You can also implement your own resolver by extending ``Doctrine\ORM\Mapping\DefaultEntityListenerResolver`` or implementing ``Doctrine\ORM\Mapping\EntityListenerResolver``
|
- You can also implement your own resolver by extending ``Doctrine\ORM\Mapping\DefaultEntityListenerResolver`` or implementing ``Doctrine\ORM\Mapping\EntityListenerResolver``
|
||||||
|
|
||||||
Specifying an entity listener instance :
|
Specifying an entity listener instance :
|
||||||
@ -933,12 +951,12 @@ process and manipulate the instance.
|
|||||||
.. code-block:: php
|
.. code-block:: php
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
$test = new EventTest();
|
$test = new TestEvent();
|
||||||
$metadataFactory = $em->getMetadataFactory();
|
$metadataFactory = $em->getMetadataFactory();
|
||||||
$evm = $em->getEventManager();
|
$evm = $em->getEventManager();
|
||||||
$evm->addEventListener(Events::loadClassMetadata, $test);
|
$evm->addEventListener(Events::loadClassMetadata, $test);
|
||||||
|
|
||||||
class EventTest
|
class TestEvent
|
||||||
{
|
{
|
||||||
public function loadClassMetadata(\Doctrine\ORM\Event\LoadClassMetadataEventArgs $eventArgs)
|
public function loadClassMetadata(\Doctrine\ORM\Event\LoadClassMetadataEventArgs $eventArgs)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user