Skip to content

Commit 2356ec0

Browse files
committed
refactored the event dispatcher guide
1 parent 1bedfa9 commit 2356ec0

File tree

11 files changed

+193
-192
lines changed

11 files changed

+193
-192
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
.. index::
2+
single: Event Dispatcher
3+
4+
How to extend a Class without using Inheritance
5+
===============================================
6+
7+
To allow multiple classes to add methods to another one, you can define the
8+
magic ``__call()`` method in the class you want to be extended like this::
9+
10+
class Foo
11+
{
12+
// ...
13+
14+
public function __call($method, $arguments)
15+
{
16+
// create an event named 'foo.method_is_not_found'
17+
// and pass the method name and the arguments passed to this method
18+
$event = new Event($this, 'foo.method_is_not_found', array('method' => $method, 'arguments' => $arguments));
19+
20+
// calls all listeners until one is able to implement the $method
21+
$this->dispatcher->notifyUntil($event);
22+
23+
// no listener was able to process the event? The method does not exist
24+
if (!$event->isProcessed()) {
25+
throw new \Exception(sprintf('Call to undefined method %s::%s.', get_class($this), $method));
26+
}
27+
28+
// return the listener returned value
29+
return $event->getReturnValue();
30+
}
31+
}
32+
33+
Then, create a class that will host the listener::
34+
35+
class Bar
36+
{
37+
public function addBarMethodToFoo(Event $event)
38+
{
39+
// we only want to respond to the calls to the 'bar' method
40+
if ('bar' != $event->get('method']) {
41+
// allow another listener to take care of this unknown method
42+
return false;
43+
}
44+
45+
// the subject object (the foo instance)
46+
$foo = $event->getSubject();
47+
48+
// the bar method arguments
49+
$arguments = $event->get('parameters');
50+
51+
// do something
52+
// ...
53+
54+
// set the return value
55+
$event->setReturnValue($someValue);
56+
57+
// tell the world that you have processed the event
58+
return true;
59+
}
60+
}
61+
62+
Eventually, add the new ``bar`` method to the ``Foo`` class::
63+
64+
$dispatcher->connect('foo.method_is_not_found', array($bar, 'addBarMethodToFoo'));
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
.. index::
2+
single: Event Dispatcher
3+
4+
How to customize a Method Behavior without using Inheritance
5+
============================================================
6+
7+
Doing something before or after a Method Call
8+
---------------------------------------------
9+
10+
If you want to do something just before, or just after a method is called, you
11+
can notify respectively an event at the beginning or at the end of the
12+
method::
13+
14+
class Foo
15+
{
16+
// ...
17+
18+
public function send($foo, $bar)
19+
{
20+
// do something before the method
21+
$event = new Event($this, 'foo.do_before_send', array('foo' => $foo, 'bar' => $bar));
22+
$this->dispatcher->notify($event);
23+
24+
// the real method implementation is here
25+
// $ret = ...;
26+
27+
// do something after the method
28+
$event = new Event($this, 'foo.do_after_send', array('ret' => $ret));
29+
$this->dispatcher->notify($event);
30+
31+
return $ret;
32+
}
33+
}
34+
35+
Modifying Method Arguments
36+
--------------------------
37+
38+
If you want to allow third party classes to modify arguments passed to a method
39+
just before that method is executed, add a ``filter`` event at the beginning of
40+
the method::
41+
42+
class Foo
43+
{
44+
// ...
45+
46+
public function render($template, $arguments = array())
47+
{
48+
// filter the arguments
49+
$event = new Event($this, 'foo.filter_arguments');
50+
$this->dispatcher->filter($event, $arguments);
51+
52+
// get the filtered arguments
53+
$arguments = $event->getReturnValue();
54+
// the method starts here
55+
}
56+
}
57+
58+
And here is a filter example::
59+
60+
class Bar
61+
{
62+
public function filterFooArguments(Event $event, $arguments)
63+
{
64+
$arguments['processed'] = true;
65+
66+
return $arguments;
67+
}
68+
}

cookbook/index.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ Dive into Symfony2 cookbook:
1414
testing/http_authorization
1515
testing/insulating_clients
1616
testing/profiling
17+
event_dispatcher/class_extension
18+
event_dispatcher/method_behavior
1719
profiler/data_collector
1820
symfony1
1921

cookbook/map.rst.inc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,7 @@
66
* :doc:`/cookbook/testing/http_authorization`
77
* :doc:`/cookbook/testing/insulating_clients`
88
* :doc:`/cookbook/testing/profiling`
9+
* :doc:`/cookbook/event_dispatcher/class_extension`
10+
* :doc:`/cookbook/event_dispatcher/method_behavior`
911
* :doc:`/cookbook/profiler/data_collector`
1012
* :doc:`/cookbook/symfony1`

guides/event/index.rst

Lines changed: 0 additions & 8 deletions
This file was deleted.

guides/event/recipes.rst

Lines changed: 0 additions & 176 deletions
This file was deleted.

guides/index.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ Dive into Symfony2 with the topical guides:
1414
security/index
1515
cache/index
1616
translation
17-
event/index
1817
bundles/index
1918
dependency_injection/index
2019
internals/index

0 commit comments

Comments
 (0)