Zend_Form-Advanced.xml 27 KB

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