diff --git a/docs/en/reference/events.rst b/docs/en/reference/events.rst index 1d5351563..72e396100 100644 --- a/docs/en/reference/events.rst +++ b/docs/en/reference/events.rst @@ -20,12 +20,12 @@ manager. $evm = new EventManager(); 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 dispatchEvent(EventTest::preFoo); - $evm->dispatchEvent(EventTest::postFoo); + $evm->dispatchEvent(TestEvent::preFoo); + $evm->dispatchEvent(TestEvent::postFoo); You can easily remove a listener with the ``removeEventListener()`` method. @@ -133,13 +133,12 @@ several reasons: - It is easy to read. - Simplicity. - Each method within an EventSubscriber is named after the - corresponding constant. If constant name and constant value differ, - you MUST use the new value and thus, your code might be subject to - codechanges when the value changes. This contradicts the intention - of a constant. + corresponding constant's value. If the constant's name and value differ + it contradicts the intention of using the constant and makes your code + harder to maintain. An example for a correct notation can be found in the example -``EventTest`` above. +``TestEvent`` above. .. _reference-events-lifecycle-events: @@ -159,7 +158,7 @@ the life-time of their registered entities. - prePersist - The prePersist event occurs for a given entity before the respective EntityManager persist operation for that 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 the entity has been made persistent. It will be invoked after the 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 listeners: - - 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 - methods that receives some kind of ``EventArgs`` instance which - give access to the entity, EntityManager or other relevant data. + methods that receives some kind of ``EventArgs`` instance. + +The EventArgs instance received by the listener gives access to the entity, +EntityManager and other relevant data. .. note:: @@ -224,10 +225,11 @@ listeners: Lifecycle Callbacks ------------------- -A lifecycle event is a regular event with the additional feature of -providing a mechanism to register direct callbacks inside the -corresponding entity classes that are executed when the lifecycle -event occurs. +Lifecycle Callbacks are defined on an entity class. They allow you to +trigger callbacks whenever an instance of that entity class experiences +a relevant lifecycle event. More than one callback can be defined for each +lifecycle event. Lifecycle Callbacks are best used for simple operations +specific to a particular entity class's lifecycle. .. code-block:: php @@ -277,8 +279,9 @@ event occurs. } } -Note that when using annotations you have to apply the -@HasLifecycleCallbacks marker annotation on the entity class. +Note that the methods set as lifecycle callbacks need to be public and, +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 can do it with the following. @@ -292,9 +295,13 @@ can do it with the following. name: type: string(50) lifecycleCallbacks: - prePersist: [ doStuffOnPrePersist, doOtherStuffOnPrePersistToo ] + prePersist: [ doStuffOnPrePersist, doOtherStuffOnPrePersist ] 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: .. code-block:: xml @@ -317,9 +324,14 @@ XML would look something like this: -You just need to make sure a public ``doStuffOnPrePersist()`` and -``doStuffOnPostPersist()`` method is defined on your ``User`` -model. +In XML the ``type`` of the lifecycle-callback entry is the event that you +are triggering on and the ``method`` is the method to call. The allowed event +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 @@ -335,15 +347,17 @@ model. // ... } + public function doOtherStuffOnPrePersist() + { + // ... + } + 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 ----------------------------------- @@ -375,8 +389,10 @@ Listening and subscribing to Lifecycle Events Lifecycle event listeners are much more powerful than the simple lifecycle callbacks that are defined on the entity classes. They -allow to implement re-usable behaviors between different entity -classes, yet require much more detailed knowledge about the inner +sit at a level above the entities and allow you to implement re-usable +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 *Implementing Event Listeners* section carefully if you are trying 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 the restrictions apply as well, with the additional restriction -that you do not have access to the EntityManager or UnitOfWork APIs -inside these events. +that (prior to version 2.4) you do not have access to the +EntityManager or UnitOfWork APIs inside these events. prePersist ~~~~~~~~~~ @@ -501,10 +517,10 @@ The following restrictions apply to ``prePersist``: - If you are using a PrePersist Identity Generator such as sequences the ID value will *NOT* be available within any PrePersist events. -- Doctrine will not recognize changes made to relations in a pre - persist event called by "reachability" through a cascade persist - unless you use the internal ``UnitOfWork`` API. We do not recommend - such operations in the persistence by reachability context, so do +- Doctrine will not recognize changes made to relations in a prePersist + event called by "reachability" through a cascade persist unless you + use the internal ``UnitOfWork`` API. We do not recommend such + operations in the persistence by reachability context, so do this at your own risk and possibly supported by unit-tests. preRemove @@ -593,13 +609,13 @@ mentioned sets. See this example: 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. You have to execute an additional call to ``$unitOfWork->computeChangeSet($classMetadata, $entity)``. - Changing primitive fields or associations requires you to 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)``. postFlush @@ -699,7 +715,8 @@ Restrictions for this event: recognized by the flush operation anymore. - Changes to fields of the passed entities are not recognized by 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 ``EntityManager#remove()``, even in combination with the UnitOfWork 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 - 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. -- When the listener mapping is not given the parser will lookup for methods that match with the naming convention. -- When the listener mapping is given the parser won't lookup for any naming convention. +- The callback method can be defined by naming convention or specifying a method mapping. +- When a listener mapping is not given the parser will use the naming convention to look for a matching method, + 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 @@ -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 -you should map the listener method using the event type mapping. +To define a specific event listener method (one that does not follow the naming convention) +you need to map the listener method using the event type mapping: .. configuration-block:: @@ -863,9 +881,9 @@ you should map the listener method using the event type mapping. 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`` Specifying an entity listener instance : @@ -933,12 +951,12 @@ process and manipulate the instance. .. code-block:: php getMetadataFactory(); $evm = $em->getEventManager(); $evm->addEventListener(Events::loadClassMetadata, $test); - class EventTest + class TestEvent { public function loadClassMetadata(\Doctrine\ORM\Event\LoadClassMetadataEventArgs $eventArgs) {