Zend_Form-Advanced.xml 26 KB

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