From 4b7c8c2e24aba8e66e58887764c0dbb7926adfbc Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 8 Apr 2014 17:18:14 +0200 Subject: [PATCH 1/5] [Book][Security] constants are defined in the SecurityContextInterface --- book/security.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/book/security.rst b/book/security.rst index b1e7aebbe75..fb5a0729733 100644 --- a/book/security.rst +++ b/book/security.rst @@ -436,7 +436,7 @@ Next, create the controller that will display the login form:: use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; - use Symfony\Component\Security\Core\SecurityContext; + use Symfony\Component\Security\Core\SecurityContextInterface; class SecurityController extends Controller { @@ -445,20 +445,20 @@ Next, create the controller that will display the login form:: $session = $request->getSession(); // get the login error if there is one - if ($request->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) { + if ($request->attributes->has(SecurityContextInterface::AUTHENTICATION_ERROR)) { $error = $request->attributes->get( - SecurityContext::AUTHENTICATION_ERROR + SecurityContextInterface::AUTHENTICATION_ERROR ); } else { - $error = $session->get(SecurityContext::AUTHENTICATION_ERROR); - $session->remove(SecurityContext::AUTHENTICATION_ERROR); + $error = $session->get(SecurityContextInterface::AUTHENTICATION_ERROR); + $session->remove(SecurityContextInterface::AUTHENTICATION_ERROR); } return $this->render( 'AcmeSecurityBundle:Security:login.html.twig', array( // last username entered by the user - 'last_username' => $session->get(SecurityContext::LAST_USERNAME), + 'last_username' => $session->get(SecurityContextInterface::LAST_USERNAME), 'error' => $error, ) ); From 98de95a1a7c4c35b293e5dab001d0a361ea8ba96 Mon Sep 17 00:00:00 2001 From: Charles Sarrazin Date: Fri, 21 Mar 2014 17:21:01 +0100 Subject: [PATCH 2/5] [Form] Added documentation for Form Events Added initial documentation for Form Events: * List of events * Use cases for each event * Description of the events workflow * Flow charts for illustration Updated PR with comments from @WouterJ and @MyKiwi Took into account @cordoval's feedback Additional improvements * Added more examples from the Form component's code * Moved the cookbook's 'register a subscriber using a callable' section into the form events documentation Took into account @xabbuh's feedback Fixed missing new line Removed superfluous comma. Updated from feedback Moved the list of events down in the listener and subscriber section * Formatted the list as a table, exposing the constant values; * Added references to the form event information table; * Added caution sections for actions that should prevented while in each event. Added the form_events link in the components map file, a.k.a. 'Added the missing link' Added missing newlines Added cross-reference in the form events cookbook Updated based on Luis' feedback Added tables describing the form and event values: * Model data * Normalized data * View data * Event data Small fixes Updated a few wordings to make them more clear Changed important directive to caution Removed sidebar section about form extensions. Renamed ``{EVENT}`` to ``FormEvents::{EVENT}``, and added code snippet Last small changes Fixed underline too short --- components/form/form_events.rst | 398 ++++++++++++++++++++ components/form/index.rst | 1 + components/map.rst.inc | 1 + cookbook/form/dynamic_form_modification.rst | 23 +- images/components/form/general_flow.png | Bin 0 -> 10427 bytes images/components/form/set_data_flow.png | Bin 0 -> 8588 bytes images/components/form/submission_flow.png | Bin 0 -> 10285 bytes 7 files changed, 404 insertions(+), 19 deletions(-) create mode 100644 components/form/form_events.rst create mode 100644 images/components/form/general_flow.png create mode 100644 images/components/form/set_data_flow.png create mode 100644 images/components/form/submission_flow.png diff --git a/components/form/form_events.rst b/components/form/form_events.rst new file mode 100644 index 00000000000..1b81360f529 --- /dev/null +++ b/components/form/form_events.rst @@ -0,0 +1,398 @@ +.. index:: + single: Forms; Form Events + +Form Events +=========== + +The Form component provides a structured process to let you customize your +forms, by making use of the :doc:`EventDispatcher ` +component. Using form events, you may modify information or fields at +different steps of the workflow: from the population of the form to the +submission of the data from the request. + +Registering an event listener is very easy using the Form component. + +For example, if you wish to register a function to the +``FormEvents::PRE_SUBMIT`` event, the following code lets you add a field, +depending on the request' values:: + + // ... + + use Symfony\Component\Form\FormEvent; + use Symfony\Component\Form\FormEvents; + + $listener = function (FormEvent $event) { + // ... + }; + + $form = $formFactory->createBuilder() + // add form fields + ->addEventListener(FormEvents::PRE_SUBMIT, $listener); + + // ... + +The Form Workflow +----------------- + +The Form Submission Workflow +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. image:: /images/components/form/general_flow.png + :align: center + +1) Pre-populating the Form (``FormEvents::PRE_SET_DATA`` and ``FormEvents::POST_SET_DATA``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. image:: /images/components/form/set_data_flow.png + :align: center + +Two events are dispatched during pre-population of a form, when +:method:`Form::setData() ` +is called: ``FormEvents::PRE_SET_DATA`` and ``FormEvents::POST_SET_DATA``. + +A) The ``FormEvents::PRE_SET_DATA`` Event +......................................... + +The ``FormEvents::PRE_SET_DATA`` event is dispatched at the beginning of the +``Form::setData()`` method. It can be used to: + +* Modify the data given during pre-population; +* Modify a form depending on the pre-populated data (adding or removing fields dynamically). + +:ref:`Form Events Information Table` + ++-----------------+-----------+ +| **Data type** | **Value** | ++-----------------+-----------+ +| Model data | ``null`` | ++-----------------+-----------+ +| Normalized data | ``null`` | ++-----------------+-----------+ +| View data | ``null`` | ++-----------------+-----------+ + +.. caution:: + + During ``FormEvents::PRE_SET_DATA``, + :method:`Form::setData() ` + is locked and will throw an exception if used. If you wish to modify + data, you should use + :method:`FormEvent::setData() ` + instead. + +.. sidebar:: ``FormEvents::PRE_SET_DATA`` in the Form component + + The ``collection`` form type relies on the + :class:`Symfony\\Component\\Form\\Extension\\Core\\EventListener\\ResizeFormListener` + subscriber, listening to the ``FormEvents::PRE_SET_DATA`` event in order + to reorder the form's fields depending on the data from the pre-populated + object, by removing and adding all form rows. + +B) The ``FormEvents::POST_SET_DATA`` Event +.......................................... + +The ``FormEvents::POST_SET_DATA`` event is dispatched at the end of the +:method:`Form::setData() ` +method. This event is mostly here for reading data after having pre-populated +the form. + +:ref:`Form Events Information Table` + ++-----------------+------------------------------------------------------+ +| **Data type** | **Value** | ++-----------------+------------------------------------------------------+ +| Model data | Model data injected into ``setData()`` | ++-----------------+------------------------------------------------------+ +| Normalized data | Model data transformed using a model transformer | ++-----------------+------------------------------------------------------+ +| View data | Normalized data transformed using a view transformer | ++-----------------+------------------------------------------------------+ + +.. sidebar:: ``FormEvents::POST_SET_DATA`` in the Form component + + The :class:`Symfony\\Component\\Form\\Extension\\DataCollector\\EventListener\\DataCollectorListener` + class is subscribed to listen to the ``FormEvents::POST_SET_DATA`` event + in order to collect information about the forms from the denormalized + model and view data. + +2) Submitting a Form (``FormEvents::PRE_SUBMIT``, ``FormEvents::SUBMIT`` and ``FormEvents::POST_SUBMIT``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. image:: /images/components/form/submission_flow.png + :align: center + +Three events are dispatched when +:method:`Form::handleRequest() ` +or :method:`Form::submit() ` are +called: ``FormEvents::PRE_SUBMIT``, ``FormEvents::SUBMIT``, +``FormEvents::POST_SUBMIT``. + +A) The ``FormEvents::PRE_SUBMIT`` Event +....................................... + +The ``FormEvents::PRE_SUBMIT`` event is dispatched at the beginning of the +:method:`Form::submit() ` method. + +It can be used to: + +* Change data from the request, before submitting the data to the form. +* Add or remove form fields, before submitting the data to the form. + +:ref:`Form Events Information Table` + ++-----------------+------------------------------------------+ +| **Data type** | **Value** | ++-----------------+------------------------------------------+ +| Model data | Same as in ``FormEvents::POST_SET_DATA`` | ++-----------------+------------------------------------------+ +| Normalized data | Same as in ``FormEvents::POST_SET_DATA`` | ++-----------------+------------------------------------------+ +| View data | Same as in ``FormEvents::POST_SET_DATA`` | ++-----------------+------------------------------------------+ + +.. sidebar:: ``FormEvents::PRE_SUBMIT`` in the Form component + + The :class:`Symfony\\Component\\Form\\Extension\\Core\\EventListener\\TrimListener` + subscriber subscribes to the ``FormEvents::PRE_SUBMIT`` event in order to + trim the request's data (for string values). + The :class:`Symfony\\Component\\Form\\Extension\\Csrf\\EventListener\\CsrfValidationListener` + subscriber subscribes to the ``FormEvents::PRE_SUBMIT`` event in order to + validate the CSRF token. + +B) The ``FormEvents::SUBMIT`` Event +................................... + +The ``FormEvents::SUBMIT`` event is dispatched just before the +:method:`Form::submit() ` method +transforms back the normalized data to the model and view data. + +It can be used to change data from the normalized representation of the data. + +:ref:`Form Events Information Table` + ++-----------------+-------------------------------------------------------------------------------------+ +| **Data type** | **Value** | ++-----------------+-------------------------------------------------------------------------------------+ +| Model data | Same as in ``FormEvents::POST_SET_DATA`` | ++-----------------+-------------------------------------------------------------------------------------+ +| Normalized data | Data from the request reverse-transformed from the request using a view transformer | ++-----------------+-------------------------------------------------------------------------------------+ +| View data | Same as in ``FormEvents::POST_SET_DATA`` | ++-----------------+-------------------------------------------------------------------------------------+ + +.. caution:: + + At this point, you cannot add or remove fields to the form. + +.. sidebar:: ``FormEvents::SUBMIT`` in the Form component + + The :class:`Symfony\\Component\\Form\\Extension\\Core\\EventListener\\ResizeFormListener` + subscribes to the ``FormEvents::SUBMIT`` event in order to remove the + fields that need to be removed whenever manipulating a collection of forms + for which ``allow_delete`` has been enabled. + +C) The ``FormEvents::POST_SUBMIT`` Event +........................................ + +The ``FormEvents::POST_SUBMIT`` event is dispatched after the +:method:`Form::submit() ` once the +model and view data have been denormalized. + +It can be used to fetch data after denormalization. + +:ref:`Form Events Information Table` + ++-----------------+---------------------------------------------------------------+ +| **Data type** | **Value** | ++-----------------+---------------------------------------------------------------+ +| Model data | Normalized data reverse-transformed using a model transformer | ++-----------------+---------------------------------------------------------------+ +| Normalized data | Same as in ``FormEvents::POST_SUBMIT`` | ++-----------------+---------------------------------------------------------------+ +| View data | Normalized data transformed using a view transformer | ++-----------------+---------------------------------------------------------------+ + +.. caution:: + + At this point, you cannot add or remove fields to the form. + +.. sidebar:: ``FormEvents::POST_SUBMIT`` in the Form component + + The :class:`Symfony\\Component\\Form\\Extension\\DataCollector\\EventListener\\DataCollectorListener` + subscribes to the ``FormEvents::POST_SUBMIT`` event in order to collect + information about the forms. + The :class:`Symfony\\Component\\Form\\Extension\\Validator\\EventListener\\ValidationListener` + subscribes to the ``FormEvents::POST_SUBMIT`` event in order to + automatically validate the denormalized object, and update the normalized + as well as the view's representations. + +Registering Event Listeners or Event Subscribers +------------------------------------------------ + +In order to be able to use Form events, you need to create an event listener +or an event subscriber, and register it to an event. + +The name of each of the "form" events is defined as a constant on the +:class:`Symfony\\Component\\Form\\FormEvents` class. +Additionally, each event callback (listener or subscriber method) is passed a +single argument, which is an instance of +:class:`Symfony\\Component\\Form\\FormEvent`. The event object contains a +reference to the current state of the form, and the current data being +processed. + +.. _component-form-event-table: + ++--------------------+-------------------------------+------------------+ +| **Name** | ``FormEvents`` **Constant** | **Event's data** | ++--------------------+-------------------------------+------------------+ +| form.pre_set_data | ``FormEvents::PRE_SET_DATA`` | Model data | ++--------------------+-------------------------------+------------------+ +| form.post_set_data | ``FormEvents::POST_SET_DATA`` | Model data | ++--------------------+-------------------------------+------------------+ +| form.pre_bind | ``FormEvents::PRE_SUBMIT`` | Request data | ++--------------------+-------------------------------+------------------+ +| form.bind | ``FormEvents::SUBMIT`` | Normalized data | ++--------------------+-------------------------------+------------------+ +| form.post_bind | ``FormEvents::POST_SUBMIT`` | View data | ++--------------------+-------------------------------+------------------+ + +.. versionadded:: 2.3 + + Before Symfony 2.3, ``FormEvents::PRE_SUBMIT``, ``FormEvents::SUBMIT`` + and ``FormEvents::POST_SUBMIT`` were called ``FormEvents::PRE_BIND``, + ``FormEvents::BIND`` and ``FormEvents::POST_BIND``. + +.. caution:: + + The ``FormEvents::PRE_BIND``, ``FormEvents::BIND`` and + ``FormEvents::POST_BIND`` constants will be removed in version 3.0 of + Symfony. + The event names still keep their original values, so make sure you use the + ``FormEvents`` constants in your code for forward compatibility. + +Event Listeners +~~~~~~~~~~~~~~~ + +An event listener may be any type of valid callable. + +Creating and binding an event listener to the form is very easy:: + + // ... + + use Symfony\Component\Form\FormEvent; + use Symfony\Component\Form\FormEvents; + + $form = $formFactory->createBuilder() + ->add('username', 'text') + ->add('show_email', 'checkbox') + ->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) { + $user = $event->getData(); + $form = $event->getForm(); + + if (!$user) { + return; + } + + // Check whether the user has chosen to display his email or not. + // If the data was submitted previously, the additional value that is + // included in the request variables needs to be removed. + if (true === $user['show_email']) { + $form->add('email', 'email'); + } else { + unset($user['email']); + $event->setData($user); + } + }) + ->getForm(); + + // ... + +When you have created a form type class, you can use one of its methods as a +callback for better readability:: + + // ... + + class SubscriptionType extends AbstractType + { + public function buildForm(FormBuilderInterface $builder, array $options) + { + $builder->add('username', 'text'); + $builder->add('show_email', 'checkbox'); + $builder->addEventListener(FormEvents::PRE_SET_DATA, array($this, 'onPreSetData')); + } + + public function onPreSetData(FormEvent $event) + { + // ... + } + } + +Event Subscribers +~~~~~~~~~~~~~~~~~ + +Event subscribers have different uses: + +* Improving readability; +* Listening to multiple events; +* Regrouping multiple listeners inside a single class. + +.. code-block:: php + + use Symfony\Component\EventDispatcher\EventSubscriberInterface; + use Symfony\Component\Form\FormEvent; + use Symfony\Component\Form\FormEvents; + + class AddEmailFieldListener implements EventSubscriberInterface + { + public function getSubscribedEvents() + { + return array( + FormEvents::PRE_SET_DATA => 'onPreSetData', + FormEvents::PRE_SUBMIT => 'onPreSubmit', + ); + } + + public function onPreSetData(FormEvent $event) + { + $user = $event->getData(); + $form = $event->getForm(); + + // Check whether the user from the initial data has chosen to + // display his email or not. + if (true === $user->isShowEmail()) { + $form->add('email', 'email'); + } + } + + public function onPreSubmit(FormEvent $event) + { + $user = $event->getData(); + $form = $event->getForm(); + + if (!$user) { + return; + } + + // Check whether the user has chosen to display his email or not. + // If the data was submitted previously, the additional value that + // is included in the request variables needs to be removed. + if (true === $user['show_email']) { + $form->add('email', 'email'); + } else { + unset($user['email']); + $event->setData($user); + } + } + } + +To register the event subscriber, use the addEventSubscriber() method:: + + // ... + + $form = $formFactory->createBuilder() + ->add('username', 'text') + ->add('show_email', 'checkbox') + ->addEventSubscriber(new AddEmailFieldListener()) + ->getForm(); + + // ... diff --git a/components/form/index.rst b/components/form/index.rst index 5ea5add00f6..a2de93c6245 100644 --- a/components/form/index.rst +++ b/components/form/index.rst @@ -6,3 +6,4 @@ introduction type_guesser + form_events diff --git a/components/map.rst.inc b/components/map.rst.inc index fbc1872afb8..88909e4301e 100644 --- a/components/map.rst.inc +++ b/components/map.rst.inc @@ -68,6 +68,7 @@ * :doc:`/components/form/index` * :doc:`/components/form/introduction` + * :doc:`/components/form/form_events` * :doc:`/components/form/type_guesser` * :doc:`/components/http_foundation/index` diff --git a/cookbook/form/dynamic_form_modification.rst b/cookbook/form/dynamic_form_modification.rst index 2add7ddd759..e7109617793 100644 --- a/cookbook/form/dynamic_form_modification.rst +++ b/cookbook/form/dynamic_form_modification.rst @@ -24,6 +24,10 @@ Example: on a registration form, you have a "country" field and a "state" field which should populate dynamically based on the value in the "country" field. +If you wish to learn more about the basics behind form events, you can +take a look at the :doc:`Form Events ` +documentation. + .. _cookbook-form-events-underlying-data: Customizing your Form based on the underlying Data @@ -134,25 +138,6 @@ the event listener might look like the following:: :method:`FormInterface::add ` was added in Symfony 2.2. -.. note:: - You can of course use any callback type instead of a closure, e.g. a method - call on the ``ProductType`` object itself for better readability:: - - // ... - class ProductType extends AbstractType - { - public function buildForm(FormBuilderInterface $builder, array $options) - { - // ... - $builder->addEventListener(FormEvents::PRE_SET_DATA, array($this, 'onPreSetData')); - } - - public function onPreSetData(FormEvent $event) - { - // ... - } - } - .. note:: The ``FormEvents::PRE_SET_DATA`` line actually resolves to the string diff --git a/images/components/form/general_flow.png b/images/components/form/general_flow.png new file mode 100644 index 0000000000000000000000000000000000000000..31650e52af6f87244424b62856ebdcb5078c7454 GIT binary patch literal 10427 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 U8J=Zj{G$*9sp+WJs#w1J4|C!=>Hq)$ literal 0 HcmV?d00001 diff --git a/images/components/form/set_data_flow.png b/images/components/form/set_data_flow.png new file mode 100644 index 0000000000000000000000000000000000000000..3cd4b1e2f7bf878d3ec455eda8eb9069584ff252 GIT binary patch literal 8588 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

<6Kw!{xy)=)~3Acn+iP= zTibg(GT0s=1y6PtQIMQ1M+r7pX&@Z`CtcqoHRF<_%}+pUP7bR4U+8+o7SfS-NBX|G zgM01gVVbO%jVRY*6!!i_6Xl8phciXO=L*%;vCs0f^YQpM7CRX*4(&HN3oa#}Ww)N! zl70q(D1KesT`chyF2^(bo?I4GRZmpI_og7%{EnN!+5MFL=Vz+rE4_^P4p;A#z9hVD znrPU@wo9ud!2Jlj6Cpvy71lH1`Nj*VP)qZcnil?1lsce?FZj}az-{YymoTLCbDBEtM6p+ zX$_fFK(=Ew)VqeNw94G_GjAGFhwW?a?rZ%7rB@YHS1Y-w6k1l4zKjs7qI*}goSS?V zIFQoG=G)fcuAh({0}I1aU{FZ0iivklm;<+z^d0}#@$)`A*RB~G1}+$y{rS$GbjO!+ zG{QPk;4cM>z|ilk3wQAa^K~6fDRe-8Z|F&T_nyk78#ZSzYq=@lVw_{0BwJ@$XpYNf5O!(tefiZz}z-}|Rjt*NG`TB~CH?mqy=(0juG literal 0 HcmV?d00001 diff --git a/images/components/form/submission_flow.png b/images/components/form/submission_flow.png new file mode 100644 index 0000000000000000000000000000000000000000..a3c6e9cfb90ce85d38337a1a4b32b15fc8f5d49c GIT binary patch literal 10285 zcmeHtWl&tvvMv@NBv^2V;0YQWg6jky2p%-JCAeFV;4oNl8{B0exJz(mkf4*`u7k_m z)vdbkocn&fe{cWTt9tESwR^4Iy}G}zJ5obU5f_IN2L%NM7oa2uL_tBdML|JJ z#zy}$b1E&uf`WpMqM@QKk3=H(_VyqUNN{klzP`SkoZQ{rT~SdHCnx8hH~ahhNl8ha zoSbB2WTK;^rKP3m=;(rif)EGb4iG9TE)WP25CANava3?3%qBtykTg-4E8fvj-vcLyOr zdP#b0a%>I|hX8269&+yjd7&JjjQI?+71_$c!I6*5zeC zj7}9Na*o=}Yu?U}o64S}nibAWnFFup4zt8dhC9m)SC}#@bs9PYg?_Zs(9YF#-cA%v zJV6PQ$=6^b#`zb+UTGxwdL}IBDZ}nGfGBx>K>tq3hyTsfl_oA;EI@p39>iuyaDlE) zf7BME>KFr8K0nSbVZ>WR@HBY(e#;IAM|csz ze2)t;0IVBai3pzPUtf;pp|WGB^tMc~;6#Ke8!nSSB1I5-r+wR|B+3AN4q*KI03c%NVq~%v!BxUetCfm-5SKCZ%l2bCHnAY`xSI0C_$l&D0 zD&`$tF3X=LAWk$Z#Ii4j4d+bl>zu054Wna~exkjRPNZg_-BBs$lZrJ6Pt?=CWt$$DKPxe?5_kUOyCDeyoAmkRz!t^6$_OXeAX<> zcy8G?-9TL7-m)<~`61*4(6mDWM<0HJq6w?O=qM{q1gsEbEuV6+>GRTG1DJVbO665D zV@e2!R~xObs^Q~iAgY|{m3$N%r`EGThI2zmw2jJQEhSKsfA1)Om)$dsJ(1x*q53yH0IGwj;W!H z<$?Z`C|a47u0%-EA9w+Z=D-=#F>v$|-9;$mD3_?_s=QUuaRT!mpXR0dW%Z=)$O&K-7IuTQvCaVSIBupi^PRFUpX^v7|LqtGEQJ=yRq0&<`kHeuH&4 zsP4o2QzG~5m4$M~c3+e=dg;ksyC(2y3Rxc13K$-!!=A5Z?++PP%BE}LKzkpeLOhF8 z0ov6r6x6cUfcy|IR;|oebzUO5FRMbksa*+xhnh~9Pv0@0^bP0c8kpcp;Ci8v^-FB4 zCu=@&<2f6+DvY`OOkzN(<*ELO0(8V;u~1nZrQ+bx;&q;{aOsfB4X+bFi5A**S$FgG zci*RZ9M~!#K3&R(X^C@Y;XKXf zqD8N)aeAudOcwXBYt_C})|e-g5G)WhcEtO$>>Sos(cYRKNOWi|V{BBC4N=pv@E73H zgZOR&1BM z#tTtU2fHsx z=)+OwUXZezdwe~b?iqUhRqHTTG&?Cc{RfRVE3}w2vx6rJE^of$s&Y8SFelQCP7Ovx? zqPh1|d09#uH5-pw(lM6HV+xLjs~yewg*dwEoH!2Vlr*pb;??8ciDgskc7( z>-<;lBl0}40HxElq@X*kKQ7I<%UD@Jjxa6sC~P$pSA={8<5!mx%gkm8wZ#@5-mJJ_ z=f;%hu&cJb6>7-vr~5^k^}Q{B5Ztypcy#$CTt^m)1w+uO2l=H2xX9pt$LA$RZ7!|T z3Ft}w2rH|$j5NU#!JhJ^));T#oN~sTGH~qOXy0}f(gaB$_?EjR2}lDgR3+G@IYEgC zRA$9{cMsa)aum93hd0wv9B-$mtfTSd)ZX8j!^m(o3e^)4(g4?(XB8%BXPx>On2_gE zuV0e1!FsKvJvd%v1ZkAM-2Jj^C8l;3lr>(}wpOmTxIaE+NGX?n8_5Ea_@)NX_%Qyy zCpsj{CU*~AxZK?H?v2_wQ0%DXh2)4l6iYL_r?;;`!Y23jSv=4cbZ7B^KKqhBMQ!{u zYe5E7KlUy~QE{Vv5XG!hu`uIKX36_&m5R2$n4;x^1Gxd}OJ88PO-Q*`A|8b#_D1de z1gVt?#qsA-0sp+_N4xiMGW{JHi!LM2_|-4V@3OCUrvF%lh-O)x&<^P8Q;k#WWJv=1 zOWf%A1If!eGKCHWvBXZO*Cg#HTcoUyGo>xZ#ntN}26+b+g$RPznX0*}=w?4y4-n`4 zTP2cetHrUMLk;9fgf(g`V~aMc!TgK--C4b$n7H~*>G;XvP;0-8Z_;0S3e<^H8waydY>Wj$6Rf+oXr$Z?=la5yrB%p z=!n3nci3@?Cw&$9tbr5=6A1d@|1GaNNF8a{RTyV(sP&XMtc)=EDal)v6t>EZvnK#6 z^B2!>GSmhzQ@j$@Q%KkEaz4p_Ss7Wcav**$HzeHgOXg;I``$Nb$ET;vtBCClGhGxV zu4~lBzIMhZukP==fdg8~1mE@)x=CJOW$|RaYa_l{1@gy%l^qTEsj-<1ioMe|`P4K$ zOrg3QD@5RunY>>-n6HRRa#;fw&JIa6Uyf!@R{k&}2L96Rn=TA1*y64F_W7m0PT?kGGSF^q_XkfaDPnXB0{0 z*Au(zF12$bUJnEQo%-*Oi@+(UwuHWWWb7b0f@dQ3T$)Kv1V_KGo$fsG2r}r^^ zQr~H^3q3#JMyX9}E)jAxqHjiq4WBI$JfWGyD7U(XHE(*%jbos`7X2)REm2}&16#Rs z8{Z?x*=Gqfy71D}Ym&K1*P0jKu2g@ew)u0dOK(7Em{R%#oZY0%g^ zUMJPe^{Bu88|EJJWU6Uv z*3xb7&Ln+Fi-{^Wu4m`%9EQyN1~{T$h%@5Rd5Ljn^3a_~_pyj~ zv>PQzu@b0V*RO)UP1eNr!!!hBNe1%e(2K_XQDBwybPz^DAE;GQr;ahu-830EP@+I@ z`H8q)twF?Bfc1*O_15pQ4OVPXbrMS9ZM;nzC9-2?spy`J?j8A!WPjP$q z5^c`ar>fjqQz(Vksq*g3&XS3U7lsAME>2162d4C8eGQT2SetGvCPaQ4|t?R67f{l37UT0hTJg+%~ zafFn9yV|iKBZyTfe570DLeW;yYV=|Iwg6~AyU%q-{g(BLLL|s&n*VyR`HionJWH1X zlqSh|!QFKt1Uss02IASE;Z0UQ?QGbM%)c=m9zSC{*VcG@r66P9Yn%oUhha~^_O@!G9CooKkwRQOw5=r zSu%9BTb8sh2<(Fqa!8QaI!i*-F?xQ69Kni@-`~K%&XlG|0d-2%2HRcU-`BB8qwNbe z8hy3T`*8a?q>1Tca)77wpZqRN|heuZ<1=H@WJuE8_7>^d%EN%W86OJ&}yB;bstb`tP-IOnK5dI zJ1kNKg<4()P_iO@L(*;Xk@v3R4R%3+UEc8@Xi*Nzchz!yKoCdc5QZmF4@ybu8HD@#+WVjGLmq}Nk7Ic8{UFX=bWzsXeB1_QEp$Z zGyu?TyI!9*He8H3%dFcwYwlOUtNb3uv2(&ridVtDBff88ip)8d=##S1@$RZknRlD? z$eSrOGQ_dB}s0)V^qD)rJn`o{x=d#%J_o>rJ#&| zkRX-%@?NAiYq1A4OH;7tJ6zI4#7-l}(td-E6mKNRqN|Wf|52Al}5QE(uN{V0eAhyT?10O^e|FM zVdIT_(cCrtmg#h!$Lc(+rv1;hpQW9?UY%FY>VKD-lX?KOZ?6sVGM`~~GwXbzIxPau z%XYN)l5q{41meI$skm>1epTnSjeLo|p(~E#7jlctkR)};*|vJBd*eHFDU|tX1o31j zxw^d;GQWCWo!D_U^0GU{86xP%zK-hLesBPX{V?=Nxu^FpI!$eJ2^fqaThSO}#jBnw z#yauCqQ1LnYgIf$$Cw@sdDBMhYmGEhehF1tOm-q?{`yex`ZkK?m z!_dN&?{{(wpaTDF_d+Yrra(+}q*Gj?4XGFH!Y&77rAe54to3B0c=4-A_*_tk7ctDA zj?%i)OtjW#<89Nbg<-0i>|f|65{5fnj$Au~%V(hNY#S z`-0BOvI{*n>KdLOr74|xbl3=1a-%%S6sJ}`rrlqc*FDJMOo(R04j$pTEsfdbV6-w-mRI~HsL4)jqivUB zAd)-vRlA*M2CZs`?MQb^dX_r1p)ct5He2hDpcl%{#0DaYuPV5bY2;b7DS9jSE$m_Z z^mXqg^~V(AmHg`FjKfRGr5kp_QHg`Av+hdmuX6UARJ~h(XPI)$YK07gxKM;*hC&&O zC|6sKfkI|ynrcLhOuu960~wusb28eqWE3VlMW7jlwul1-#kV4nh$Vg`mg%~Ck^{{w_Ki>4eaVgA?Q=hrLVbF6=no{WtD>#NbZ@XJWT%1x&pCXA zm*tQz#nrb!kKNkr<|vz1=nOdzapqxuiHF@&h9M=uhJ9xe>d*oVFt?Gk&Ki=@YkC=k zPemD8L?g?SQV>I|?;%LbG^d;1*J6P27@>!=%*yv+w>_HUi^7^b z=LF?YjZ0D6`?1PbXA7SLGUyB!o^#hTe?F4O*r_bQqdypb8%Kii_1`dqyI^p|k}e4@ zAYLJ{{-S>rXok=n*=73h{5;&txO$LiWVrGFlrK3QfI05l>Lw{N!>5I=x z#?cbN;~v2iwX&Xtz@*6ix!HdNi9Fcqb(wa0hw>jRIuGz0nw4wL~Uj9#aCXb)V;?n z+AQ;03bzZgZA6hO)y0tr*NE$iyNsLL;UtOWo56o^|UXWkaWjEEJ8hIFQDEL`AwPWn5UvEFz7c}wG*BI{#AiQ4n z;+t3YSNPR4aF3tJ|Iy*nXz2vum@)|u1zs1D32$Drn>W+bzQrG)^Dn`ZhJW@_t^v`3 zJNdaxl9qlcc+QK@ukm$0*IJG+5}|W;F>1zhpQrhV9WVB*CP3&AY)BRe5_&V?0S)JU zNYWLa)>wBQDKgu@^05>j3=s8N=tA9I5Ip|;<<55aM0>jB)W|S0oM@WH>*7)p{IfV8 z0==K}taf%Ly&QLzDCsg@dv;U=yo@!~6R8n{+OxAbQc_6Pl-dCuLm#LiN+O3)|uj_l=jfpt(1mm8J)$C`nK?Gqd-^9sfKE;3pZ$(8T-w@3rL^o616QgK!QCN8#O74RpXa97=dEnJPQiA z6qM6qQMx&v;AjhPO-!QZB%VT~K#YYX(^17Q(x)7D)V@}Id+C()OhNx5qd$PWo5gILD~;p@ z|GW+g^_Qh)YJv-sC!=}YT_TETt~4^_;ik8Ko_x>I*raXKohz#Z4zqeYl&sjXnWdnf z6?m^~4Z60k{n)-}V`2FjY*keFS;uubp?$%AJfYQWawADTuaMA)&}R&9=YVEu)+0EB9RxWc7S)?B*Cp?Y%w?ywzn9gZ5K_1*rj&eir2xP=4c8J< zg~=~T3J;KGu>7g72{h+~yct)n96QOx%!;<3Z*quP^wv@%0Ms&CK%itAAVJG1Rsdx+e&*?2=WAtOReGZp#(UZD!s}E=RMz`b z@oN(Q_|5sT31389^{|y zU5E}}+=c_l@>Xnwx0~JROJYg3&*E=-pCl6Tt?oE{sF-IY^qWKtzL!L%%|qo3N^v={ zxm@W`qSMg7a$!)Q+7Fqz^IX?muEgSfJZAolyE^PrAqm%Q&%GM)F;cPyk9K+&X>pSo z@h(AAy12I*#Nu7KABC+|t(&&vqvhG1P6%@*rM8A1;=Vx{_v^^1#dsgK@fjnV`h zZCav4STl0@re~wGe(t&p;b`MIr-thi3kht_uW!DtIhhrJY_zw(>E<>y6Kz-A@hJZ` zOJO#_GAW}%7WU<&=CIU(E$ZNFp)x^;o}KX?iJZ))mMY%||a8qD*r z8=m3nW!4qPqP4X%uA3TVv!$?9%T2W+Zu{MCT5b4PNN{fGqz`Pe(v=~oFD2Bva`7ZP zxUf2Dj3kkc6Xh3&mn7fw4*fD*?!|Txt#)8YZqRJ>{ERb@oS+mA-;m5I7-Gf z9Gls`MWwNZAMbuoj*+)7&sNvmp?$M`eBs3uck5gGuK4)E&*7btSmE!nYE+O~ch23P zkdd_ZCu}6E)m%_v0PuT7vUVj2Kx*NCf`$M6IpfgHS5T+F4KH1xBsKp|A`@rD>hDi1 zlH_ks2pwmA1AMT@bIwC^CD6-C7TbKZ^;_{urNate#^?W&Gy6{l?Y}3?{|71ff2H8c z5~`g{-t#kwQ_BAXUx!UArbAoOqs@#}LRPY$Ed3K-AF7xyY05XS(eD!eXeb!DbrDZI z{rG=hX+2*a`vWDIS)YE0Ml&(xGYE1hs>~03||aMxu_lAJ=&6T^M7% z(3|tRGB~HGfV^!{rY@DJM`16f3XHhj+H3^*6x@rX;<~u=4ygPLM+)92GVz{L}3Unq2I>*FL6C zqMM)0X<0F#_Wj6A$tT+B>^@D)IMh4mIb49Qlu#d+ASQTWH;I*8KyWPJc? z^!@3>k5?*m=SoAp>A2Ov@s3<}!(Ws3=YsYmTdpwg;|F#of6pgh_(dQqD3e*&$!O#o zV0ScKPzdTc^B#~JaCxB)l*hGyO>G|HVb!6;zqF0-;f zJ9s7MYT3AZSk5gp`SyM{b*6e^5{C6lkbUKWDJ!Ia&9QWKW3**_yy5=m6VwPd@|Nk~ zz}f2sH+EA_P1bxT17IDVHvGW`E9S{#okyxk}_hkjh z!Wxn}yX~uk6KWL2V~CID_apa6$J07yNxaz`wmKhAO==^@bKUc5thL|SGf8Sn4~c`6 zER|+5|7dbJrb;hZ{;s(-VbDem%9ep*>0aufj{Ru)aioP-ztC9Ss>x6kARGq9=h#O$ zo~L3=(|LBg3DQ2DQxBh=?ym-8A!e}R1!fu~YOyGi(O%3`q(@1oERmF3r8X3ASdsQf zkmjq>X&|Pbe09RqFfkdC>Hy&PnnqbnlC6f{-%L zlCe`3=CEJl0^*AU&9W#zoq;hC?z0^ZkVKxurc-{C2j(xG1QG~Ad1**-%gw|prCHcD zgO8Kk$}lV?m&>w3Ac5|XzxmSJX+t*F!>}dIjWPhhQHi>UKy^33oO-Y|jVq5-aKAV4 zb}LH>ej9|^Gwu-GMx?o|LkB>tPX&m=m&`<}W?6DMrK=Kcb+*;EW-J-6rt4yWQ8)|n zB`(TV`5&$~7{s)8Ah@EAf9Qb*7+p@&7j8eZ-QXWAUVlsFIRP9od-A$kxO&+M;!9)R z(wZI$GNSSqFy?U*iJyyYzYB_NpNS7fU%;+3#vfIZ`>rrQWNDEq5cx;7V_^^(*K)^m zBP3X~0#_O3i#|_pn3_No1c3x|>a5KFXiTwVl>H_OjnHP9qUI0Aw`qb!U4Q0oLIXkA?F^<7mw>c8k3`e#Sc cD}h_2P<2ER{{Bho-*zg1yqa9KjA_V!0Nnm}+yDRo literal 0 HcmV?d00001 From 475eff9d03cc33d284e629a8a430fd23a4593a94 Mon Sep 17 00:00:00 2001 From: AlaaAttya Date: Mon, 7 Apr 2014 15:12:22 +0200 Subject: [PATCH 3/5] Update factories.rst your factory method should be static to work! --- components/dependency_injection/factories.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/dependency_injection/factories.rst b/components/dependency_injection/factories.rst index f156d7a8fab..9561b621c48 100644 --- a/components/dependency_injection/factories.rst +++ b/components/dependency_injection/factories.rst @@ -17,7 +17,7 @@ object:: class NewsletterFactory { - public function get() + public static function get() { $newsletterManager = new NewsletterManager(); From 8dd5e8b430fc0efd06da2ac7a3d07bb30b67a14a Mon Sep 17 00:00:00 2001 From: AlaaAttya Date: Sun, 13 Apr 2014 11:54:52 +0200 Subject: [PATCH 4/5] Update factories.rst --- components/dependency_injection/factories.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/dependency_injection/factories.rst b/components/dependency_injection/factories.rst index 9561b621c48..d77c701b880 100644 --- a/components/dependency_injection/factories.rst +++ b/components/dependency_injection/factories.rst @@ -79,8 +79,8 @@ class: When you specify the class to use for the factory (via ``factory_class``) the method will be called statically. If the factory itself should be instantiated -and the resulting object's method called (as in this example), configure the -factory itself as a service: +and the resulting object's method called, configure the factory itself as a service. +In this case, the method (e.g. get) should be changed to be non-static: .. configuration-block:: From c818065231dd11854396f70fdd148d2c30eff414 Mon Sep 17 00:00:00 2001 From: AlaaAttya Date: Sun, 13 Apr 2014 11:55:25 +0200 Subject: [PATCH 5/5] Update factories.rst --- components/dependency_injection/factories.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/dependency_injection/factories.rst b/components/dependency_injection/factories.rst index d77c701b880..96df6429244 100644 --- a/components/dependency_injection/factories.rst +++ b/components/dependency_injection/factories.rst @@ -17,7 +17,7 @@ object:: class NewsletterFactory { - public static function get() + public function get() { $newsletterManager = new NewsletterManager();