svn: /pear/peardoc/trunk/en/package/html/ html-quickform2/controller-actions.xml html-quickform2.xml
[email protected] (Alexey Borzov) Sat, 22 Oct 2011 21:58:41 +0000
| Newsgroups | php.pear.doc |
|---|---|
| Message-ID | <[email protected]> |
avb Sat, 22 Oct 2011 21:58:41 +0000
Revision: http://svn.php.net/viewvc?view=revision&revision=318327
Log:
Overview of Controller actions, boast about unit tests
Changed paths:
A pear/peardoc/trunk/en/package/html/html-quickform2/controller-actions.xml
U pear/peardoc/trunk/en/package/html/html-quickform2.xml
svn-diffs-318327.txt
(text/x-diff, 13.5 KB)
Added: pear/peardoc/trunk/en/package/html/html-quickform2/controller-actions.xml
===================================================================
--- pear/peardoc/trunk/en/package/html/html-quickform2/controller-actions.xml (rev 0)
+++ pear/peardoc/trunk/en/package/html/html-quickform2/controller-actions.xml 2011-10-22 21:58:41 UTC (rev 318327)
@@ -0,0 +1,271 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<refentry
+ xmlns="http://docbook.org/ns/docbook"
+ xmlns:phd="http://www.php.net/ns/phd"
+ version="lillet"
+ xml:id="package.html.html-quickform2.controller-actions"
+>
+ <refnamediv>
+ <refname>Controller action handlers</refname>
+ <refpurpose>Using available handlers and writing custom ones</refpurpose>
+ </refnamediv>
+ <refsection xml:id="package.html.html-quickform2.controller-actions.overview">
+ <info>
+ <title>Overview</title>
+ </info>
+ <para>
+ Action handlers in <classname>HTML_QuickForm2_Controller</classname> define what should happen
+ when request to a script containing the form is made. To make Controller execute a specific
+ action handler after form submit you <phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Controller_Page::getButtonName">give a special name</phd:pearapi>
+ to a form's submit button:
+ <programlisting role="php">
+<![CDATA[
+$form->addElement('submit', $this->getButtonName('foo'),
+ array('value' => 'This button does foo!'));
+]]>
+ </programlisting>
+ </para>
+ <para>
+ Action handlers are called via <phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Controller_Page::handle"/>
+ <programlisting role="php">
+<![CDATA[
+$page->handle('foo');
+]]>
+ </programlisting>
+ which is usually done by <phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Controller::run"/> after finding page id and action name from
+ request, but can also be done manually. In fact, built-in handlers liberally call other action
+ handlers, the execution ending with either <literal>'display'</literal>,
+ <literal>'jump'</literal> or <literal>'process'</literal>.
+ </para>
+ <para>
+ Action handlers can be added either to the form Page or to the Controller:
+ <programlisting role="php">
+<![CDATA[
+$page->addHandler('foo', new SpecificActionFoo());
+$controller->addHandler('foo', new GenericActionFoo());
+]]>
+ </programlisting>
+ When Page's <phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Controller_Page::handle">handle()</phd:pearapi> method is called it
+ first checks for a handler added via <phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Controller_Page::addHandler"/> and calls its <phd:pearapi
+ phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Controller_Action::perform">perform()</phd:pearapi> method if
+ present. If a handler is missing it calls Controller's <phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Controller_Controller::handle">handle()</phd:pearapi> which checks
+ for a handler added via <phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Controller_Controller::addHandler"/> and calls its
+ <function>perform</function> method. If a handler is missing here but its name is known and a
+ default handler is available (see below), it is loaded and added automatically, otherwise an
+ Exception is thrown.
+ </para>
+ </refsection>
+
+ <refsection xml:id="package.html.html-quickform2.controller-actions.builtin">
+ <info>
+ <title>Built-in action names and action handlers</title>
+ </info>
+ <table>
+ <title>Handlers that can be bound to submit buttons</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Built-in name</entry>
+ <entry>Default handler</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row valign="top">
+ <entry><literal>'back'</literal></entry>
+ <entry><phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Controller_Action_Back" /></entry>
+ <entry>This handler should be bound to the <literal>"Back"</literal> button of
+ (usually) a wizard-type multipage form, it redirects to the previous page whether current
+ page is valid or not.</entry>
+ </row>
+ <row valign="top">
+ <entry><emphasis>None</emphasis>, actual name should be equal to <varname>id</varname> of some
+ form page.</entry>
+ <entry><phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Controller_Action_Direct" /></entry>
+ <entry>Used to go to a specific page of the form, most useful for non-wizard forms,
+ obviously.</entry>
+ </row>
+ <row valign="top">
+ <entry><literal>'next'</literal></entry>
+ <entry><phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Controller_Action_Next" /></entry>
+ <entry>This handler should be bound to the <literal>"Back"</literal> button of
+ (usually) a wizard-type multipage form, it redirects to the next page if the current
+ one is valid (or the form is not wizard). On the last page of a multipage form it behaves
+ like <literal>'submit'</literal>.</entry>
+ </row>
+ <row valign="top">
+ <entry><literal>'submit'</literal></entry>
+ <entry><phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Controller_Action_Submit" /></entry>
+ <entry>This handler should be bound to a "global" submit button for a form. It can be
+ the "submit" button of a single-page or tabbed multi-page form, "finish"
+ button of a wizard. Default handler checks whether all the pages of the form are valid, then
+ either calls the <literal>'process'</literal> handler or displays the invalid
+ page.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table>
+ <title>Other handlers, only called explicitly</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Built-in name</entry>
+ <entry>Default handler</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row valign="top">
+ <entry><literal>'display'</literal></entry>
+ <entry><phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Controller_Action_Display" /></entry>
+ <entry>Displays the form using <phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Renderer_Default">Default renderer</phd:pearapi>. You should
+ subclass this handler and override its <phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Controller_Action_Display::renderForm">renderForm()</phd:pearapi>
+ method if you want to customize the form output.</entry>
+ </row>
+ <row valign="top">
+ <entry><literal>'jump'</literal></entry>
+ <entry><phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Controller_Action_Jump" /></entry>
+ <entry>Performs a HTTP redirect to a given page.</entry>
+ </row>
+ <row valign="top">
+ <entry><literal>'process'</literal></entry>
+ <entry><emphasis>None</emphasis>, application-specific</entry>
+ <entry>This is the action called by default <literal>'submit'</literal> and
+ <literal>'next'</literal> (on the last page of the wizard only) handlers after
+ successful (i.e. without validation errors) form submit. This action doesn't have a
+ default handler, you should define the custom one yourself and implement all the necessary
+ logic to process the form's values in it.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsection>
+
+ <refsection xml:id="package.html.html-quickform2.controller-actions.custom">
+ <info>
+ <title>Writing a custom handler</title>
+ </info>
+ <para>
+ Basically you need to create a class implementing <phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Controller_Action" /> and add necessary logic to its <phd:pearapi
+ phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Controller_Action::perform">perform()</phd:pearapi> method.
+ </para>
+ <para>
+ If you intend to bind this action to some submit button via <function>getButtonName</function>,
+ you should make sure that you store the submitted values in the session container. This is
+ most easily done via <phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Controller_Page::storeValues"/>.
+ </para>
+ <para>
+ As usual, see the built-in handlers' source for the inspiration.
+ </para>
+ </refsection>
+
+ <refsection xml:id="package.html.html-quickform2.controller-actions.bind">
+ <info>
+ <title>Can actions be bound to something other than submit buttons?</title>
+ </info>
+ <para>
+ Controller is able to properly handle actions bound to <literal><input type="image"
+ /></literal> controls, too. You don't have to do anything special, just set the
+ control's name via <function>getButtonName</function>.
+ </para>
+ <para>
+ If you want to bind an action to something like a hyperlink, you must consider the following:
+ <emphasis>the form must be submitted</emphasis> to be able to get its values, thus you need to
+ write some javascript that will submit the form and pass the action name to the controller
+ (possibly by setting a name of some hidden element to that name).
+ </para>
+ </refsection>
+
+ <refsection xml:id="package.html.html-quickform2.controller-actions.urls">
+ <info>
+ <title>URLs</title>
+ </info>
+ <para>
+ If an instance of <classname>HTML_QuickForm2</classname> is not provided with an explicit
+ <literal>'action'</literal> attribute it tries to guess it from environment using
+ <varname>$_SERVER['PHP_SELF']</varname>. This may not be a best guess when all requests are
+ routed through <filename>index.php</filename>.
+ </para>
+ <para>
+ Controller has even more problems since its <literal>'jump'</literal> handler has to build an
+ absolute URL for a redirect (per <link xmlns:xlink="http://www.w3.org/1999/xlink"
+ xlink:href="&url.rfc;2616">RFC 2616</link>). It uses various values from
+ <varname>$_SERVER</varname> array for this, but your server may be configured in such a way (e.g.
+ if you use reverse proxy) that an URL a user sees is quite different from the one a script can
+ guess.
+ </para>
+ <para>
+ Thus the only bulletproof solution sometimes will be to explicitly set the
+ <literal>'action'</literal> attribute of all <classname>HTML_QuickForm2</classname> instances in
+ Controller:
+ <programlisting role="php">
+<![CDATA[
+foreach ($controller as $page) {
+ $page->getForm()->setAttribute('action', 'http://example.com/pretty/url/of/my/form');
+}
+]]>
+ </programlisting>
+ Default handler for <literal>'jump'</literal> will use this absolute URL for redirects.
+ </para>
+ </refsection>
+
+ <refsection xml:id="package.html.html-quickform2.controller-actions.pretty-urls">
+ <info>
+ <title>Pretty URLs</title>
+ </info>
+ <para>
+ A common question is whether it is possible to get rid of "ugly" <literal>GET</literal>
+ parameters that appear when redirecting from one form page to the other:
+ <screen>
+<![CDATA[
+http://example.com/wizard.php?_qf_page2_display=true
+]]>
+ </screen>
+ </para>
+ <para>
+ The simplest solution will be to get rid of <literal>'jump'</literal> altogether and use
+ <literal>'display'</literal> in its place. However, this will completely break navigation with
+ browser's "Back" and "Forward" buttons, so don't do that.
+ </para>
+ <para>
+ It is possible to use an URL like
+ <screen>
+<![CDATA[
+http://example.com/wizard/page2
+]]>
+ </screen>
+ instead of the above one, but it'll be more difficult:
+ <orderedlist>
+ <listitem><simpara>Make sure that the "pretty" URL actually routes to a script
+ containing the Controller.</simpara></listitem>
+ <listitem><simpara>Create a custom <literal>'jump'</literal> handler that'll redirect to a
+ "pretty" URL instead of an "ugly" one.</simpara></listitem>
+ <listitem><simpara>Either change <phd:pearapi phd:package="HTML_QuickForm2"
+ phd:linkend="HTML_QuickForm2_Controller::getActionName" /> to be able to get action name from a
+ "pretty" URL or add a key with "ugly" action name to
+ <varname>$_REQUEST</varname>.</simpara></listitem>
+ </orderedlist>
+ </para>
+ </refsection>
+</refentry>
Modified: pear/peardoc/trunk/en/package/html/html-quickform2.xml
===================================================================
--- pear/peardoc/trunk/en/package/html/html-quickform2.xml 2011-10-22 21:44:05 UTC (rev 318326)
+++ pear/peardoc/trunk/en/package/html/html-quickform2.xml 2011-10-22 21:58:41 UTC (rev 318327)
@@ -25,6 +25,8 @@
<para>
Major advantages over PHP4 versions:
<itemizedlist>
+ <listitem><simpara>Most of the package's functionality is covered by unit
+ tests.</simpara></listitem>
<listitem><simpara>DOM-like API for building the form structure, new streamlined API for
elements' values handling.</simpara></listitem>
<listitem><simpara>Default rendering without tables (inspired by <link
@@ -43,6 +45,7 @@
&package.html.html-quickform2.rules;
&package.html.html-quickform2.controller-overview;
&package.html.html-quickform2.controller-migration;
+ &package.html.html-quickform2.controller-actions;
</chapter>
</book>