Zend_Form-Advanced.xml 26 KB

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