Zend_Form-Advanced.xml 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 15103 -->
  3. <!-- Reviewed: no -->
  4. <sect1 id="zend.form.advanced">
  5. <title>Uso avanzado de Zend_Form</title>
  6. <para>
  7. <classname>Zend_Form</classname> tiene una funcional riqueza, muchas de ellas dirigidas
  8. a expertos desarroladores. Este capítulo esta dirigido a documentar algunas de las
  9. funcionalidades con ejemplos y casos de uso.
  10. </para>
  11. <sect2 id="zend.form.advanced.arrayNotation">
  12. <title>Notación de array</title>
  13. <para>
  14. A muchos desarroladores web experimentados les gusta agrupar elementos relacionados de formulario
  15. usando notación de array en los nombres del elemento. Por ejemplo, si se tienen
  16. dos direcciones que se desean capturar, un envío y una dirección de facturación,
  17. se pueden tener elementos idénticos; agrupándolos en un array se puede
  18. asegurar que son capturados por separado. Nótese el siguiente formulario
  19. por ejemplo:
  20. </para>
  21. <programlisting language="html"><![CDATA[
  22. <form>
  23. <fieldset>
  24. <legend>Shipping Address</legend>
  25. <dl>
  26. <dt><label for="recipient">Ship to:</label></dt>
  27. <dd><input name="recipient" type="text" value="" /></dd>
  28. <dt><label for="address">Address:</label></dt>
  29. <dd><input name="address" type="text" value="" /></dd>
  30. <dt><label for="municipality">City:</label></dt>
  31. <dd><input name="municipality" type="text" value="" /></dd>
  32. <dt><label for="province">State:</label></dt>
  33. <dd><input name="province" type="text" value="" /></dd>
  34. <dt><label for="postal">Postal Code:</label></dt>
  35. <dd><input name="postal" type="text" value="" /></dd>
  36. </dl>
  37. </fieldset>
  38. <fieldset>
  39. <legend>Billing Address</legend>
  40. <dl>
  41. <dt><label for="payer">Bill To:</label></dt>
  42. <dd><input name="payer" type="text" value="" /></dd>
  43. <dt><label for="address">Address:</label></dt>
  44. <dd><input name="address" type="text" value="" /></dd>
  45. <dt><label for="municipality">City:</label></dt>
  46. <dd><input name="municipality" type="text" value="" /></dd>
  47. <dt><label for="province">State:</label></dt>
  48. <dd><input name="province" type="text" value="" /></dd>
  49. <dt><label for="postal">Postal Code:</label></dt>
  50. <dd><input name="postal" type="text" value="" /></dd>
  51. </dl>
  52. </fieldset>
  53. <dl>
  54. <dt><label for="terms">I agree to the Terms of Service</label></dt>
  55. <dd><input name="terms" type="checkbox" value="" /></dd>
  56. <dt></dt>
  57. <dd><input name="save" type="submit" value="Save" /></dd>
  58. </dl>
  59. </form>
  60. ]]></programlisting>
  61. <para>
  62. En este ejemplo, la facturación y la dirección de envío contienen algunos
  63. campos idénticos, eso significa que uno puede sobrescribir al otro. Nosotros podemos
  64. resolver esta solución usando una notación de array:
  65. </para>
  66. <programlisting language="html"><![CDATA[
  67. <form>
  68. <fieldset>
  69. <legend>Shipping Address</legend>
  70. <dl>
  71. <dt><label for="shipping-recipient">Ship to:</label></dt>
  72. <dd><input name="shipping[recipient]" id="shipping-recipient"
  73. type="text" value="" /></dd>
  74. <dt><label for="shipping-address">Address:</label></dt>
  75. <dd><input name="shipping[address]" id="shipping-address"
  76. type="text" value="" /></dd>
  77. <dt><label for="shipping-municipality">City:</label></dt>
  78. <dd><input name="shipping[municipality]" id="shipping-municipality"
  79. type="text" value="" /></dd>
  80. <dt><label for="shipping-province">State:</label></dt>
  81. <dd><input name="shipping[province]" id="shipping-province"
  82. type="text" value="" /></dd>
  83. <dt><label for="shipping-postal">Postal Code:</label></dt>
  84. <dd><input name="shipping[postal]" id="shipping-postal"
  85. type="text" value="" /></dd>
  86. </dl>
  87. </fieldset>
  88. <fieldset>
  89. <legend>Billing Address</legend>
  90. <dl>
  91. <dt><label for="billing-payer">Bill To:</label></dt>
  92. <dd><input name="billing[payer]" id="billing-payer"
  93. type="text" value="" /></dd>
  94. <dt><label for="billing-address">Address:</label></dt>
  95. <dd><input name="billing[address]" id="billing-address"
  96. type="text" value="" /></dd>
  97. <dt><label for="billing-municipality">City:</label></dt>
  98. <dd><input name="billing[municipality]" id="billing-municipality"
  99. type="text" value="" /></dd>
  100. <dt><label for="billing-province">State:</label></dt>
  101. <dd><input name="billing[province]" id="billing-province"
  102. type="text" value="" /></dd>
  103. <dt><label for="billing-postal">Postal Code:</label></dt>
  104. <dd><input name="billing[postal]" id="billing-postal"
  105. type="text" value="" /></dd>
  106. </dl>
  107. </fieldset>
  108. <dl>
  109. <dt><label for="terms">I agree to the Terms of Service</label></dt>
  110. <dd><input name="terms" type="checkbox" value="" /></dd>
  111. <dt></dt>
  112. <dd><input name="save" type="submit" value="Save" /></dd>
  113. </dl>
  114. </form>
  115. ]]></programlisting>
  116. <para>
  117. En el ejemplo anterior, obtenemos direcciones separadas. En el formulario
  118. sometido, ahora tenemos tres elementos, 'guardar' elemento para someterlo,
  119. y dos arrays, 'envio' y 'cuenta', cada uno con
  120. llaves para los variados elementos.
  121. </para>
  122. <para>
  123. <classname>Zend_Form</classname> intenta automatizar este proceso con los
  124. <link linkend="zend.form.forms.subforms">subformularios</link>. Por
  125. defecto, los subformularios son generados usando la notación de array como se muestra
  126. en el anterior formulario HTML listado completo con identificadores. El nombre del array
  127. esta basado en el nombre del subformulario, con las llaves basados en los elementos
  128. contenidos en el subformulario. Los subformularios pueder ser anidados arbitrariamente,
  129. y esto puede crear arrays anidados que reflejan la estructura.
  130. Adicionalmente, las validaciones rutinarias en
  131. <classname>Zend_Form</classname> respetan la estructura del array, asegurando que sus
  132. formularios sean validados correctamente, no importa cuan arbitrariamente anidados esten los
  133. subformularios. No se necesita hacer nada para beneficiarse; éste
  134. comportamiento esta activo por defecto.
  135. </para>
  136. <para>
  137. Adicionalmente, existen facilidades que le permiten activar condicionalmente la notación
  138. de un array, así como también especificar el específico array al
  139. cual un elemento o coleccion pertenece:
  140. </para>
  141. <itemizedlist>
  142. <listitem>
  143. <para>
  144. <methodname>Zend_Form::setIsArray($flag)</methodname>: Definiendo la
  145. bandera a verdadero, se puede indicar que un formulario entero debería ser
  146. tratado como un array. Por defecto, el nombre del formulario será
  147. usado como el nombre del array, a no ser que
  148. <methodname>setElementsBelongTo()</methodname> haya sido llamado. Si el
  149. formulario no tiene un nombre específico, o si
  150. <methodname>setElementsBelongTo()</methodname> no ha sido definido, esta bandera
  151. será ignorada (como cuando no hay nombre del array al cual
  152. los elementos puedan pertenecer).
  153. </para>
  154. <para>
  155. Se deberá determinar si un formulario está siendo tratado como un array
  156. usando el accesor <methodname>isArray()</methodname>.
  157. </para>
  158. </listitem>
  159. <listitem><para>
  160. <methodname>Zend_Form::setElementsBelongTo($array)</methodname>:
  161. Usando este método, se puede especificar el nombre de un array al
  162. cual todos los elementos del formulario pertenecen. Se puede determinar el
  163. nombre usando el accesor <methodname>getElementsBelongTo()</methodname>.
  164. </para></listitem>
  165. </itemizedlist>
  166. <para>
  167. Adicionalmente, a nivel del elemento, se pueden especificar
  168. elementos individuales que puedan pertenecer a arrays particulares usando
  169. el método <classname>Zend_Form_Element::setBelongsTo()</classname>.
  170. Para descubrir el valor que tiene -- sea o no sea definido explícitamente o
  171. implícitamente a través del formulario -- se puede usar el
  172. accesor <methodname>getBelongsTo()</methodname>.
  173. </para>
  174. </sect2>
  175. <sect2 id="zend.form.advanced.multiPage">
  176. <title>Formularios Multi-Página</title>
  177. <para>
  178. Actualmente, los formularios multi-página no están oficialmente soportados en
  179. <classname>Zend_Form</classname>; sin embargo, la mayoría del soporte para implementarlos
  180. está disponible y puede ser utilizado con algunos retoques.
  181. </para>
  182. <para>
  183. La clave para crear fomrularios multi-página es utilizar subformularios, pero
  184. solo para mostrar un solo subformulario por página. Esto le permite
  185. someter un solo subformulario a la vez y validarlo, pero no procesar
  186. el formulario hasta que todos los subformularios esten completos.
  187. </para>
  188. <example id="zend.form.advanced.multiPage.registration">
  189. <title>Ejemplo de formulario de registro</title>
  190. <para>
  191. Vamos a usar un formulario de registro como ejemplo. Para nuestros propósitos,
  192. queremos capturar el nombre del usuario y la contraseña en la
  193. primera página, después la información del usuario -- nombre, apellido,
  194. y ubicación -- y finalmente permitirles decidir qué lista de correo,
  195. si desean suscribirse.
  196. </para>
  197. <para>
  198. Primero, vamos a crear nuestro propio formulario, y definir varios subformularios
  199. dentro del mismo:
  200. </para>
  201. <programlisting language="php"><![CDATA[
  202. class My_Form_Registration extends Zend_Form
  203. {
  204. public function init()
  205. {
  206. // Crea un subformulario usuario: username y password
  207. $user = new Zend_Form_SubForm();
  208. $user->addElements(array(
  209. new Zend_Form_Element_Text('username', array(
  210. 'required' => true,
  211. 'label' => 'Username:',
  212. 'filters' => array('StringTrim', 'StringToLower'),
  213. 'validators' => array(
  214. 'Alnum',
  215. array('Regex',
  216. false,
  217. array('/^[a-z][a-z0-9]{2,}$/'))
  218. )
  219. )),
  220. new Zend_Form_Element_Password('password', array(
  221. 'required' => true,
  222. 'label' => 'Password:',
  223. 'filters' => array('StringTrim'),
  224. 'validators' => array(
  225. 'NotEmpty',
  226. array('StringLength', false, array(6))
  227. )
  228. )),
  229. ));
  230. // Crea un subformulario de datos demográficos : given name, family name, y
  231. // location
  232. $demog = new Zend_Form_SubForm();
  233. $demog->addElements(array(
  234. new Zend_Form_Element_Text('givenName', array(
  235. 'required' => true,
  236. 'label' => 'Given (First) Name:',
  237. 'filters' => array('StringTrim'),
  238. 'validators' => array(
  239. array('Regex',
  240. false,
  241. array('/^[a-z][a-z0-9., \'-]{2,}$/i'))
  242. )
  243. )),
  244. new Zend_Form_Element_Text('familyName', array(
  245. 'required' => true,
  246. 'label' => 'Family (Last) Name:',
  247. 'filters' => array('StringTrim'),
  248. 'validators' => array(
  249. array('Regex',
  250. false,
  251. array('/^[a-z][a-z0-9., \'-]{2,}$/i'))
  252. )
  253. )),
  254. new Zend_Form_Element_Text('location', array(
  255. 'required' => true,
  256. 'label' => 'Your Location:',
  257. 'filters' => array('StringTrim'),
  258. 'validators' => array(
  259. array('StringLength', false, array(2))
  260. )
  261. )),
  262. ));
  263. // Crea un sub fomulario de correos
  264. $listOptions = array(
  265. 'none' => 'No lists, please',
  266. 'fw-general' => 'Zend Framework General List',
  267. 'fw-mvc' => 'Zend Framework MVC List',
  268. 'fw-auth' => 'Zend Framwork Authentication and ACL List',
  269. 'fw-services' => 'Zend Framework Web Services List',
  270. );
  271. $lists = new Zend_Form_SubForm();
  272. $lists->addElements(array(
  273. new Zend_Form_Element_MultiCheckbox('subscriptions', array(
  274. 'label' =>
  275. 'Which lists would you like to subscribe to?',
  276. 'multiOptions' => $listOptions,
  277. 'required' => true,
  278. 'filters' => array('StringTrim'),
  279. 'validators' => array(
  280. array('InArray',
  281. false,
  282. array(array_keys($listOptions)))
  283. )
  284. )),
  285. ));
  286. // Adjuntando los subformlarios al formulario principal
  287. $this->addSubForms(array(
  288. 'user' => $user,
  289. 'demog' => $demog,
  290. 'lists' => $lists
  291. ));
  292. }
  293. }
  294. ]]></programlisting>
  295. <para>
  296. Note que no hay botones de enviar, y que ni hemos hecho
  297. nada con los decoradores de subformularios -- lo que significa que por
  298. defecto serán desplegados como campos. Necesitaremos hacer
  299. algo con ellos mientras desplegamos cada subformulario individualmente,
  300. y añadir botones de manera que podamos procesarlos realmente --
  301. el cual requerira las propiedades acción y método. Vamos a añadir
  302. algunos andamios a nuestras clases para proveer esa información:
  303. </para>
  304. <programlisting language="php"><![CDATA[
  305. class My_Form_Registration extends Zend_Form
  306. {
  307. // ...
  308. /**
  309. * Prepara un subformulario para mostrar
  310. *
  311. * @param string|Zend_Form_SubForm $spec
  312. * @return Zend_Form_SubForm
  313. */
  314. public function prepareSubForm($spec)
  315. {
  316. if (is_string($spec)) {
  317. $subForm = $this->{$spec};
  318. } elseif ($spec instanceof Zend_Form_SubForm) {
  319. $subForm = $spec;
  320. } else {
  321. throw new Exception('Invalid argument passed to ' .
  322. __FUNCTION__ . '()');
  323. }
  324. $this->setSubFormDecorators($subForm)
  325. ->addSubmitButton($subForm)
  326. ->addSubFormActions($subForm);
  327. return $subForm;
  328. }
  329. /**
  330. * Add form decorators to an individual sub form
  331. *
  332. * @param Zend_Form_SubForm $subForm
  333. * @return My_Form_Registration
  334. */
  335. public function setSubFormDecorators(Zend_Form_SubForm $subForm)
  336. {
  337. $subForm->setDecorators(array(
  338. 'FormElements',
  339. array('HtmlTag', array('tag' => 'dl',
  340. 'class' => 'zend_form')),
  341. 'Form',
  342. ));
  343. return $this;
  344. }
  345. /**
  346. * Añade un Boton de envio(submit) a cada subformulario
  347. *
  348. * @param Zend_Form_SubForm $subForm
  349. * @return My_Form_Registration
  350. */
  351. public function addSubmitButton(Zend_Form_SubForm $subForm)
  352. {
  353. $subForm->addElement(new Zend_Form_Element_Submit(
  354. 'save',
  355. array(
  356. 'label' => 'Save and continue',
  357. 'required' => false,
  358. 'ignore' => true,
  359. )
  360. ));
  361. return $this;
  362. }
  363. /**
  364. * Añade el method y el action a cada subformulario
  365. *
  366. * @param Zend_Form_SubForm $subForm
  367. * @return My_Form_Registration
  368. */
  369. public function addSubFormActions(Zend_Form_SubForm $subForm)
  370. {
  371. $subForm->setAction('/registration/process')
  372. ->setMethod('post');
  373. return $this;
  374. }
  375. }
  376. ]]></programlisting>
  377. <para>
  378. Siguiente, necesitamos añadir andamios a nuestro action controller,
  379. y tener varias consideraciones. Primero, necesitamos asegurar que
  380. persiste la información del formulario entre los requerimientos, de esa manera determinar
  381. cuándo terminar. Segundo, necesitamos alguna lógica para determinar qué segmentos
  382. del formulario han sido sometidos, y qué subformulario
  383. mostrar de acuerdo a la información. Usaremos
  384. <classname>Zend_Session_Namespace</classname> para persistir la información, el cual
  385. nos ayudará a responder la pregunta de qué formulario someter.
  386. </para>
  387. <para>
  388. Vamos a crear nuestro controlador, y añadir un método para recuperar un
  389. formulario instanciado:
  390. </para>
  391. <programlisting language="php"><![CDATA[
  392. class RegistrationController extends Zend_Controller_Action
  393. {
  394. protected $_form;
  395. public function getForm()
  396. {
  397. if (null === $this->_form) {
  398. $this->_form = new My_Form_Registration();
  399. }
  400. return $this->_form;
  401. }
  402. }
  403. ]]></programlisting>
  404. <para>
  405. Ahora, vamos a añadir algunas funcionalidades para determinar qué formulario
  406. mostrar. Básicamente, hasta que el formulario entero sea considerado válido,
  407. necesitamos continuar mostrando segmentos de formulario. Adicionalmente,
  408. queremos asegurar que están en un orden particular: usuario,
  409. demog, y después las listas. Podemos determinar qué información ha sido
  410. sometida verificando nuestro session namespace para claves particulares
  411. representando cada subformulario.
  412. </para>
  413. <programlisting language="php"><![CDATA[
  414. class RegistrationController extends Zend_Controller_Action
  415. {
  416. // ...
  417. protected $_namespace = 'RegistrationController';
  418. protected $_session;
  419. /**
  420. * Obtiene el namespace de la sesión que estamos usando
  421. *
  422. * @return Zend_Session_Namespace
  423. */
  424. public function getSessionNamespace()
  425. {
  426. if (null === $this->_session) {
  427. $this->_session =
  428. new Zend_Session_Namespace($this->_namespace);
  429. }
  430. return $this->_session;
  431. }
  432. /**
  433. * Obtiene la lista de Formularios que ya están almacenados en la sesión
  434. *
  435. * @return array
  436. */
  437. public function getStoredForms()
  438. {
  439. $stored = array();
  440. foreach ($this->getSessionNamespace() as $key => $value) {
  441. $stored[] = $key;
  442. }
  443. return $stored;
  444. }
  445. /**
  446. * Obtiene la lista de todos los subformularios disponibles
  447. *
  448. * @return array
  449. */
  450. public function getPotentialForms()
  451. {
  452. return array_keys($this->getForm()->getSubForms());
  453. }
  454. /**
  455. * ¿Qué subformulario se envio?
  456. *
  457. * @return false|Zend_Form_SubForm
  458. */
  459. public function getCurrentSubForm()
  460. {
  461. $request = $this->getRequest();
  462. if (!$request->isPost()) {
  463. return false;
  464. }
  465. foreach ($this->getPotentialForms() as $name) {
  466. if ($data = $request->getPost($name, false)) {
  467. if (is_array($data)) {
  468. return $this->getForm()->getSubForm($name);
  469. break;
  470. }
  471. }
  472. }
  473. return false;
  474. }
  475. /**
  476. * Obtiene el siguiente subformulario para mostrarlo
  477. *
  478. * @return Zend_Form_SubForm|false
  479. */
  480. public function getNextSubForm()
  481. {
  482. $storedForms = $this->getStoredForms();
  483. $potentialForms = $this->getPotentialForms();
  484. foreach ($potentialForms as $name) {
  485. if (!in_array($name, $storedForms)) {
  486. return $this->getForm()->getSubForm($name);
  487. }
  488. }
  489. return false;
  490. }
  491. }
  492. ]]></programlisting>
  493. <para>
  494. El método de arriba nos permite usar notaciones tal como "<methodname>$subForm =
  495. $this-&gt;getCurrentSubForm();</methodname>" recuperar el actual
  496. subformulario para la validación, o "<methodname>$next =
  497. $this-&gt;getNextSubForm();</methodname>" obtener el siguiente para
  498. mostrar.
  499. </para>
  500. <para>
  501. Ahora, vamos a encontrar la manera para procesar y mostrar varios
  502. subformularios. Podemos usar <methodname>getCurrentSubForm()</methodname> para determinar
  503. si algún subformulario ha sido sometido (los valores de retorno falso indican que
  504. ninguno ha sido desplegado o sometido), y
  505. <methodname>getNextSubForm()</methodname> recupera el formulario que mostrar. Podemos
  506. entonces usar el método del formulario <methodname>prepareSubForm()</methodname> para asegurar
  507. que el formulario está listo para mostrar.
  508. </para>
  509. <para>
  510. Cuando tenemos un formulario sometido, podemos validar el subformulario,
  511. y luego verificar si el formulario entero es válido ahora. Para hacer
  512. esas tareas, necesitamos métodos adicionales que aseguren que la
  513. información sometida es añadida a la sesión, y que cuando validamos
  514. el formulario entero, nosotros validamos contra todos los segmentos de
  515. la sesión:
  516. </para>
  517. <programlisting language="php"><![CDATA[
  518. class RegistrationController extends Zend_Controller_Action
  519. {
  520. // ...
  521. /**
  522. * ¿Es válido el subformulario?
  523. *
  524. * @param Zend_Form_SubForm $subForm
  525. * @param array $data
  526. * @return bool
  527. */
  528. public function subFormIsValid(Zend_Form_SubForm $subForm,
  529. array $data)
  530. {
  531. $name = $subForm->getName();
  532. if ($subForm->isValid($data)) {
  533. $this->getSessionNamespace()->$name = $subForm->getValues();
  534. return true;
  535. }
  536. return false;
  537. }
  538. /**
  539. * ¿Es válido todo el formulario?
  540. *
  541. * @return bool
  542. */
  543. public function formIsValid()
  544. {
  545. $data = array();
  546. foreach ($this->getSessionNamespace() as $key => $info) {
  547. $data[$key] = $info;
  548. }
  549. return $this->getForm()->isValid($data);
  550. }
  551. }
  552. ]]></programlisting>
  553. <para>
  554. Ahora que tenemos el trabajo preparado, vamos a construir las
  555. acciones para este controlador. Necesitaremos una página de destino
  556. para el formulario, y luego una acción 'process' para procesar el formulario.
  557. </para>
  558. <programlisting language="php"><![CDATA[
  559. class RegistrationController extends Zend_Controller_Action
  560. {
  561. // ...
  562. public function indexAction()
  563. {
  564. // volver a mostrar la página actual, o mostrar el "siguiente"
  565. // (primer) subformulario
  566. if (!$form = $this->getCurrentSubForm()) {
  567. $form = $this->getNextSubForm();
  568. }
  569. $this->view->form = $this->getForm()->prepareSubForm($form);
  570. }
  571. public function processAction()
  572. {
  573. if (!$form = $this->getCurrentSubForm()) {
  574. return $this->_forward('index');
  575. }
  576. if (!$this->subFormIsValid($form,
  577. $this->getRequest()->getPost())) {
  578. $this->view->form = $this->getForm()->prepareSubForm($form);
  579. return $this->render('index');
  580. }
  581. if (!$this->formIsValid()) {
  582. $form = $this->getNextSubForm();
  583. $this->view->form = $this->getForm()->prepareSubForm($form);
  584. return $this->render('index');
  585. }
  586. // Formulario Válido!
  587. // Render information in a verification page
  588. $this->view->info = $this->getSessionNamespace();
  589. $this->render('verification');
  590. }
  591. }
  592. ]]></programlisting>
  593. <para>
  594. Como se ha notado, el código actual para procesar el formulario es
  595. relativamente simple. Verificamos si tenemos un subformulario actual
  596. sometido y si no, retornamos a la página de destino. Si tenemos
  597. un subformulario, intentaremos validarlo, volviéndolo a mostrar si tiene
  598. fallos. Si el subformulario es válido, entonces verificaremos si
  599. el formulario es válido, lo que debería indicar que hemos terminado; si no,
  600. mostraremos el siguiente segmento del formulario. Finalmente, mostraremos una
  601. página de verificación con el contenido de la sesión.
  602. </para>
  603. <para>
  604. Los scripts de vista son muy simples:
  605. </para>
  606. <programlisting language="php"><![CDATA[
  607. <? // registration/index.phtml ?>
  608. <h2>registro</h2>
  609. <?php echo $this->form ?>
  610. <? // registration/verification.phtml ?>
  611. <h2>Gracias por Registrarse!</h2>
  612. <p>
  613. Aquí está la información que nos ha proporcionado:
  614. </p>
  615. <?
  616. // Tienen que construir esto con los items que estan almacenados en los namespaces
  617. // de la sesión
  618. foreach ($this->info as $info):
  619. foreach ($info as $form => $data): ?>
  620. <h4><?php echo ucfirst($form) ?>:</h4>
  621. <dl>
  622. <? foreach ($data as $key => $value): ?>
  623. <dt><?php echo ucfirst($key) ?></dt>
  624. <? if (is_array($value)):
  625. foreach ($value as $label => $val): ?>
  626. <dd><?php echo $val ?></dd>
  627. <? endforeach;
  628. else: ?>
  629. <dd><?php echo $this->escape($value) ?></dd>
  630. <? endif;
  631. endforeach; ?>
  632. </dl>
  633. <? endforeach;
  634. endforeach
  635. ]]></programlisting>
  636. <para>
  637. Próximas novedades de Zend Framework incluirán componentes
  638. para hacer formularios multi páginas mas simples, abstrayendo la sesión y
  639. la lógica de orden. Mientras tanto, el ejemplo de arriba debería servir
  640. como guia razonable para alcanzar esta tarea en su web.
  641. </para>
  642. </example>
  643. </sect2>
  644. </sect1>
  645. <!--
  646. vim:se ts=4 sw=4 et:
  647. -->