Bladeren bron

DOCUMENTATION Spanish:
- convert CRLF => LF

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@15299 44c647ce-9c0f-0410-b52a-842ac1e357ba

mikaelkael 16 jaren geleden
bovenliggende
commit
ba1908bf1f

+ 126 - 126
documentation/manual/es/module_specs/Zend_Acl-Advanced.xml

@@ -1,126 +1,126 @@
-<sect1 id="zend.acl.advanced">
-
-    <title>Uso Avanzado</title>
-
-    <sect2 id="zend.acl.advanced.storing">
-
-        <title>Almacenamiento Permanente de los Datos ACL</title>
-
-        <para>
-            Zend_Acl fue diseñado de tal manera que no requiere ninguna
-            tecnología particular como bases de datos o un servidor de
-            cache para el almacenamiento de datos ACL. Al poseer una
-            implementación completamente construida en PHP, es posible
-            contruir herramientas de administración personalizadas sobre
-            Zend_Acl con relativa facilidad y flexibilidad. En muchas
-            situaciones se requiere alguna forma de mantenimiento
-            interactivo de una ACL, y Zend_Acl provee métodos para
-            configurar, y consultar, los controles de acceso de una
-            aplicación.
-        </para>
-
-        <para>
-            El almacenamiento de los datos ACL es una tarea que se
-            delega al desarrollador, puesto que la utilización variará
-            exténsamente en distintas situaciones. Dado que Zend_Acl es
-            serializable, los objetos ACL pueden serializarse con la
-            función
-            <ulink url="http://php.net/serialize">
-                <code>serialize()</code>
-            </ulink>
-            de PHP, y los resultados pueden ser almacenados donde sea
-            que el desarrollador lo desee, en un archivo, base de datos,
-            o mecanismo de cache
-        </para>
-
-    </sect2>
-
-    <sect2 id="zend.acl.advanced.assertions">
-
-        <title>
-            Escribiendo reglas condicionales ACL con aserciones
-        </title>
-
-        <para>
-            A veces, una regla para permitir o negar una función de acceso a un
-            recurso no debería ser absoluta sino que depende de varios criterios.
-            Por ejemplo, supóngase que debe permitirse cierto acceso, pero
-            únicamente entre las 8:00am y 5:00pm. Otro ejemplo sería negar el
-            acceso debido a una petición que proviene de una dirección IP que se
-            ha marcado como una fuente de abusos. Zend_Acl tiene soporte para la
-            aplicación de normas basadas en cualquier condición que el
-            desarrollador necesite.
-        </para>
-
-    <para>
-        Zend_Acl provee soporte para reglas condicionales con
-        <code>Zend_Acl_Assert_Interface</code>
-        . Con el fin de utilizar la regla de aserción de la interfaz,
-        un desarrollador escribe una clase que implemente el método
-        <code>assert()</code>
-        de la interfaz:
-    </para>
-
-        <programlisting role="php"><![CDATA[
-class CleanIPAssertion implements Zend_Acl_Assert_Interface
-{
-    public function assert(Zend_Acl $acl,
-                           Zend_Acl_Role_Interface $role = null,
-                           Zend_Acl_Resource_Interface $resource = null,
-                           $privilege = null)
-    {
-        return $this->_isCleanIP($_SERVER['REMOTE_ADDR']);
-    }
-
-    protected function _isCleanIP($ip)
-    {
-        // ...
-    }
-}
-]]>
-        </programlisting>
-
-        <para>
-            Una vez la clase de aserción esta disponible, el desarrollador puede 
-            suministrar una instancia de la clase de aserción cuando asigna reglas 
-            condicionales. Una regla que es creada con una aserción
-            sólo se aplica cuando el método de la aserción devuelve true.
-        </para>
-        
-        <programlisting role="php"><![CDATA[
-$acl = new Zend_Acl();
-$acl->allow(null, null, null, new CleanIPAssertion());
-]]>
-        </programlisting>
-
-        <para>
-            El código anterior crea una regla condicional que permite el acceso a 
-            todos los privilegios sobre todo, por todo el mundo, excepto cuando la IP 
-            de quien hace la petición está en la "lista negra". Si una petición 
-            viene desde una IP que no está considerada "limpia", entonces la regla no
-            se aplica. Dado que la regla se aplica a todos los roles, todos los 
-            recursos, y todos los privilegios, una IP "no limpia" daría lugar a una 
-            negación de acceso. Éste es un caso especial, sin embargo, y debería ser
-            entendido que en todos los otros casos (por ejemplo, cuando un rol 
-            específico, recurso, o privilegio está especificado por la regla), 
-            una aserción fallida provoca que la regla no se aplique, y otras reglas 
-            deberían ser usadas para determinar si el acceso está permitido o
-            denegado.
-        </para>
-
-        <para>
-            El método
-            <code>assert()</code>
-            de un objeto aserción es pasado a la ACL, regla,  recurso, y privilegio 
-      para el cual una consulta de autorización (por ejemplo,
-            <code>isAllowed()</code>
-            ) se aplica, con el fin de proporcionar un contexto para que la clase de 
-      aserción determine sus condiciones cuando fuera necesario.
-        </para>
-
-    </sect2>
-
-</sect1>
-<!--
-    vim:se ts=4 sw=4 et:
--->
+<sect1 id="zend.acl.advanced">
+
+    <title>Uso Avanzado</title>
+
+    <sect2 id="zend.acl.advanced.storing">
+
+        <title>Almacenamiento Permanente de los Datos ACL</title>
+
+        <para>
+            Zend_Acl fue diseñado de tal manera que no requiere ninguna
+            tecnología particular como bases de datos o un servidor de
+            cache para el almacenamiento de datos ACL. Al poseer una
+            implementación completamente construida en PHP, es posible
+            contruir herramientas de administración personalizadas sobre
+            Zend_Acl con relativa facilidad y flexibilidad. En muchas
+            situaciones se requiere alguna forma de mantenimiento
+            interactivo de una ACL, y Zend_Acl provee métodos para
+            configurar, y consultar, los controles de acceso de una
+            aplicación.
+        </para>
+
+        <para>
+            El almacenamiento de los datos ACL es una tarea que se
+            delega al desarrollador, puesto que la utilización variará
+            exténsamente en distintas situaciones. Dado que Zend_Acl es
+            serializable, los objetos ACL pueden serializarse con la
+            función
+            <ulink url="http://php.net/serialize">
+                <code>serialize()</code>
+            </ulink>
+            de PHP, y los resultados pueden ser almacenados donde sea
+            que el desarrollador lo desee, en un archivo, base de datos,
+            o mecanismo de cache
+        </para>
+
+    </sect2>
+
+    <sect2 id="zend.acl.advanced.assertions">
+
+        <title>
+            Escribiendo reglas condicionales ACL con aserciones
+        </title>
+
+        <para>
+            A veces, una regla para permitir o negar una función de acceso a un
+            recurso no debería ser absoluta sino que depende de varios criterios.
+            Por ejemplo, supóngase que debe permitirse cierto acceso, pero
+            únicamente entre las 8:00am y 5:00pm. Otro ejemplo sería negar el
+            acceso debido a una petición que proviene de una dirección IP que se
+            ha marcado como una fuente de abusos. Zend_Acl tiene soporte para la
+            aplicación de normas basadas en cualquier condición que el
+            desarrollador necesite.
+        </para>
+
+    <para>
+        Zend_Acl provee soporte para reglas condicionales con
+        <code>Zend_Acl_Assert_Interface</code>
+        . Con el fin de utilizar la regla de aserción de la interfaz,
+        un desarrollador escribe una clase que implemente el método
+        <code>assert()</code>
+        de la interfaz:
+    </para>
+
+        <programlisting role="php"><![CDATA[
+class CleanIPAssertion implements Zend_Acl_Assert_Interface
+{
+    public function assert(Zend_Acl $acl,
+                           Zend_Acl_Role_Interface $role = null,
+                           Zend_Acl_Resource_Interface $resource = null,
+                           $privilege = null)
+    {
+        return $this->_isCleanIP($_SERVER['REMOTE_ADDR']);
+    }
+
+    protected function _isCleanIP($ip)
+    {
+        // ...
+    }
+}
+]]>
+        </programlisting>
+
+        <para>
+            Una vez la clase de aserción esta disponible, el desarrollador puede 
+            suministrar una instancia de la clase de aserción cuando asigna reglas 
+            condicionales. Una regla que es creada con una aserción
+            sólo se aplica cuando el método de la aserción devuelve true.
+        </para>
+        
+        <programlisting role="php"><![CDATA[
+$acl = new Zend_Acl();
+$acl->allow(null, null, null, new CleanIPAssertion());
+]]>
+        </programlisting>
+
+        <para>
+            El código anterior crea una regla condicional que permite el acceso a 
+            todos los privilegios sobre todo, por todo el mundo, excepto cuando la IP 
+            de quien hace la petición está en la "lista negra". Si una petición 
+            viene desde una IP que no está considerada "limpia", entonces la regla no
+            se aplica. Dado que la regla se aplica a todos los roles, todos los 
+            recursos, y todos los privilegios, una IP "no limpia" daría lugar a una 
+            negación de acceso. Éste es un caso especial, sin embargo, y debería ser
+            entendido que en todos los otros casos (por ejemplo, cuando un rol 
+            específico, recurso, o privilegio está especificado por la regla), 
+            una aserción fallida provoca que la regla no se aplique, y otras reglas 
+            deberían ser usadas para determinar si el acceso está permitido o
+            denegado.
+        </para>
+
+        <para>
+            El método
+            <code>assert()</code>
+            de un objeto aserción es pasado a la ACL, regla,  recurso, y privilegio 
+      para el cual una consulta de autorización (por ejemplo,
+            <code>isAllowed()</code>
+            ) se aplica, con el fin de proporcionar un contexto para que la clase de 
+      aserción determine sus condiciones cuando fuera necesario.
+        </para>
+
+    </sect2>
+
+</sect1>
+<!--
+    vim:se ts=4 sw=4 et:
+-->

+ 194 - 194
documentation/manual/es/module_specs/Zend_Acl-Refining.xml

@@ -1,194 +1,194 @@
-<sect1 id="zend.acl.refining">
-
-    <title>Perfeccionamiento de los controles de acceso</title>
-
-    <sect2 id="zend.acl.refining.precise">
-
-        <title>Definir mejor los controles de acceso</title>
-
-        <para>
-            El ACL básico según lo definido en la
-            <link linkend="zend.acl.introduction">
-                sección anterior
-            </link>
-            demuestra cómo los diversos privilegios se pueden otorgar
-            sobre todo el ACL (todos los recursos). En la práctica, sin
-            embargo, los controles de acceso tienden a tener excepciones
-            y diversos grados de complejidad. Zend_Acl permite lograr
-            estos refinamientos de una manera sencilla y flexible.
-        </para>
-
-        <para>
-            Para el CMS del ejemplo se ha determinado que, si bien el
-            grupo 'staff' cubre las necesidades de la gran mayoría de
-            usuarios, hay una necesidad de un nuevo grupo 'marketing'
-            que requiere el acceso al boletín de noticias y las últimas
-            noticias en el CMS. El grupo es bastante autosuficiente y
-            tendrá la capacidad de publicar y de archivar los boletines
-            de noticias y las últimas noticias.
-        </para>
-
-        <para>
-            Primero revisamos el registro del rol para reflejar estos
-            cambios. Hemos determinado que el grupo 'marketing' tiene
-            los mismos permisos básicos que 'staff', así que definimos
-            'marketing' de tal manera que herede los permisos de
-            'staff':
-        </para>
-
-        <programlisting role="php"><![CDATA[ 
- // El nuevo grupo de Marketing hereda los permisos de Staff
- $acl->addRole(new Zend_Acl_Role('marketing'), 'staff'); ]]>
-        </programlisting>
-
-        <para>
-            A continuación, la nota que por encima de los controles de
-            acceso se refieren a recursos específicos (por ejemplo,
-            "boletín informativo", "últimas noticias", "anuncio de
-            noticias"). Ahora añadimos estos recursos:
-        </para>
-
-        <programlisting role="php"><![CDATA[ 
-// Crear recursos para las reglas
- // newsletter
- $acl->add(new Zend_Acl_Resource('newsletter'));
- 
- // news
- $acl->add(new Zend_Acl_Resource('news'));
- 
- // Últimas Noticias
- $acl->add(new Zend_Acl_Resource('latest'), 'news');
- 
- // anuncio de noticias
- $acl->add(new Zend_Acl_Resource('announcement'), 'news'); ]]>
-        </programlisting>
-
-        <para>
-            Entonces es simplemente una cuestión de la definición de
-            estas normas más específicas en ámbitos de la ACL:
-        </para>
-
-        <programlisting role="php"><![CDATA[ // 
- Marketing debe ser capaz de archivar y publicar boletines informativos y
- // las últimas noticias
- $acl->allow('marketing',
- array('newsletter', 'latest'),
- array('publish', 'archive'));
- 
- // Staff (y marketing, por herencia), se le denega el permiso a
- // revisar las últimas noticias
- $acl->deny('staff', 'latest', 'revise');
- 
- // Todos (incluyendo los administradores) tienen permiso denegado para
- // archivar anuncios y noticias
- $acl->deny(null, 'announcement', 'archive'); ]]>
-        </programlisting>
-
-        <para>
-            Ahora podemos consultar el ACL con respecto a los últimos
-            cambios:
-        </para>
-
-        <programlisting role="php"><![CDATA[ 
- echo $acl->isAllowed('staff', 'newsletter', 'publish') ?
- "allowed" : "denied";
- // denegado
- 
- echo $acl->isAllowed('marketing', 'newsletter', 'publish') ?
- "allowed" : "denied";
- // permitido    
- 
- echo $acl->isAllowed('staff', 'latest', 'publish') ?
- "allowed" : "denied";
- // denegado
- 
- echo $acl->isAllowed('marketing', 'latest', 'publish') ?
- "allowed" : "denied";
- // permitido    
- 
- echo $acl->isAllowed('marketing', 'latest', 'archive') ?
- "allowed" : "denied";
- // permitido    
- 
- echo $acl->isAllowed('marketing', 'latest', 'revise') ?
- "allowed" : "denied";
- // denegado
- 
- echo $acl->isAllowed('editor', 'announcement', 'archive') ?
- "allowed" : "denied";
- // denegado
- 
- echo $acl->isAllowed('administrator', 'announcement', 'archive') ?
- "allowed" : "denied";
- // denegado 
- ]]>
-        </programlisting>
-
-    </sect2>
-
-    <sect2 id="zend.acl.refining.removing">
-
-        <title>Eliminar los controles de acceso</title>
-
-        <para>
-            Para eliminar una o más reglas ACL, simplemente utilice el
-            método removeAllow() o removeDeny(). Al igual que con
-            allow() y deny(), puede utilizar un valor null para indicar
-            que el método es aplicable a todos los roles, recursos y/o
-            privilegios:
-        </para>
-
-        <programlisting role="php"><![CDATA[
-// Elimina la prohibición de leer las últimas noticias de staff (y marketing, 
-// por herencia)
-$acl->removeDeny('staff', 'latest', 'revise');
-
-echo $acl->isAllowed('marketing', 'latest', 'revise') ?
- "allowed" : "denied"; 
-// permitido 
-
-// Elimina la autorización para publicar y archivar los boletines 
-// marketing 
-$acl->removeAllow('marketing',
-                  'newsletter',
-                  array('publish', 'archive'));
-
-echo $acl->isAllowed('marketing', 'newsletter', 'publish') ?
-     "allowed" : "denied";
-// denegado
-
-echo $acl->isAllowed('marketing', 'newsletter', 'archive') ?
-"allowed" : "denied";
-
-// denegado
- ]]>
-        </programlisting>
-
-        <para>
-            Los privilegios pueden ser modificados de manera incremental como se
-            ha indicado anteriormente, pero un valor null para los
-            privilegios anula tales cambios incrementales:
-        </para>
-
-        <programlisting role="php">
-            <![CDATA[
-//Permitir al grupo de "marketing" todos los permisos a las últimas noticias
-$acl->allow('marketing', 'latest');
-
-echo $acl->isAllowed('marketing', 'latest', 'publish') ?
-"allowed" : "denied";
-//permitido
-
-echo $acl->isAllowed('marketing', 'latest', 'archive') ?
-"allowed" : "denied";
-//permitido
-
-echo $acl->isAllowed('marketing', 'latest', 'anything') ?
-"allowed" : "denied";
-// permitido
-]]>
-        </programlisting>
-
-    </sect2>
-
-</sect1>
+<sect1 id="zend.acl.refining">
+
+    <title>Perfeccionamiento de los controles de acceso</title>
+
+    <sect2 id="zend.acl.refining.precise">
+
+        <title>Definir mejor los controles de acceso</title>
+
+        <para>
+            El ACL básico según lo definido en la
+            <link linkend="zend.acl.introduction">
+                sección anterior
+            </link>
+            demuestra cómo los diversos privilegios se pueden otorgar
+            sobre todo el ACL (todos los recursos). En la práctica, sin
+            embargo, los controles de acceso tienden a tener excepciones
+            y diversos grados de complejidad. Zend_Acl permite lograr
+            estos refinamientos de una manera sencilla y flexible.
+        </para>
+
+        <para>
+            Para el CMS del ejemplo se ha determinado que, si bien el
+            grupo 'staff' cubre las necesidades de la gran mayoría de
+            usuarios, hay una necesidad de un nuevo grupo 'marketing'
+            que requiere el acceso al boletín de noticias y las últimas
+            noticias en el CMS. El grupo es bastante autosuficiente y
+            tendrá la capacidad de publicar y de archivar los boletines
+            de noticias y las últimas noticias.
+        </para>
+
+        <para>
+            Primero revisamos el registro del rol para reflejar estos
+            cambios. Hemos determinado que el grupo 'marketing' tiene
+            los mismos permisos básicos que 'staff', así que definimos
+            'marketing' de tal manera que herede los permisos de
+            'staff':
+        </para>
+
+        <programlisting role="php"><![CDATA[ 
+ // El nuevo grupo de Marketing hereda los permisos de Staff
+ $acl->addRole(new Zend_Acl_Role('marketing'), 'staff'); ]]>
+        </programlisting>
+
+        <para>
+            A continuación, la nota que por encima de los controles de
+            acceso se refieren a recursos específicos (por ejemplo,
+            "boletín informativo", "últimas noticias", "anuncio de
+            noticias"). Ahora añadimos estos recursos:
+        </para>
+
+        <programlisting role="php"><![CDATA[ 
+// Crear recursos para las reglas
+ // newsletter
+ $acl->add(new Zend_Acl_Resource('newsletter'));
+ 
+ // news
+ $acl->add(new Zend_Acl_Resource('news'));
+ 
+ // Últimas Noticias
+ $acl->add(new Zend_Acl_Resource('latest'), 'news');
+ 
+ // anuncio de noticias
+ $acl->add(new Zend_Acl_Resource('announcement'), 'news'); ]]>
+        </programlisting>
+
+        <para>
+            Entonces es simplemente una cuestión de la definición de
+            estas normas más específicas en ámbitos de la ACL:
+        </para>
+
+        <programlisting role="php"><![CDATA[ // 
+ Marketing debe ser capaz de archivar y publicar boletines informativos y
+ // las últimas noticias
+ $acl->allow('marketing',
+ array('newsletter', 'latest'),
+ array('publish', 'archive'));
+ 
+ // Staff (y marketing, por herencia), se le denega el permiso a
+ // revisar las últimas noticias
+ $acl->deny('staff', 'latest', 'revise');
+ 
+ // Todos (incluyendo los administradores) tienen permiso denegado para
+ // archivar anuncios y noticias
+ $acl->deny(null, 'announcement', 'archive'); ]]>
+        </programlisting>
+
+        <para>
+            Ahora podemos consultar el ACL con respecto a los últimos
+            cambios:
+        </para>
+
+        <programlisting role="php"><![CDATA[ 
+ echo $acl->isAllowed('staff', 'newsletter', 'publish') ?
+ "allowed" : "denied";
+ // denegado
+ 
+ echo $acl->isAllowed('marketing', 'newsletter', 'publish') ?
+ "allowed" : "denied";
+ // permitido    
+ 
+ echo $acl->isAllowed('staff', 'latest', 'publish') ?
+ "allowed" : "denied";
+ // denegado
+ 
+ echo $acl->isAllowed('marketing', 'latest', 'publish') ?
+ "allowed" : "denied";
+ // permitido    
+ 
+ echo $acl->isAllowed('marketing', 'latest', 'archive') ?
+ "allowed" : "denied";
+ // permitido    
+ 
+ echo $acl->isAllowed('marketing', 'latest', 'revise') ?
+ "allowed" : "denied";
+ // denegado
+ 
+ echo $acl->isAllowed('editor', 'announcement', 'archive') ?
+ "allowed" : "denied";
+ // denegado
+ 
+ echo $acl->isAllowed('administrator', 'announcement', 'archive') ?
+ "allowed" : "denied";
+ // denegado 
+ ]]>
+        </programlisting>
+
+    </sect2>
+
+    <sect2 id="zend.acl.refining.removing">
+
+        <title>Eliminar los controles de acceso</title>
+
+        <para>
+            Para eliminar una o más reglas ACL, simplemente utilice el
+            método removeAllow() o removeDeny(). Al igual que con
+            allow() y deny(), puede utilizar un valor null para indicar
+            que el método es aplicable a todos los roles, recursos y/o
+            privilegios:
+        </para>
+
+        <programlisting role="php"><![CDATA[
+// Elimina la prohibición de leer las últimas noticias de staff (y marketing, 
+// por herencia)
+$acl->removeDeny('staff', 'latest', 'revise');
+
+echo $acl->isAllowed('marketing', 'latest', 'revise') ?
+ "allowed" : "denied"; 
+// permitido 
+
+// Elimina la autorización para publicar y archivar los boletines 
+// marketing 
+$acl->removeAllow('marketing',
+                  'newsletter',
+                  array('publish', 'archive'));
+
+echo $acl->isAllowed('marketing', 'newsletter', 'publish') ?
+     "allowed" : "denied";
+// denegado
+
+echo $acl->isAllowed('marketing', 'newsletter', 'archive') ?
+"allowed" : "denied";
+
+// denegado
+ ]]>
+        </programlisting>
+
+        <para>
+            Los privilegios pueden ser modificados de manera incremental como se
+            ha indicado anteriormente, pero un valor null para los
+            privilegios anula tales cambios incrementales:
+        </para>
+
+        <programlisting role="php">
+            <![CDATA[
+//Permitir al grupo de "marketing" todos los permisos a las últimas noticias
+$acl->allow('marketing', 'latest');
+
+echo $acl->isAllowed('marketing', 'latest', 'publish') ?
+"allowed" : "denied";
+//permitido
+
+echo $acl->isAllowed('marketing', 'latest', 'archive') ?
+"allowed" : "denied";
+//permitido
+
+echo $acl->isAllowed('marketing', 'latest', 'anything') ?
+"allowed" : "denied";
+// permitido
+]]>
+        </programlisting>
+
+    </sect2>
+
+</sect1>

+ 461 - 461
documentation/manual/es/module_specs/Zend_Acl.xml

@@ -1,461 +1,461 @@
-<sect1 id="zend.acl.introduction">
-    <title>Introducción</title>
-    <para>
-        Zend_Acl provee la implementación de un sistema simple y
-        flexible de Listas de Control de Acceso (ACL, por sus siglas en
-        inglés) para la administración de privilegios. En general, una
-        aplicación puede utilizar las ACL para controlar el acceso a
-        ciertos objetos protegidos, que son requeridos por otros
-        objetos.
-    </para>
-    <para>
-        Para los propósitos de esta documentación,
-        <itemizedlist>
-            <listitem>
-                <para>
-                    Un
-                    <emphasis role="strong">recurso</emphasis>
-                    es un objeto al cual el acceso esta controlado.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                    Un
-                    <emphasis role="strong">rol</emphasis>
-                    es un objeto que puede solicitar acceso a un
-                    recurso.
-                </para>
-            </listitem>
-        </itemizedlist>
-        En términos generales,
-        <emphasis role="strong">
-            Los roles solicitan acceso a los recursos
-        </emphasis>
-        . Por ejemplo, si una persona solicita acceso a un automóvil,
-        entonces la persona se convierte en el rol solicitante, y el
-        automóvil en el recurso, puesto que el acceso al automóvil puede
-        no estar disponible a cualquiera.
-    </para>
-
-    <para>
-        A través de la especificación y uso de Listas de Control de
-        Acceso (ACL), una aplicación puede controlar cómo los objetos
-        solicitantes (roles) han obtenido acceso a objetos protegidos
-        (recursos).
-    </para>
-
-    <sect2 id="zend.acl.introduction.resources">
-        <title>Acerca de los Recursos</title>
-        <para>
-            En Zend_Acl, crear un recurso es muy sencillo. Zend_Acl
-            proporciona el
-            <code>Zend_Acl_Resource_Interface</code>
-            para facilitar a los desarrolladores la creacción de
-            recursos. Una clase solo necesita implementar su interfaz,
-            la cual consiste en un método único,
-            <code>getResourceId()</code>
-            , para que Zend_Acl considere el objeto como un recurso.
-            Adicionalmente,
-            <code>Zend_Acl_Resource</code>
-            se incluye con Zend_Acl como una implementación principal de
-            recursos para los desarrolladores para extenderla hasta
-            donde lo deseen.
-        </para>
-        <para>
-            Zend_Acl provee un estructura de árbol a la cual pueden ser
-            agregados múltiples recursos (o "Áreas con Controles de
-            Acceso").Ya que los recursos son almacenados en esta
-            estructura de árbol, estos pueden ser organizados desde lo
-            general (hacia la raíz del árbol) a lo específico (hacia las
-            ramas del árbol). Consultas sobre un recurso específico
-            buscarán automáticamente, en la jerarquía del
-            recurso, reglas asignadas a recursos anteriores a los que
-            el recurso actual haga referencia, permitiendo la herencia
-            simple de reglas. Por ejemplo, si una regla por defecto se
-            aplica a cada edificio en una ciudad, uno simplemente
-            podría asignar la regla a la ciudad, en lugar de asignar la
-            misma regla a cada edificio. Algunos edificios pueden
-            necesitar excepciones a la regla, sin embargo, y esto es
-            fácil de hacer en Zend_Acl asignando esta excepción a
-            cada edificio que necesite una excepción a la regla. Un
-            recurso sólo puede heredar de un recurso padre, aunque este
-            recurso padre puede tener a la vez su propio recurso padre,
-            y así; sucesivamente.
-        </para>
-        <para>
-            Zend_Acl también soporta privilegios sobre recursos (ej.
-            "crear","leer","actualizar", "borrar"), y el desarrollador
-            puede asignar reglas que afecten o a todos los privilegios o
-            a privilegios específicos sobre un recurso.
-        </para>
-    </sect2>
-
-    <sect2 id="zend.acl.introduction.roles">
-        <title>Acerca de las Reglas</title>
-        <para>
-            Al igual que los recursos, la creación de un rol
-            también es muy simple. Zend_Acl proporciona
-            <code>Zend_Acl_Role_Interface</code>
-            para facilitar a los desarrolladores la creación de
-            roles. Una clase solo necesita la implementación de su
-            interfaz, la cual consiste en un método único,
-            <code>getRoleId()</code>
-            , para que Zend_Acl considere que el objeto es un Rol.
-            Adicionalmente,
-            <code>Zend_Acl_Role</code>
-            está incluido con Zend_Acl como una implementación principal
-            del rol para que los desarrolladores la extiendan hasta
-            donde lo deseen.
-        </para>
-        <para>
-            En Zend_Acl, un Rol puede heredar de otro o más roles. Esto
-            es para soportar herencia de reglas entre roles. Por ejemplo,
-            un Rol de usuario, como "sally", puede estar bajo uno o más
-            roles padre, como "editor" y "administrador". El
-            desarrollador puede asignar reglas a "editor" y
-            "administrador" por separado, y "sally" puede heredar tales
-            reglas de ambos, sin tener que asignar reglas directamente a
-            "sally".
-        </para>
-        <para>
-            Dado que la habilidad de herencia desde múltiples roles es
-            muy util, múltiples herencias tambien introduce cierto grado
-            de complejidad. El siguiente ejemplo ilustra la condición de
-            ambiguedad y como Zend_Acl soluciona esto.
-        </para>
-        <example
-            id="zend.acl.introduction.roles.example.multiple_inheritance">
-            <title>Herencia Multiple entre Roles</title>
-            <para>
-                El siguiente código define tres roles principales - "
-                <code>invitado</code>
-                ", "
-                <code>miembro</code>
-                ", y "
-                <code>admin</code>
-                " - de los cuales otros roles pueden heredar. Entonces,
-                un rol identificado como "
-                <code>unUsuario</code>
-                " es colocado y hereda de los otros tres roles. El orden en
-                el cual estos roles aparecen en el array
-                <code>$parents</code>
-                es importante. Cuando es necesario, Zend_Acl busca por
-                reglas de acceso definidas no solo para el rol
-                solicitado (aquí, "
-                <code>unUsuario</code>
-                "), sino también sobre los roles heredados (aquí, "
-                <code>invitado</code>
-                ", "
-                <code>miembro</code>
-                ", y "
-                <code>admin</code>
-                "):
-            </para>
-            <programlisting role="php"><![CDATA[<?php
-require_once 'Zend/Acl.php';
-$acl = new Zend_Acl();
-
-require_once 'Zend/Acl/Role.php';
-$acl->addRole(new Zend_Acl_Role('invitado'))
-    ->addRole(new Zend_Acl_Role('miembro'))
-    ->addRole(new Zend_Acl_Role('admin'));
-
-$parents = array('invitado', 'miembro', 'admin');
-$acl->addRole(new Zend_Acl_Role('unUsuario'), $parents);
-
-require_once 'Zend/Acl/Resource.php';
-$acl->add(new Zend_Acl_Resource('unRecurso'));
-
-$acl->deny('invitado', 'unRecurso');
-$acl->allow('miembro', 'unRecurso');
-
-echo $acl->isAllowed('unUsuario', 'unRecurso') ? 'permitido' : 'denegado';]]>
-            </programlisting>
-            <para>
-                Ya que no hay reglas específicamente definidas para
-                el rol "
-                <code>unUsuario</code>
-                " y "
-                <code>unRecurso</code>
-                ", Zend_Acl debe buscar por reglas que puedan estar
-                definidas para roles "
-                <code>unUsuario</code>
-                " hereda. Primero, el rol "
-                <code>admin</code>
-                " es visitado, y no hay regla de acceso definida
-                para éste. Luego, el rol "
-                <code>miembro</code>
-                " es visitado, y Zend_Acl encuentra que aquí hay una
-                regla especificando que "
-                <code>miembro</code>
-                " tiene permiso para acceder a "
-                <code>unRecurso</code>
-                ".
-            </para>
-            <para>
-                Así, Zend_Acl va a seguir examinando las reglas definidas
-                para otros roles padre, sin embargo, encontraría que "
-                <code>invitado</code>
-                " tiene el acceso denegado a "
-                <code>unRecurso</code>
-                ". Este hecho introduce una ambigüedad debido a que
-                ahora "
-                <code>unUsuario</code>
-                " está tanto denegado como permitido para acceder a "
-                <code>unRecurso</code>
-                ", por la razon de tener un conflicto de reglas
-                heredadas de diferentes roles padre.
-            </para>
-            <para>
-                Zend_Acl resuelve esta ambiguedad completando la
-                consulta cuando encuentra la primera regla que es
-                directamente aplicable a la consulta. En este caso, dado
-                que el rol "
-                <code>miembro</code>
-                " es examinado antes que el rol "
-                <code>invitado</code>
-                ", el código de ejemplo mostraría "
-                <code>permitido</code>
-                ".
-            </para>
-        </example>
-        <note>
-            <para>
-                Cuando se especifican múltiples padres para un Rol, se
-                debe tener en cuenta que el último padre listado es el
-                primero en ser buscado por reglas aplicables para una
-                solicitud de autorización.
-            </para>
-        </note>
-    </sect2>
-
-    <sect2 id="zend.acl.introduction.creating">
-        <title>Creando las Listas de Control de Acceso (ACL)</title>
-
-        <para>
-            Una ACL puede representar cualquier grupo de objetos físicos
-            o virtuales que desee. Para propósitos de demostración,
-            sin embargo, crearemos un ACL básico para un Sistema de
-            Administración de Contenido que mantendrá varias escalas de
-            grupos sobre una amplia variedad de áreas. Para crear un
-            nuevo objeto ACL, iniciamos la ACL sin parámetros:
-        </para>
-
-        <programlisting role="php"><![CDATA[<?php
-require_once 'Zend/Acl.php';
-
-$acl = new Zend_Acl();]]>
-        </programlisting>
-
-        <note>
-            <para>
-                Hasta que un desarrollador especifique una regla
-                "permitido", Zend_Acl deniega el acceso a cada privilegio
-                sobre cada recurso para cada rol.
-            </para>
-        </note>
-    </sect2>
-
-    <sect2 id="zend.acl.introduction.role_registry">
-        <title>Registrando Roles</title>
-
-        <para>
-            El Sistema de Administración de Contenido casi
-            siempre necesita una jerarquía de permisos para determinar
-            la capacidad de identificación de sus usuarios. Puede haber
-            un grupo de 'Invitados' para permitir acceso limitado para
-            demostraciones, un grupo de 'Personal' para la mayoría de
-            usuarios del CMS quienes realizan la mayor parte de
-            operaciones del día a día, un grupo 'Editores' para las
-            responsabilidades de publicación, revisión, archivo y
-            eliminación de contenido, y finalmente un grupo
-            'Administradores' cuyas tareas pueden incluir todas las de los
-            otros grupos y también el mantenimiento de la información
-            delicada, manejo de usuarios, configuración de los datos
-            básicos y su respaldo/exportación. Este grupo de permisos
-            pueden ser representados en un registro de roles,
-            permitiendo a cada grupo heredar los privilegios de los
-            grupos 'padre', al igual que proporcionando distintos
-            privilegios solo para su grupo individual. Los permisos pueden
-            ser expresados como:
-        </para>
-
-        <table
-            id="zend.acl.introduction.role_registry.table.example_cms_access_controls">
-            <title>Controles de Acceso para un CMS de ejemplo</title>
-            <tgroup cols="3">
-                <thead>
-                    <row>
-                        <entry>Nombre</entry>
-                        <entry>Permisos Individuales</entry>
-                        <entry>Hereda permisos de</entry>
-                    </row>
-                </thead>
-                <tbody>
-                    <row>
-                        <entry>Invitado</entry>
-                        <entry>View</entry>
-                        <entry>N/A</entry>
-                    </row>
-                    <row>
-                        <entry>Personal</entry>
-                        <entry>Editar, Enviar, Revisar</entry>
-                        <entry>Invitado</entry>
-                    </row>
-                    <row>
-                        <entry>Editor</entry>
-                        <entry>Publicar, Archivar, Eliminar</entry>
-                        <entry>Personal</entry>
-                    </row>
-                    <row>
-                        <entry>Administrador</entry>
-                        <entry>(Todos los accesos permitidos)</entry>
-                        <entry>N/A</entry>
-                    </row>
-                </tbody>
-            </tgroup>
-        </table>
-
-        <para>
-            Para este ejemplo, se usa
-            <code>Zend_Acl_Role</code>
-            , pero cualquier objeto que implemente
-            <code>Zend_Acl_Role_Interface</code>
-            es admisible. Estos grupos pueden ser agragados al registro
-            de roles de la siguiente manera:
-        </para>
-
-        <programlisting role="php"><![CDATA[<?php
-require_once 'Zend/Acl.php';
-
-$acl = new Zend_Acl();
-
-// Agregar grupos al registro de roles usando Zend_Acl_Role
-require_once 'Zend/Acl/Role.php';
-
-// Invitado no hereda controles de acceso
-$rolInvitado = new Zend_Acl_Role('invitado');
-$acl->addRole($rolInvitado);
-
-// Personal hereda de Invitado
-$acl->addRole(new Zend_Acl_Role('personal'), $rolInvitado);
-
-/* alternativamente, lo de arriba puede ser escrito así:
-$rolInvitado = $acl->addRole(new Zend_Acl_Role('personal'), 'invitado');
-//*/
-
-// Editor hereda desde personal
-$acl->addRole(new Zend_Acl_Role('editor'), 'personal');
-
-// Administrador no hereda controles de acceso
-$acl->addRole(new Zend_Acl_Role('administrador'));]]>
-        </programlisting>
-
-    </sect2>
-
-    <sect2 id="zend.acl.introduction.defining">
-        <title>Definiendo Controles de Acceso</title>
-
-        <para>
-            Ahora que la ACL contiene los roles relevantes, se pueden
-            establecer reglas que definan cómo los roles pueden acceder
-            a los recursos. Tenga en cuenta que no definiremos ningún
-            recurso en particular para este ejemplo, el cual está
-            simplificado para ilustrar que las reglas se aplican a todos
-            los recursos. Zend_Acl proporciona una forma práctica por la
-            cual las reglas solo necesitan ser asignadas de lo general a
-            lo especifico, minimizando el número de reglas necesarias,
-            porque los recursos y roles heredan reglas que están
-            definidas en sus padres.
-        </para>
-
-        <para>
-            Consecuentemente, podemos definir un grupo razonablemente
-            complejo de reglas con un mínimo de código. Para aplicar
-            estos permisos básicos como están definidos arriba:
-        </para>
-
-        <programlisting role="php"><![CDATA[<?php
-require_once 'Zend/Acl.php';
-
-$acl = new Zend_Acl();
-
-require_once 'Zend/Acl/Role.php';
-
-$rolInvitado = new Zend_Acl_Role('invitado');
-$acl->addRole($rolInvitado);
-$acl->addRole(new Zend_Acl_Role('personal'), $rolInvitado);
-$acl->addRole(new Zend_Acl_Role('editor'), 'personal');
-$acl->addRole(new Zend_Acl_Role('administrador'));
-
-// Invitado solo puede ver el contenido
-$acl->allow($rolInvitado, null, 'ver');
-
-/* Lo de arriba puede ser escrito de la siguiente forma alternativa:
-$acl->allow('invitado', null, 'ver');
-//*/
-
-// Personal hereda el privilegio de ver de invitado, pero también necesita privilegios adicionales
-$acl->allow('personal', null, array('editar', 'enviar', 'revisar'));
-
-// Editor hereda los privilegios de ver, editar, enviar, y revisar de personal,
-// pero también necesita privilegios adicionales
-$acl->allow('editor', null, array('publicar', 'archivar', 'eliminar'));
-
-// Administrador no hereda nada, pero tiene todos los privilegios permitidos
-$acl->allow('administrador');]]>
-        </programlisting>
-
-        <para>
-            El valor
-            <code>null</code>
-            en las llamadas de
-            <code>allow()</code>
-            es usado para indicar que las reglas de permiso se aplican a
-            todos los recursos.
-        </para>
-
-    </sect2>
-
-    <sect2 id="zend.acl.introduction.querying">
-        <title>Consultando la ACL</title>
-
-        <para>
-            Ahora tenemos una ACL flexible que puede ser usada para
-            determinar qué solicitantes tienen permisos para realizar
-            funciones a través de la aplicacion web. Ejecutar
-            consultas es la forma más simple de usar el método
-            <code>isAllowed()</code>
-            :
-        </para>
-
-        <programlisting role="php"><![CDATA[<?php
-echo $acl->isAllowed('invitado', null, 'ver') ?
-     "permitido" : "denegado"; // permitido
-
-echo $acl->isAllowed('personal', null, 'publicar') ?
-     "permitido" : "denegado"; // denegado
-
-echo $acl->isAllowed('personal', null, 'revisar') ?
-     "permitido" : "denegado"; // permitido
-
-echo $acl->isAllowed('editor', null, 'ver') ?
-     "permitido" : "denegado"; // permitido debido a la herencia de invitado
-
-echo $acl->isAllowed('editor', null, 'actualizar') ?
-     "permitido" : "denegado"; // denegado debido a que no hay regla de permiso para 'actualizar'
-
-echo $acl->isAllowed('administrador', null, 'ver') ?
-     "permitido" : "denegado"; // permitido porque administrador tiene permitidos todos los privilegios
-
-echo $acl->isAllowed('administrador') ?
-     "permitido" : "denegado"; // permitido porque administrador tiene permitidos todos los privilegios
-
-echo $acl->isAllowed('administrador', null, 'actualizar') ?
-     "permitido" : "denegado"; // permitido porque administrador tiene permitidos todos los privilegios]]>
-        </programlisting>
-    </sect2>
-</sect1> 
-<!--
-    vim:se ts=4 sw=4 et:
--->
+<sect1 id="zend.acl.introduction">
+    <title>Introducción</title>
+    <para>
+        Zend_Acl provee la implementación de un sistema simple y
+        flexible de Listas de Control de Acceso (ACL, por sus siglas en
+        inglés) para la administración de privilegios. En general, una
+        aplicación puede utilizar las ACL para controlar el acceso a
+        ciertos objetos protegidos, que son requeridos por otros
+        objetos.
+    </para>
+    <para>
+        Para los propósitos de esta documentación,
+        <itemizedlist>
+            <listitem>
+                <para>
+                    Un
+                    <emphasis role="strong">recurso</emphasis>
+                    es un objeto al cual el acceso esta controlado.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Un
+                    <emphasis role="strong">rol</emphasis>
+                    es un objeto que puede solicitar acceso a un
+                    recurso.
+                </para>
+            </listitem>
+        </itemizedlist>
+        En términos generales,
+        <emphasis role="strong">
+            Los roles solicitan acceso a los recursos
+        </emphasis>
+        . Por ejemplo, si una persona solicita acceso a un automóvil,
+        entonces la persona se convierte en el rol solicitante, y el
+        automóvil en el recurso, puesto que el acceso al automóvil puede
+        no estar disponible a cualquiera.
+    </para>
+
+    <para>
+        A través de la especificación y uso de Listas de Control de
+        Acceso (ACL), una aplicación puede controlar cómo los objetos
+        solicitantes (roles) han obtenido acceso a objetos protegidos
+        (recursos).
+    </para>
+
+    <sect2 id="zend.acl.introduction.resources">
+        <title>Acerca de los Recursos</title>
+        <para>
+            En Zend_Acl, crear un recurso es muy sencillo. Zend_Acl
+            proporciona el
+            <code>Zend_Acl_Resource_Interface</code>
+            para facilitar a los desarrolladores la creacción de
+            recursos. Una clase solo necesita implementar su interfaz,
+            la cual consiste en un método único,
+            <code>getResourceId()</code>
+            , para que Zend_Acl considere el objeto como un recurso.
+            Adicionalmente,
+            <code>Zend_Acl_Resource</code>
+            se incluye con Zend_Acl como una implementación principal de
+            recursos para los desarrolladores para extenderla hasta
+            donde lo deseen.
+        </para>
+        <para>
+            Zend_Acl provee un estructura de árbol a la cual pueden ser
+            agregados múltiples recursos (o "Áreas con Controles de
+            Acceso").Ya que los recursos son almacenados en esta
+            estructura de árbol, estos pueden ser organizados desde lo
+            general (hacia la raíz del árbol) a lo específico (hacia las
+            ramas del árbol). Consultas sobre un recurso específico
+            buscarán automáticamente, en la jerarquía del
+            recurso, reglas asignadas a recursos anteriores a los que
+            el recurso actual haga referencia, permitiendo la herencia
+            simple de reglas. Por ejemplo, si una regla por defecto se
+            aplica a cada edificio en una ciudad, uno simplemente
+            podría asignar la regla a la ciudad, en lugar de asignar la
+            misma regla a cada edificio. Algunos edificios pueden
+            necesitar excepciones a la regla, sin embargo, y esto es
+            fácil de hacer en Zend_Acl asignando esta excepción a
+            cada edificio que necesite una excepción a la regla. Un
+            recurso sólo puede heredar de un recurso padre, aunque este
+            recurso padre puede tener a la vez su propio recurso padre,
+            y así; sucesivamente.
+        </para>
+        <para>
+            Zend_Acl también soporta privilegios sobre recursos (ej.
+            "crear","leer","actualizar", "borrar"), y el desarrollador
+            puede asignar reglas que afecten o a todos los privilegios o
+            a privilegios específicos sobre un recurso.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.acl.introduction.roles">
+        <title>Acerca de las Reglas</title>
+        <para>
+            Al igual que los recursos, la creación de un rol
+            también es muy simple. Zend_Acl proporciona
+            <code>Zend_Acl_Role_Interface</code>
+            para facilitar a los desarrolladores la creación de
+            roles. Una clase solo necesita la implementación de su
+            interfaz, la cual consiste en un método único,
+            <code>getRoleId()</code>
+            , para que Zend_Acl considere que el objeto es un Rol.
+            Adicionalmente,
+            <code>Zend_Acl_Role</code>
+            está incluido con Zend_Acl como una implementación principal
+            del rol para que los desarrolladores la extiendan hasta
+            donde lo deseen.
+        </para>
+        <para>
+            En Zend_Acl, un Rol puede heredar de otro o más roles. Esto
+            es para soportar herencia de reglas entre roles. Por ejemplo,
+            un Rol de usuario, como "sally", puede estar bajo uno o más
+            roles padre, como "editor" y "administrador". El
+            desarrollador puede asignar reglas a "editor" y
+            "administrador" por separado, y "sally" puede heredar tales
+            reglas de ambos, sin tener que asignar reglas directamente a
+            "sally".
+        </para>
+        <para>
+            Dado que la habilidad de herencia desde múltiples roles es
+            muy util, múltiples herencias tambien introduce cierto grado
+            de complejidad. El siguiente ejemplo ilustra la condición de
+            ambiguedad y como Zend_Acl soluciona esto.
+        </para>
+        <example
+            id="zend.acl.introduction.roles.example.multiple_inheritance">
+            <title>Herencia Multiple entre Roles</title>
+            <para>
+                El siguiente código define tres roles principales - "
+                <code>invitado</code>
+                ", "
+                <code>miembro</code>
+                ", y "
+                <code>admin</code>
+                " - de los cuales otros roles pueden heredar. Entonces,
+                un rol identificado como "
+                <code>unUsuario</code>
+                " es colocado y hereda de los otros tres roles. El orden en
+                el cual estos roles aparecen en el array
+                <code>$parents</code>
+                es importante. Cuando es necesario, Zend_Acl busca por
+                reglas de acceso definidas no solo para el rol
+                solicitado (aquí, "
+                <code>unUsuario</code>
+                "), sino también sobre los roles heredados (aquí, "
+                <code>invitado</code>
+                ", "
+                <code>miembro</code>
+                ", y "
+                <code>admin</code>
+                "):
+            </para>
+            <programlisting role="php"><![CDATA[<?php
+require_once 'Zend/Acl.php';
+$acl = new Zend_Acl();
+
+require_once 'Zend/Acl/Role.php';
+$acl->addRole(new Zend_Acl_Role('invitado'))
+    ->addRole(new Zend_Acl_Role('miembro'))
+    ->addRole(new Zend_Acl_Role('admin'));
+
+$parents = array('invitado', 'miembro', 'admin');
+$acl->addRole(new Zend_Acl_Role('unUsuario'), $parents);
+
+require_once 'Zend/Acl/Resource.php';
+$acl->add(new Zend_Acl_Resource('unRecurso'));
+
+$acl->deny('invitado', 'unRecurso');
+$acl->allow('miembro', 'unRecurso');
+
+echo $acl->isAllowed('unUsuario', 'unRecurso') ? 'permitido' : 'denegado';]]>
+            </programlisting>
+            <para>
+                Ya que no hay reglas específicamente definidas para
+                el rol "
+                <code>unUsuario</code>
+                " y "
+                <code>unRecurso</code>
+                ", Zend_Acl debe buscar por reglas que puedan estar
+                definidas para roles "
+                <code>unUsuario</code>
+                " hereda. Primero, el rol "
+                <code>admin</code>
+                " es visitado, y no hay regla de acceso definida
+                para éste. Luego, el rol "
+                <code>miembro</code>
+                " es visitado, y Zend_Acl encuentra que aquí hay una
+                regla especificando que "
+                <code>miembro</code>
+                " tiene permiso para acceder a "
+                <code>unRecurso</code>
+                ".
+            </para>
+            <para>
+                Así, Zend_Acl va a seguir examinando las reglas definidas
+                para otros roles padre, sin embargo, encontraría que "
+                <code>invitado</code>
+                " tiene el acceso denegado a "
+                <code>unRecurso</code>
+                ". Este hecho introduce una ambigüedad debido a que
+                ahora "
+                <code>unUsuario</code>
+                " está tanto denegado como permitido para acceder a "
+                <code>unRecurso</code>
+                ", por la razon de tener un conflicto de reglas
+                heredadas de diferentes roles padre.
+            </para>
+            <para>
+                Zend_Acl resuelve esta ambiguedad completando la
+                consulta cuando encuentra la primera regla que es
+                directamente aplicable a la consulta. En este caso, dado
+                que el rol "
+                <code>miembro</code>
+                " es examinado antes que el rol "
+                <code>invitado</code>
+                ", el código de ejemplo mostraría "
+                <code>permitido</code>
+                ".
+            </para>
+        </example>
+        <note>
+            <para>
+                Cuando se especifican múltiples padres para un Rol, se
+                debe tener en cuenta que el último padre listado es el
+                primero en ser buscado por reglas aplicables para una
+                solicitud de autorización.
+            </para>
+        </note>
+    </sect2>
+
+    <sect2 id="zend.acl.introduction.creating">
+        <title>Creando las Listas de Control de Acceso (ACL)</title>
+
+        <para>
+            Una ACL puede representar cualquier grupo de objetos físicos
+            o virtuales que desee. Para propósitos de demostración,
+            sin embargo, crearemos un ACL básico para un Sistema de
+            Administración de Contenido que mantendrá varias escalas de
+            grupos sobre una amplia variedad de áreas. Para crear un
+            nuevo objeto ACL, iniciamos la ACL sin parámetros:
+        </para>
+
+        <programlisting role="php"><![CDATA[<?php
+require_once 'Zend/Acl.php';
+
+$acl = new Zend_Acl();]]>
+        </programlisting>
+
+        <note>
+            <para>
+                Hasta que un desarrollador especifique una regla
+                "permitido", Zend_Acl deniega el acceso a cada privilegio
+                sobre cada recurso para cada rol.
+            </para>
+        </note>
+    </sect2>
+
+    <sect2 id="zend.acl.introduction.role_registry">
+        <title>Registrando Roles</title>
+
+        <para>
+            El Sistema de Administración de Contenido casi
+            siempre necesita una jerarquía de permisos para determinar
+            la capacidad de identificación de sus usuarios. Puede haber
+            un grupo de 'Invitados' para permitir acceso limitado para
+            demostraciones, un grupo de 'Personal' para la mayoría de
+            usuarios del CMS quienes realizan la mayor parte de
+            operaciones del día a día, un grupo 'Editores' para las
+            responsabilidades de publicación, revisión, archivo y
+            eliminación de contenido, y finalmente un grupo
+            'Administradores' cuyas tareas pueden incluir todas las de los
+            otros grupos y también el mantenimiento de la información
+            delicada, manejo de usuarios, configuración de los datos
+            básicos y su respaldo/exportación. Este grupo de permisos
+            pueden ser representados en un registro de roles,
+            permitiendo a cada grupo heredar los privilegios de los
+            grupos 'padre', al igual que proporcionando distintos
+            privilegios solo para su grupo individual. Los permisos pueden
+            ser expresados como:
+        </para>
+
+        <table
+            id="zend.acl.introduction.role_registry.table.example_cms_access_controls">
+            <title>Controles de Acceso para un CMS de ejemplo</title>
+            <tgroup cols="3">
+                <thead>
+                    <row>
+                        <entry>Nombre</entry>
+                        <entry>Permisos Individuales</entry>
+                        <entry>Hereda permisos de</entry>
+                    </row>
+                </thead>
+                <tbody>
+                    <row>
+                        <entry>Invitado</entry>
+                        <entry>View</entry>
+                        <entry>N/A</entry>
+                    </row>
+                    <row>
+                        <entry>Personal</entry>
+                        <entry>Editar, Enviar, Revisar</entry>
+                        <entry>Invitado</entry>
+                    </row>
+                    <row>
+                        <entry>Editor</entry>
+                        <entry>Publicar, Archivar, Eliminar</entry>
+                        <entry>Personal</entry>
+                    </row>
+                    <row>
+                        <entry>Administrador</entry>
+                        <entry>(Todos los accesos permitidos)</entry>
+                        <entry>N/A</entry>
+                    </row>
+                </tbody>
+            </tgroup>
+        </table>
+
+        <para>
+            Para este ejemplo, se usa
+            <code>Zend_Acl_Role</code>
+            , pero cualquier objeto que implemente
+            <code>Zend_Acl_Role_Interface</code>
+            es admisible. Estos grupos pueden ser agragados al registro
+            de roles de la siguiente manera:
+        </para>
+
+        <programlisting role="php"><![CDATA[<?php
+require_once 'Zend/Acl.php';
+
+$acl = new Zend_Acl();
+
+// Agregar grupos al registro de roles usando Zend_Acl_Role
+require_once 'Zend/Acl/Role.php';
+
+// Invitado no hereda controles de acceso
+$rolInvitado = new Zend_Acl_Role('invitado');
+$acl->addRole($rolInvitado);
+
+// Personal hereda de Invitado
+$acl->addRole(new Zend_Acl_Role('personal'), $rolInvitado);
+
+/* alternativamente, lo de arriba puede ser escrito así:
+$rolInvitado = $acl->addRole(new Zend_Acl_Role('personal'), 'invitado');
+//*/
+
+// Editor hereda desde personal
+$acl->addRole(new Zend_Acl_Role('editor'), 'personal');
+
+// Administrador no hereda controles de acceso
+$acl->addRole(new Zend_Acl_Role('administrador'));]]>
+        </programlisting>
+
+    </sect2>
+
+    <sect2 id="zend.acl.introduction.defining">
+        <title>Definiendo Controles de Acceso</title>
+
+        <para>
+            Ahora que la ACL contiene los roles relevantes, se pueden
+            establecer reglas que definan cómo los roles pueden acceder
+            a los recursos. Tenga en cuenta que no definiremos ningún
+            recurso en particular para este ejemplo, el cual está
+            simplificado para ilustrar que las reglas se aplican a todos
+            los recursos. Zend_Acl proporciona una forma práctica por la
+            cual las reglas solo necesitan ser asignadas de lo general a
+            lo especifico, minimizando el número de reglas necesarias,
+            porque los recursos y roles heredan reglas que están
+            definidas en sus padres.
+        </para>
+
+        <para>
+            Consecuentemente, podemos definir un grupo razonablemente
+            complejo de reglas con un mínimo de código. Para aplicar
+            estos permisos básicos como están definidos arriba:
+        </para>
+
+        <programlisting role="php"><![CDATA[<?php
+require_once 'Zend/Acl.php';
+
+$acl = new Zend_Acl();
+
+require_once 'Zend/Acl/Role.php';
+
+$rolInvitado = new Zend_Acl_Role('invitado');
+$acl->addRole($rolInvitado);
+$acl->addRole(new Zend_Acl_Role('personal'), $rolInvitado);
+$acl->addRole(new Zend_Acl_Role('editor'), 'personal');
+$acl->addRole(new Zend_Acl_Role('administrador'));
+
+// Invitado solo puede ver el contenido
+$acl->allow($rolInvitado, null, 'ver');
+
+/* Lo de arriba puede ser escrito de la siguiente forma alternativa:
+$acl->allow('invitado', null, 'ver');
+//*/
+
+// Personal hereda el privilegio de ver de invitado, pero también necesita privilegios adicionales
+$acl->allow('personal', null, array('editar', 'enviar', 'revisar'));
+
+// Editor hereda los privilegios de ver, editar, enviar, y revisar de personal,
+// pero también necesita privilegios adicionales
+$acl->allow('editor', null, array('publicar', 'archivar', 'eliminar'));
+
+// Administrador no hereda nada, pero tiene todos los privilegios permitidos
+$acl->allow('administrador');]]>
+        </programlisting>
+
+        <para>
+            El valor
+            <code>null</code>
+            en las llamadas de
+            <code>allow()</code>
+            es usado para indicar que las reglas de permiso se aplican a
+            todos los recursos.
+        </para>
+
+    </sect2>
+
+    <sect2 id="zend.acl.introduction.querying">
+        <title>Consultando la ACL</title>
+
+        <para>
+            Ahora tenemos una ACL flexible que puede ser usada para
+            determinar qué solicitantes tienen permisos para realizar
+            funciones a través de la aplicacion web. Ejecutar
+            consultas es la forma más simple de usar el método
+            <code>isAllowed()</code>
+            :
+        </para>
+
+        <programlisting role="php"><![CDATA[<?php
+echo $acl->isAllowed('invitado', null, 'ver') ?
+     "permitido" : "denegado"; // permitido
+
+echo $acl->isAllowed('personal', null, 'publicar') ?
+     "permitido" : "denegado"; // denegado
+
+echo $acl->isAllowed('personal', null, 'revisar') ?
+     "permitido" : "denegado"; // permitido
+
+echo $acl->isAllowed('editor', null, 'ver') ?
+     "permitido" : "denegado"; // permitido debido a la herencia de invitado
+
+echo $acl->isAllowed('editor', null, 'actualizar') ?
+     "permitido" : "denegado"; // denegado debido a que no hay regla de permiso para 'actualizar'
+
+echo $acl->isAllowed('administrador', null, 'ver') ?
+     "permitido" : "denegado"; // permitido porque administrador tiene permitidos todos los privilegios
+
+echo $acl->isAllowed('administrador') ?
+     "permitido" : "denegado"; // permitido porque administrador tiene permitidos todos los privilegios
+
+echo $acl->isAllowed('administrador', null, 'actualizar') ?
+     "permitido" : "denegado"; // permitido porque administrador tiene permitidos todos los privilegios]]>
+        </programlisting>
+    </sect2>
+</sect1> 
+<!--
+    vim:se ts=4 sw=4 et:
+-->

+ 651 - 651
documentation/manual/es/module_specs/Zend_Amf-Server.xml

@@ -1,651 +1,651 @@
-<sect1 id="zend.amf.server">
-    <title>Zend_Amf_Server</title>
-
-    <para>
-        <code>Zend_Amf_Server</code> proporciona un servidor al estilo RPC para 
-        tramitar solicitudes hechas desde Adobe Flash Player utilizando el protocolo AMF. 
-        Al igual que todas las clases de servidor, Zend Framework sigue la API de
-        SoapServer, proporcionando una interfaz para crear servidores fácil de recordar.
-
-    </para>
-
-    <example id="zend.amf.server.basic">
-        <title>Servidor AMF básico</title>
-
-        <para>
-            Asumamos que ha creado la clase <code>Foo</code> con una
-            variedad de métodos públicos. Usando el siguiente código, puede
-            crear un servidor AMF:
-        </para>
-
-        <programlisting role="php"><![CDATA[
-$servidor = new Zend_Amf_Server();
-$servidor->setClass('Foo');
-$respuesta = $servidor->handle();
-echo $respuesta;
-]]>
-        </programlisting>
-
-        <para>
-            Alternativamente, en su lugar puede elegir agregar una función simple como 
-            llamada de retorno:
-        </para>
-
-        <programlisting role="php"><![CDATA[
-$servidor = new Zend_Amf_Server();
-$servidor->addFunction('myUberCoolFunction');
-$respuesta = $servidor->handle();
-echo $respuesta;
-]]>
-        </programlisting>
-
-        <para>
-            También puede combinar y examinar la identidad de varias clases y funciones.
-            Al hacerlo, sugerimos darle un espacio de nombres a cada una para 
-            garantizar que no ocurran colisiones entre nombres de métodos; 
-            puede hacerse simplemente pasando una segunda cadena de argumentos para cualquier <code>addFunction()</code> o
-            <code>setClass()</code>:
-        </para>
-
-        <programlisting role="php"><![CDATA[
-$servidor = new Zend_Amf_Server();
-$servidor->addFunction('myUberCoolFunction', 'my')
-       ->setClass('Foo', 'foo')
-       ->setClass('Bar', 'bar');
-$respuesta = $servidor->handle();
-echo $respuesta;
-]]>
-        </programlisting>
-
-        <para>
-        El <code>Zend_Amf_Server</code> también permite cargar servicios 
-        dinámicamente, en función de una ruta de directorio ya suministrada. 
-        Puede añadir al servidor tantos directorios como desee. 
-        El orden en que se añadan los directorios al servidor será el orden en que
-        se realizarán las búsquedas LIFO en los directorios para coincidir 
-        con la clase.
-        El método <code>addDirectory()</code> realiza la acción de añadir directorios. 
-        </para>
-
-        <programlisting role="php"><![CDATA[
-$servidor->addDirectory(dirname(__FILE__) .'/../services/');
-$servidor->addDirectory(dirname(__FILE__) .'/../package/');
-]]>
-        </programlisting>
-
-        <para>
-        Cuando se llama a servicios remotos, los nombres de los directorios que 
-        contengan las fuentes pueden tener los delimitadores guión bajo (_) y el punto (.). 
-        Cuando se utilize un guión bajo (_) tanto en PEAR como en Zend Framework, 
-        se respetarán los nombres de clases de acuerdo a las convenciones de nomenclatura. 
-        Esto significa que si usted llama al servicio com_Foo_Bar el servidor 
-        buscará el archivo Bar.php en cada una de las rutas incluidas en <code>com/Foo/Bar.php</code>.
-        Si se usa la notación punto para su servicio remoto como <code>com.Foo.Bar</code> 
-        cada ruta incluida deberá tener <code>com/Foo/Bar.php</code> agregado al final
-        para autocargar Bar.php.
-        </para>
-
-        <para>
-            Todos las solicitudes AMF enviadas al script serán manejadas 
-            por el servidor, y este devolverá una respuesta AMF.
-        </para>
-    </example>
-
-    <note>
-        <title>Todos los métodos y las funciones agregadas requieren bloques de documentación (docblocks)</title>
-
-        <para>
-            Como todos los demás componentes del servidor en Zend Framework, 
-            debe documentar los métodos de su clase usando PHP docblocks. 
-            Como mínimo, necesita proporcionar anotaciones para cada argumento 
-            así como para el valor de retorno. Como ejemplos:
-        </para>
-
-        <programlisting role="php"><![CDATA[
-// Función que agregar:
-
-/**
- * @param  string $nombre
- * @param  string $saludo
- * @return string
- */
-function holaMundo($ombre, $saludo = 'Hola')
-{
-    return $saludo . ', ' . $nombre;
-}
-]]>
-        </programlisting>
-
-        <programlisting role="php"><![CDATA[
-// Clase agregada
-
-class Mundo
-{
-    /**
-     * @param  string $nombre
-     * @param  string $saludo
-     * @return string
-     */
-    public function hola($nombre, $saludo = 'Hola')
-    {
-        return $saludo . ', ' . $nombre;
-    }
-}
-]]>
-        </programlisting>
-
-        <para>
-            Pueden usarse otras anotaciones, pero serán ignoradas.
-        </para>
-    </note>
-
-    <sect2 id="zend.amf.server.flex">
-        <title>Conectándose al Servidor desde Flex</title>
-
-        <para>
-            Conectarse a <code>Zend_Amf_Server</code> desde su proyecto Flex
-            es bastante simple; solo necesita apuntar el final del URI
-            a su script <code>Zend_Amf_Server</code>.
-        </para>
-
-        <para>
-            Por ejemplo, digamos que usted ya ha creado su servidor y lo ha 
-            puesto en el fichero <code>server.php</code> en el directorio raíz (root)
-            de su aplicación, por lo tanto la URI es <code>http://example.com/server.php</code>. 
-            En este caso, usted debería modificar su fichero services-config.xml
-            poniendo este valor como atributo al punto final del canal uri.
-       </para>
-        <para>
-             Si nunca ha creado un fichero services-config.xml puede hacerlo 
-             abriendo su proyecto en la ventana del navegador. 
-             Haga clic derecho sobre el nombre del proyecto y seleccione 'properties' (propiedades).
-             En el cuadro de diálogo 'properties' del proyecto ir al menú ‘Flex Build Path' (Crear ruta Flex),
-             luego en la pestaña ‘Library path’ (ruta de biblioteca) asegúrese 
-             de que el fichero 'rpc.swc' sea añadido a su ruta de proyectos
-             y pulse Ok (Aceptar) para cerrar la ventana.  
-        </para>
-        <para>          
-            También necesitará indicarle al compilador que debe usar 
-            services-config.xml para encontrar el punto final de RemoteObject. 
-            Para hacerlo, abra de nuevo el panel de propiedades de su proyecto 
-            haciendo clic en el botón derecho sobre el proyecto en la carpeta del
-            navegador y seleccione 'properties' (propiedades). 
-            Ahora seleccione ‘Flex Compiler' (Compilador Flex) y añada la cadena:
-            -services “services-config.xml". 
-            Presione 'Apply' (Aplicar) y luego en OK para volver a actualizar la opción. 
-            Lo que acaba de hacer es decirle al compilador Flex que busque en el fichero 
-            services-config.xml aquellas variables que se usarán en tiempo de
-            ejecución por la clase RemotingObject.           
-        </para>
-        <para>         
-            Ahora, para conectarnos a nuestros métodos remotos debemos indicarle a Flex
-            qué fichero de configuración de servicios utilizar. 
-            Por esta razón creamos un nuevo fichero 'services-config.xml' 
-            en la carpeta src del proyecto Flex. 
-            Con click derecho sobre el proyecto y seleccionando 'new'(nuevo) 
-            'File' (fichero), se abrirá una nueva ventana. 
-            Seleccione la carpeta del proyecto y luego nombre el archivo 
-            'services-config.xml' y presione 'finish' (finalizar).          
-        </para>
-        <para>
-            Flex ha creado y abierto el nuevo fichero services-config.xml. 
-            Utilice el siguiente texto de ejemplo para su fichero services-config.xml. 
-            Asegúrese de actualizar su punto final para que concuerde con el servidor. 
-            Asegúrese también de guardar el fichero.
-        </para>
-
-        <programlisting role="xml"><![CDATA[
-<?xml version="1.0" encoding="UTF-8"?>
-<services-config>
-    <services>
-        <service id="zend-service"
-            class="flex.messaging.services.RemotingService"
-            messageTypes="flex.messaging.messages.RemotingMessage">
-            <destination id="zend">
-                <channels>
-                    <channel ref="zend-endpoint"/>
-                </channels>
-                <properties>
-                    <source>*</source>
-                </properties>
-            </destination>
-        </service>
-    </services>
-    <channels>
-        <channel-definition id="zend-endpoint"
-            class="mx.messaging.channels.AMFChannel">
-            <endpoint uri="http://example.com/server.php"
-                class="flex.messaging.endpoints.AMFEndpoint"/>
-        </channel-definition>
-    </channels>
-</services-config>
-]]>
-        </programlisting>
-
-        <para>
-            Hay dos puntos clave en el ejemplo. 
-            En primer lugar, pero último en el listado, creamos un canal AMF,
-            y especificamos el punto final como la URL a nuestro <code>Zend_Amf_Server</code>:
-        </para>
-
-        <programlisting role="xml"><![CDATA[
-<channel-definition id="zend-endpoint"
-    <endpoint uri="http://example.com/server.php"
-        class="flex.messaging.endpoints.AMFEndpoint"/>
-</channel-definition>
-]]>
-        </programlisting>
-
-        <para>
-            Advierta que a este canal le hemos dado un identificador, "zend-endpoint".
-            El ejemplo crea un servicio cuyo destino hace referencia a este canal, 
-            asignándole también un ID, en este caso es "zend".
-        </para>
-
-        <para>
-            Dentro de nuestros ficheros Flex MXML, necesitamos vincular un RemoteObject al servicio. 
-            En MXML, esto podría hacerse así:
-        </para>
-
-        <programlisting role="xml"><![CDATA[
-<mx:RemoteObject id="myservice"
-    fault="faultHandler(event)"
-    showBusyCursor="true"
-    source="RoundTrip"
-    destination="zend">
-]]>
-        </programlisting>
-
-        <para>
-            Aquí, hemos definido un nuevo objeto remoto identificado por "myservice" 
-            vinculado destino de servicio "zend" que hemos definido en el fichero
-            <code>services-config.xml</code>. Entonces invocamos sus métodos en 
-            nuestro ActionScript simplemente llamando a "myservice.&lt;method&gt;".
-            (En este caso, el código original "RoundTrip" es el nombre de nuestra
-            aplicación Flex). Un ejemplo:
-        </para>
-
-        <programlisting role="ActionScript"><![CDATA[
-myservice.hello("Wade");
-]]>
-        </programlisting>
-
-        <para>
-            Cuando se usan nombres-de-espacio, puede usarse
-            "myservice.&lt;namespace&gt;.&lt;method&gt;":
-        </para>
-
-        <programlisting role="ActionScript"><![CDATA[
-myservice.world.hello("Wade");
-]]>
-        </programlisting>
-
-        <para>
-            Para más información sobre como invocar a Flex RemoteObject visite el
-            sitio de ayuda de Adobe Flex 3 en:<ulink
-                url="http://livedocs.adobe.com/flex/3/html/help.html?content=data_access_4.html"></ulink>.
-        </para>
-    </sect2>
-
-    <sect2 id="zend.amf.server.errors">
-        <title>Manejo de errores</title>
-
-        <para>
-            Por defecto, todas las excepciones producidas en sus 
-            clases o funciones adjuntas serán capturados y devueltas como 
-            mensajes de error de AMF (AMF ErrorMessages). 
-            Sin embargo, el contenido de estos objetos de mensajes de error
-            variará dependiendo de si el servidor está o no en modo "producción"
-            (el estado por defecto).
-        </para>
-
-        <para>
-            Cuando se está en modo de producción, únicamente el código de excepción será devuelto. 
-            Si desactiva el modo de producción, algo que debe hacerse sólo
-            para probar  -- serán devueltos más detalles de la excepción: 
-            el mensaje de excepción (error), línea y backtrace serán adjuntados.
-        </para>
-
-        <para>
-            Para desactivar el modo de producción, haga lo siguiente:
-        </para>
-
-        <programlisting role="php"><![CDATA[
-$servidor->setProduction(false);
-]]>
-        </programlisting>
-
-        <para>
-            Para habilitarlo nuevamente, pase el valor true en su lugar.
-        </para>
-
-        <programlisting role="php"><![CDATA[
-$servidor->setProduction(true);
-]]>
-        </programlisting>
-
-        <note>
-            <title>¡Deshabilite el modo de producción racionalmente!</title>
-
-            <para>
-                Sugerimos deshabilitar el modo de producción solo cuando se está
-                en modo de desarrollo.
-                Los mensajes de excepción y los backtraces puede contener información 
-                sensible del sistema, y no desea que se pueda acceder a ellas 
-                desde el exterior. 
-                Aunque AMF es un formato binario, ahora al ser abierta la especificación,  
-                cualquiera puede potencialmente deserializar los datos.
-            </para>
-        </note>
-
-        <para>
-            Un área en la que se debe tener especialmente mucho cuidado son los 
-            errores propios de PHP.
-            Cuando la directiva INI <code>display_errors</code> está habilitada,
-            los errores de PHP de cualquier nivel del reporte actual serán
-            pasados directamente a la salida, y potencialmente se podrían hacer 
-            estragos con las respuestas de AMF.
-            Para prevenir estos problemas, sugerimos deshabilitar la directiva 
-            <code>display_errors</code> cuando se está en modo de producción.
-        </para>
-    </sect2>
-
-    <sect2 id="zend.amf.server.response">
-        <title>Respuestas de AMF</title>
-
-        <para>
-            En ocasiones es posible que quiera manipular ligeramente el objeto
-            respuesta, es bastante usual querer devolver algunas cebeceras 
-            de mensajes adicionales. Puede hacerlo mediante el método del servidor 
-            <code>handle()</code> que devuelve el objeto respuesta.
-        </para>
-
-        <example id="zend.amf.server.response.messageHeaderExample">
-            <title>Agregar cabeceras de mensaje a la respuesta de AMF</title>
-
-            <para>
-                En este ejemplo, añadiremos la cabecera de mensaje (MessageHeader) 
-                "foo" con el valor 'bar' a la respuesta antes de devolverla.            
-            </para>
-
-            <programlisting role="php"><![CDATA[
-$respuesta = $servidor->handle();
-$respuesta->addAmfHeader(new Zend_Amf_Value_MessageHeader('foo', true, 'bar'))
-echo $respuesta;
-]]>
-            </programlisting>
-        </example>
-    </sect2>
-
-    <sect2 id="zend.amf.server.typedobjects">
-        <title>Objetos tipados</title>
-
-        <para>
-            Similarmente a SOAP, AMF permite pasar objetos entre cliente y servidor. 
-            Esto le da una gran flexibilidad y coherencia a ambos entornos.
-        </para>
-
-        <para>
-            <code>Zend_Amf</code> ofrece tres métodos para mapear ActionScript 
-             y objetos PHP.
-        </para>
-
-        <itemizedlist>
-            <listitem>
-                <para>
-                    Primero, usted puede crear uniones explícitas a nivel del servidor, 
-                    utilizando el método <code>setClassMap()</code>.
-                    El primer argumento es el nombre de la clase de ActionScript,  
-                    el segundo es el nombre de la clase PHP que lo mapea:
-                </para>
-
-                <programlisting role="php"><![CDATA[
-// Mapea la clase ActionScript 'ContactVO' a la clase PHP 'Contact':
-$servidor->setClassMap('ContactVO', 'Contact');
-]]>
-                </programlisting>
-            </listitem>
-
-            <listitem>
-                <para>
-                    Segundo, en su clase PHP puede ajustar la propiedad como pública
-                    mediante <code>$_explicitType</code>, con el valor 
-                    representativo de la clase ActionScript que mapear:
-                </para>
-
-                <programlisting role="php"><![CDATA[
-class Contact
-{
-    public $_explicitType = 'ContactVO';
-}
-]]>
-                </programlisting>
-            </listitem>
-
-            <listitem>
-                <para>
-                    Tercero, en un sentido similar, puede definir como público el método                
-                    <code>getASClassName()</code> dentro de su clase.
-                    Este método debe devolver la clase ActionScript apropiada:
-                 </para>
-
-                <programlisting role="php"><![CDATA[
-class Contact
-{
-    public function getASClassName()
-    {
-        return 'ContactVO';
-    }
-}
-]]>
-                </programlisting>
-            </listitem>
-        </itemizedlist>
-
-        <para>
-            Aunque hemos creado ContactVO en el servidor, 
-            ahora tenemos que hacer su clase correspondiente en AS3  
-            para que el servidor pueda mapear el objeto.
-        </para>
-        <para>
-            Haga clic derecho sobre la carpeta src del proyecto Flex y seleccione New -> ActionScript File. 
-            Nombre el fichero como ContactVO y pulse 'finish' (finalizar) para verlo. 
-            Copie el siguiente código en el fichero para terminar de crear la clase.
-        </para>
-        <programlisting role="as"><![CDATA[
-package
-{
-    [Bindable]
-    [RemoteClass(alias="ContactVO")]
-    public class ContactVO
-    {
-        public var id:int;
-        public var firstname:String;
-        public var lastname:String;
-        public var email:String;
-        public var mobile:String;
-        public function ProductVO():void {
-        }
-    }
-}
-]]>
-            </programlisting>
-        <para>
-            La clase es sintácticamente equivalente a la de PHP del mismo nombre.
-            Los nombres de variables son exactamente los mismos y necesitan estar 
-            en el mismo contenedor para trabajar correctamente. Hay
-            dos meta tags AS3 únicos en esta clase. 
-            El primero es vinculable y dispara un evento cuando es actualizada.
-            El segundo es el tag RemoteClass y define que esta clase puede tener 
-            mapeado un objeto remoto con un nombre de alias, en este caso <code>ContactVO</code>
-            Es obligatorio que en esta etiqueta(tag), el valor que se estableció es la clase PHP 
-            sea estrictamente equivalente.               
-        </para>
-        <programlisting role="as"><![CDATA[
-[Bindable]
-private var myContact:ContactVO;
-
-private function getContactHandler(event:ResultEvent):void {
-    myContact = ContactVO(event.result);
-}
-]]>
-        </programlisting>
-        <para>
-            El siguiente resultado del evento debido a la llamada de servicio, 
-            se incorporó instantáneamente a ContactVO de Flex. 
-            Cualquier cosa que esté ligada a myContact será actualizada con los
-            datos retornados por ContactVO.
-        </para>
-    </sect2>
-
-    <sect2 id="zend.amf.server.flash">
-        <title>Conectándose al servidor desde Flash</title>
-
-        <para>
-            La conexión a <code>Zend_Amf_Server</code> desde su proyecto Flash
-            es ligeramente distinta a la de Flex. Sin embargo una vez que la conexión 
-            con Flash funcione con <code>Zend_Amf_Server</code> lo hará igual 
-            modo que con Flex. El siguiente ejemplo también puede ser utilizado 
-            desde un fichero Flex AS3. Para nuestra conexión vamos a reutilizar 
-            la misma configuracion <code>Zend_Amf_Server</code> junto a la clase Mundo.
-        </para>
-        <para>
-            Abra Flash CS y cree un nuevo fichero Flash (ActionScript 3). 
-            Nombre al documento como ZendExample.fla y guárdelo en una carpeta 
-            que utilizará para este ejemplo. Cree una nuevo fichero AS3 en el mismo 
-            directorio y llámelo Main.as. Abra ambos ficheros con su editor.
-            Ahora vamos a conectar las dos ficheros a través de la clase documento.
-            Seleccione ZendExample y haga clic en el escenario. 
-            Desde el panel del escenario cambie la propiedad de la clase Document a Main.
-            Esto vincula al fichero Main.as con la interfaz de usuario en ZendExample.fla. 
-            Cuando ejecute el fichero ZendExample de Flash se ejecutará ahora
-            la clase Main.as. 
-            El paso siguiente será añadir ActionScript para hacer una lamada AMF.
-        </para>
-        <para>
-            Ahora vamos a hacer una clase Main(principal) para que podamos enviar 
-            los datos al servidor y mostrar el resultado. 
-            Copie el código siguiente en su fichero Main.as y luego vamos a recorrer 
-            el código para describir cuál es el papel de cada elemento.
-        </para>
-        <programlisting role="as"><![CDATA[
-package {
-  import flash.display.MovieClip;
-  import flash.events.*;
-  import flash.net.NetConnection;
-  import flash.net.Responder;
-
-  public class Main extends MovieClip {
-    private var gateway:String = "http://example.com/server.php";
-    private var connection:NetConnection;
-    private var responder:Responder;
-
-    public function Main() {
-      responder = new Responder(onResult, onFault);
-      connection = new NetConnection;
-      connection.connect(gateway);
-    }
-
-    public function onComplete( e:Event ):void{
-      var params = "Sent to Server";
-      connection.call("World.hello", responder, params);
-    }
-
-    private function onResult(result:Object):void {
-      // Display the returned data
-      trace(String(result));
-    }
-    private function onFault(fault:Object):void {
-      trace(String(fault.description));
-    }
-  }
-}
-]]>
-        </programlisting>
-
-
-        <para>
-            Primero tenemos que importar dos bibliotecas de ActionScript que realizan 
-            la mayor parte del trabajo. La primera es NetConnection que actúa como un 
-            tubo bidireccional entre el cliente y el servidor. 
-            La segunda es un objeto Responder que maneja los valores de retorno desde 
-            el servidor, y que están relacionados con el éxito o el fracaso de la llamada.
-       </para>
-        <programlisting role="as"><![CDATA[
-import flash.net.NetConnection;
-import flash.net.Responder;
-]]>
-        </programlisting>
-        <para>
-            En la clase necesitaremos tres variables para representar a NetConnection, 
-            Responder, y la URL del gateway a nuestra instalación <code>Zend_Amf_Server</code>.
-        </para>
-        <programlisting role="as"><![CDATA[
-private var gateway:String = "http://example.com/server.php";
-private var connection:NetConnection;
-private var responder:Responder;
-]]>
-        </programlisting>
-        <para>
-            En el constructor Main creamos un Responder(respondedor) y una nueva conexión al 
-            punto final de <code>Zend_Amf_Server</code>. El respondedor define dos 
-            diferentes métodos para manejar la respuesta desde el servidor. 
-            Por simplicidad los hemos llamado onResult y onFault.
-        </para>
-        <programlisting role="as"><![CDATA[
-responder = new Responder(onResult, onFault);
-connection = new NetConnection;
-connection.connect(gateway);
-]]>
-        </programlisting>
-        <para>
-            La función onComplete se ejecuta tan pronto como la construcción 
-            ha concluido, enviando los datos al servidor. 
-            Necesitamos añadir una línea más que hace una llamada a la función  
-            <code>Zend_Amf_Server</code> Mundo->hola.
-        </para>
-        <programlisting role="as"><![CDATA[
-connection.call("Mundo.hola", responder, params);
-]]>
-        </programlisting>
-        <para>
-            Cuando creamos la variable responder hemos definido las funciones onResult y onFault 
-            para manejar la respuesta proveniente del servidor. 
-            Hemos añadido la función OnResult para el resultado exitoso desde el servidor. 
-            Cada vez que se ejecuta apropiadamente el manejo de conexión con el 
-            servidor, el manejador de eventos llama esta función.  
-        </para>
-        <programlisting role="as"><![CDATA[
-private function onResult(result:Object):void {
-    // Muestra los datos devueltos
-    trace(String(result));
-}
-]]>
-        </programlisting>
-        <para>
-            La función onFault, se llama si hubo una respuesta nula desde el servidor. 
-            Esto ocurre cuando hay un error en el servidor, la URL al servidor es inválida, 
-            el servicio remoto o método no existe o cualquier otra cuestión 
-            relacionada con la conexión.
-        </para>
-        <programlisting role="as"><![CDATA[
-private function onFault(fault:Object):void {
-    trace(String(fault.description));
-}
-]]>
-        </programlisting>
-        <para>
-            La inclusión de ActionScript para realizar la conexión remota ha finalizado.
-            Al ejecutar el fichero ZendExample, se establece una conexión con Zend_Amf. 
-            En resumen, se han añadido las variables requeridas para abrir una conexión 
-            con el servidor remoto, se han definido qué métodos se deben utilizar cuando su aplicación 
-            recibe una respuesta desde el servidor, y finalmente se han mostrado los datos de salida 
-            devueltos a través de trace().
-        </para>
-
-    </sect2>
-
-</sect1>
-<!--
-vim:se ts=4 sw=4 et:
--->
+<sect1 id="zend.amf.server">
+    <title>Zend_Amf_Server</title>
+
+    <para>
+        <code>Zend_Amf_Server</code> proporciona un servidor al estilo RPC para 
+        tramitar solicitudes hechas desde Adobe Flash Player utilizando el protocolo AMF. 
+        Al igual que todas las clases de servidor, Zend Framework sigue la API de
+        SoapServer, proporcionando una interfaz para crear servidores fácil de recordar.
+
+    </para>
+
+    <example id="zend.amf.server.basic">
+        <title>Servidor AMF básico</title>
+
+        <para>
+            Asumamos que ha creado la clase <code>Foo</code> con una
+            variedad de métodos públicos. Usando el siguiente código, puede
+            crear un servidor AMF:
+        </para>
+
+        <programlisting role="php"><![CDATA[
+$servidor = new Zend_Amf_Server();
+$servidor->setClass('Foo');
+$respuesta = $servidor->handle();
+echo $respuesta;
+]]>
+        </programlisting>
+
+        <para>
+            Alternativamente, en su lugar puede elegir agregar una función simple como 
+            llamada de retorno:
+        </para>
+
+        <programlisting role="php"><![CDATA[
+$servidor = new Zend_Amf_Server();
+$servidor->addFunction('myUberCoolFunction');
+$respuesta = $servidor->handle();
+echo $respuesta;
+]]>
+        </programlisting>
+
+        <para>
+            También puede combinar y examinar la identidad de varias clases y funciones.
+            Al hacerlo, sugerimos darle un espacio de nombres a cada una para 
+            garantizar que no ocurran colisiones entre nombres de métodos; 
+            puede hacerse simplemente pasando una segunda cadena de argumentos para cualquier <code>addFunction()</code> o
+            <code>setClass()</code>:
+        </para>
+
+        <programlisting role="php"><![CDATA[
+$servidor = new Zend_Amf_Server();
+$servidor->addFunction('myUberCoolFunction', 'my')
+       ->setClass('Foo', 'foo')
+       ->setClass('Bar', 'bar');
+$respuesta = $servidor->handle();
+echo $respuesta;
+]]>
+        </programlisting>
+
+        <para>
+        El <code>Zend_Amf_Server</code> también permite cargar servicios 
+        dinámicamente, en función de una ruta de directorio ya suministrada. 
+        Puede añadir al servidor tantos directorios como desee. 
+        El orden en que se añadan los directorios al servidor será el orden en que
+        se realizarán las búsquedas LIFO en los directorios para coincidir 
+        con la clase.
+        El método <code>addDirectory()</code> realiza la acción de añadir directorios. 
+        </para>
+
+        <programlisting role="php"><![CDATA[
+$servidor->addDirectory(dirname(__FILE__) .'/../services/');
+$servidor->addDirectory(dirname(__FILE__) .'/../package/');
+]]>
+        </programlisting>
+
+        <para>
+        Cuando se llama a servicios remotos, los nombres de los directorios que 
+        contengan las fuentes pueden tener los delimitadores guión bajo (_) y el punto (.). 
+        Cuando se utilize un guión bajo (_) tanto en PEAR como en Zend Framework, 
+        se respetarán los nombres de clases de acuerdo a las convenciones de nomenclatura. 
+        Esto significa que si usted llama al servicio com_Foo_Bar el servidor 
+        buscará el archivo Bar.php en cada una de las rutas incluidas en <code>com/Foo/Bar.php</code>.
+        Si se usa la notación punto para su servicio remoto como <code>com.Foo.Bar</code> 
+        cada ruta incluida deberá tener <code>com/Foo/Bar.php</code> agregado al final
+        para autocargar Bar.php.
+        </para>
+
+        <para>
+            Todos las solicitudes AMF enviadas al script serán manejadas 
+            por el servidor, y este devolverá una respuesta AMF.
+        </para>
+    </example>
+
+    <note>
+        <title>Todos los métodos y las funciones agregadas requieren bloques de documentación (docblocks)</title>
+
+        <para>
+            Como todos los demás componentes del servidor en Zend Framework, 
+            debe documentar los métodos de su clase usando PHP docblocks. 
+            Como mínimo, necesita proporcionar anotaciones para cada argumento 
+            así como para el valor de retorno. Como ejemplos:
+        </para>
+
+        <programlisting role="php"><![CDATA[
+// Función que agregar:
+
+/**
+ * @param  string $nombre
+ * @param  string $saludo
+ * @return string
+ */
+function holaMundo($ombre, $saludo = 'Hola')
+{
+    return $saludo . ', ' . $nombre;
+}
+]]>
+        </programlisting>
+
+        <programlisting role="php"><![CDATA[
+// Clase agregada
+
+class Mundo
+{
+    /**
+     * @param  string $nombre
+     * @param  string $saludo
+     * @return string
+     */
+    public function hola($nombre, $saludo = 'Hola')
+    {
+        return $saludo . ', ' . $nombre;
+    }
+}
+]]>
+        </programlisting>
+
+        <para>
+            Pueden usarse otras anotaciones, pero serán ignoradas.
+        </para>
+    </note>
+
+    <sect2 id="zend.amf.server.flex">
+        <title>Conectándose al Servidor desde Flex</title>
+
+        <para>
+            Conectarse a <code>Zend_Amf_Server</code> desde su proyecto Flex
+            es bastante simple; solo necesita apuntar el final del URI
+            a su script <code>Zend_Amf_Server</code>.
+        </para>
+
+        <para>
+            Por ejemplo, digamos que usted ya ha creado su servidor y lo ha 
+            puesto en el fichero <code>server.php</code> en el directorio raíz (root)
+            de su aplicación, por lo tanto la URI es <code>http://example.com/server.php</code>. 
+            En este caso, usted debería modificar su fichero services-config.xml
+            poniendo este valor como atributo al punto final del canal uri.
+       </para>
+        <para>
+             Si nunca ha creado un fichero services-config.xml puede hacerlo 
+             abriendo su proyecto en la ventana del navegador. 
+             Haga clic derecho sobre el nombre del proyecto y seleccione 'properties' (propiedades).
+             En el cuadro de diálogo 'properties' del proyecto ir al menú ‘Flex Build Path' (Crear ruta Flex),
+             luego en la pestaña ‘Library path’ (ruta de biblioteca) asegúrese 
+             de que el fichero 'rpc.swc' sea añadido a su ruta de proyectos
+             y pulse Ok (Aceptar) para cerrar la ventana.  
+        </para>
+        <para>          
+            También necesitará indicarle al compilador que debe usar 
+            services-config.xml para encontrar el punto final de RemoteObject. 
+            Para hacerlo, abra de nuevo el panel de propiedades de su proyecto 
+            haciendo clic en el botón derecho sobre el proyecto en la carpeta del
+            navegador y seleccione 'properties' (propiedades). 
+            Ahora seleccione ‘Flex Compiler' (Compilador Flex) y añada la cadena:
+            -services “services-config.xml". 
+            Presione 'Apply' (Aplicar) y luego en OK para volver a actualizar la opción. 
+            Lo que acaba de hacer es decirle al compilador Flex que busque en el fichero 
+            services-config.xml aquellas variables que se usarán en tiempo de
+            ejecución por la clase RemotingObject.           
+        </para>
+        <para>         
+            Ahora, para conectarnos a nuestros métodos remotos debemos indicarle a Flex
+            qué fichero de configuración de servicios utilizar. 
+            Por esta razón creamos un nuevo fichero 'services-config.xml' 
+            en la carpeta src del proyecto Flex. 
+            Con click derecho sobre el proyecto y seleccionando 'new'(nuevo) 
+            'File' (fichero), se abrirá una nueva ventana. 
+            Seleccione la carpeta del proyecto y luego nombre el archivo 
+            'services-config.xml' y presione 'finish' (finalizar).          
+        </para>
+        <para>
+            Flex ha creado y abierto el nuevo fichero services-config.xml. 
+            Utilice el siguiente texto de ejemplo para su fichero services-config.xml. 
+            Asegúrese de actualizar su punto final para que concuerde con el servidor. 
+            Asegúrese también de guardar el fichero.
+        </para>
+
+        <programlisting role="xml"><![CDATA[
+<?xml version="1.0" encoding="UTF-8"?>
+<services-config>
+    <services>
+        <service id="zend-service"
+            class="flex.messaging.services.RemotingService"
+            messageTypes="flex.messaging.messages.RemotingMessage">
+            <destination id="zend">
+                <channels>
+                    <channel ref="zend-endpoint"/>
+                </channels>
+                <properties>
+                    <source>*</source>
+                </properties>
+            </destination>
+        </service>
+    </services>
+    <channels>
+        <channel-definition id="zend-endpoint"
+            class="mx.messaging.channels.AMFChannel">
+            <endpoint uri="http://example.com/server.php"
+                class="flex.messaging.endpoints.AMFEndpoint"/>
+        </channel-definition>
+    </channels>
+</services-config>
+]]>
+        </programlisting>
+
+        <para>
+            Hay dos puntos clave en el ejemplo. 
+            En primer lugar, pero último en el listado, creamos un canal AMF,
+            y especificamos el punto final como la URL a nuestro <code>Zend_Amf_Server</code>:
+        </para>
+
+        <programlisting role="xml"><![CDATA[
+<channel-definition id="zend-endpoint"
+    <endpoint uri="http://example.com/server.php"
+        class="flex.messaging.endpoints.AMFEndpoint"/>
+</channel-definition>
+]]>
+        </programlisting>
+
+        <para>
+            Advierta que a este canal le hemos dado un identificador, "zend-endpoint".
+            El ejemplo crea un servicio cuyo destino hace referencia a este canal, 
+            asignándole también un ID, en este caso es "zend".
+        </para>
+
+        <para>
+            Dentro de nuestros ficheros Flex MXML, necesitamos vincular un RemoteObject al servicio. 
+            En MXML, esto podría hacerse así:
+        </para>
+
+        <programlisting role="xml"><![CDATA[
+<mx:RemoteObject id="myservice"
+    fault="faultHandler(event)"
+    showBusyCursor="true"
+    source="RoundTrip"
+    destination="zend">
+]]>
+        </programlisting>
+
+        <para>
+            Aquí, hemos definido un nuevo objeto remoto identificado por "myservice" 
+            vinculado destino de servicio "zend" que hemos definido en el fichero
+            <code>services-config.xml</code>. Entonces invocamos sus métodos en 
+            nuestro ActionScript simplemente llamando a "myservice.&lt;method&gt;".
+            (En este caso, el código original "RoundTrip" es el nombre de nuestra
+            aplicación Flex). Un ejemplo:
+        </para>
+
+        <programlisting role="ActionScript"><![CDATA[
+myservice.hello("Wade");
+]]>
+        </programlisting>
+
+        <para>
+            Cuando se usan nombres-de-espacio, puede usarse
+            "myservice.&lt;namespace&gt;.&lt;method&gt;":
+        </para>
+
+        <programlisting role="ActionScript"><![CDATA[
+myservice.world.hello("Wade");
+]]>
+        </programlisting>
+
+        <para>
+            Para más información sobre como invocar a Flex RemoteObject visite el
+            sitio de ayuda de Adobe Flex 3 en:<ulink
+                url="http://livedocs.adobe.com/flex/3/html/help.html?content=data_access_4.html"></ulink>.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.amf.server.errors">
+        <title>Manejo de errores</title>
+
+        <para>
+            Por defecto, todas las excepciones producidas en sus 
+            clases o funciones adjuntas serán capturados y devueltas como 
+            mensajes de error de AMF (AMF ErrorMessages). 
+            Sin embargo, el contenido de estos objetos de mensajes de error
+            variará dependiendo de si el servidor está o no en modo "producción"
+            (el estado por defecto).
+        </para>
+
+        <para>
+            Cuando se está en modo de producción, únicamente el código de excepción será devuelto. 
+            Si desactiva el modo de producción, algo que debe hacerse sólo
+            para probar  -- serán devueltos más detalles de la excepción: 
+            el mensaje de excepción (error), línea y backtrace serán adjuntados.
+        </para>
+
+        <para>
+            Para desactivar el modo de producción, haga lo siguiente:
+        </para>
+
+        <programlisting role="php"><![CDATA[
+$servidor->setProduction(false);
+]]>
+        </programlisting>
+
+        <para>
+            Para habilitarlo nuevamente, pase el valor true en su lugar.
+        </para>
+
+        <programlisting role="php"><![CDATA[
+$servidor->setProduction(true);
+]]>
+        </programlisting>
+
+        <note>
+            <title>¡Deshabilite el modo de producción racionalmente!</title>
+
+            <para>
+                Sugerimos deshabilitar el modo de producción solo cuando se está
+                en modo de desarrollo.
+                Los mensajes de excepción y los backtraces puede contener información 
+                sensible del sistema, y no desea que se pueda acceder a ellas 
+                desde el exterior. 
+                Aunque AMF es un formato binario, ahora al ser abierta la especificación,  
+                cualquiera puede potencialmente deserializar los datos.
+            </para>
+        </note>
+
+        <para>
+            Un área en la que se debe tener especialmente mucho cuidado son los 
+            errores propios de PHP.
+            Cuando la directiva INI <code>display_errors</code> está habilitada,
+            los errores de PHP de cualquier nivel del reporte actual serán
+            pasados directamente a la salida, y potencialmente se podrían hacer 
+            estragos con las respuestas de AMF.
+            Para prevenir estos problemas, sugerimos deshabilitar la directiva 
+            <code>display_errors</code> cuando se está en modo de producción.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.amf.server.response">
+        <title>Respuestas de AMF</title>
+
+        <para>
+            En ocasiones es posible que quiera manipular ligeramente el objeto
+            respuesta, es bastante usual querer devolver algunas cebeceras 
+            de mensajes adicionales. Puede hacerlo mediante el método del servidor 
+            <code>handle()</code> que devuelve el objeto respuesta.
+        </para>
+
+        <example id="zend.amf.server.response.messageHeaderExample">
+            <title>Agregar cabeceras de mensaje a la respuesta de AMF</title>
+
+            <para>
+                En este ejemplo, añadiremos la cabecera de mensaje (MessageHeader) 
+                "foo" con el valor 'bar' a la respuesta antes de devolverla.            
+            </para>
+
+            <programlisting role="php"><![CDATA[
+$respuesta = $servidor->handle();
+$respuesta->addAmfHeader(new Zend_Amf_Value_MessageHeader('foo', true, 'bar'))
+echo $respuesta;
+]]>
+            </programlisting>
+        </example>
+    </sect2>
+
+    <sect2 id="zend.amf.server.typedobjects">
+        <title>Objetos tipados</title>
+
+        <para>
+            Similarmente a SOAP, AMF permite pasar objetos entre cliente y servidor. 
+            Esto le da una gran flexibilidad y coherencia a ambos entornos.
+        </para>
+
+        <para>
+            <code>Zend_Amf</code> ofrece tres métodos para mapear ActionScript 
+             y objetos PHP.
+        </para>
+
+        <itemizedlist>
+            <listitem>
+                <para>
+                    Primero, usted puede crear uniones explícitas a nivel del servidor, 
+                    utilizando el método <code>setClassMap()</code>.
+                    El primer argumento es el nombre de la clase de ActionScript,  
+                    el segundo es el nombre de la clase PHP que lo mapea:
+                </para>
+
+                <programlisting role="php"><![CDATA[
+// Mapea la clase ActionScript 'ContactVO' a la clase PHP 'Contact':
+$servidor->setClassMap('ContactVO', 'Contact');
+]]>
+                </programlisting>
+            </listitem>
+
+            <listitem>
+                <para>
+                    Segundo, en su clase PHP puede ajustar la propiedad como pública
+                    mediante <code>$_explicitType</code>, con el valor 
+                    representativo de la clase ActionScript que mapear:
+                </para>
+
+                <programlisting role="php"><![CDATA[
+class Contact
+{
+    public $_explicitType = 'ContactVO';
+}
+]]>
+                </programlisting>
+            </listitem>
+
+            <listitem>
+                <para>
+                    Tercero, en un sentido similar, puede definir como público el método                
+                    <code>getASClassName()</code> dentro de su clase.
+                    Este método debe devolver la clase ActionScript apropiada:
+                 </para>
+
+                <programlisting role="php"><![CDATA[
+class Contact
+{
+    public function getASClassName()
+    {
+        return 'ContactVO';
+    }
+}
+]]>
+                </programlisting>
+            </listitem>
+        </itemizedlist>
+
+        <para>
+            Aunque hemos creado ContactVO en el servidor, 
+            ahora tenemos que hacer su clase correspondiente en AS3  
+            para que el servidor pueda mapear el objeto.
+        </para>
+        <para>
+            Haga clic derecho sobre la carpeta src del proyecto Flex y seleccione New -> ActionScript File. 
+            Nombre el fichero como ContactVO y pulse 'finish' (finalizar) para verlo. 
+            Copie el siguiente código en el fichero para terminar de crear la clase.
+        </para>
+        <programlisting role="as"><![CDATA[
+package
+{
+    [Bindable]
+    [RemoteClass(alias="ContactVO")]
+    public class ContactVO
+    {
+        public var id:int;
+        public var firstname:String;
+        public var lastname:String;
+        public var email:String;
+        public var mobile:String;
+        public function ProductVO():void {
+        }
+    }
+}
+]]>
+            </programlisting>
+        <para>
+            La clase es sintácticamente equivalente a la de PHP del mismo nombre.
+            Los nombres de variables son exactamente los mismos y necesitan estar 
+            en el mismo contenedor para trabajar correctamente. Hay
+            dos meta tags AS3 únicos en esta clase. 
+            El primero es vinculable y dispara un evento cuando es actualizada.
+            El segundo es el tag RemoteClass y define que esta clase puede tener 
+            mapeado un objeto remoto con un nombre de alias, en este caso <code>ContactVO</code>
+            Es obligatorio que en esta etiqueta(tag), el valor que se estableció es la clase PHP 
+            sea estrictamente equivalente.               
+        </para>
+        <programlisting role="as"><![CDATA[
+[Bindable]
+private var myContact:ContactVO;
+
+private function getContactHandler(event:ResultEvent):void {
+    myContact = ContactVO(event.result);
+}
+]]>
+        </programlisting>
+        <para>
+            El siguiente resultado del evento debido a la llamada de servicio, 
+            se incorporó instantáneamente a ContactVO de Flex. 
+            Cualquier cosa que esté ligada a myContact será actualizada con los
+            datos retornados por ContactVO.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.amf.server.flash">
+        <title>Conectándose al servidor desde Flash</title>
+
+        <para>
+            La conexión a <code>Zend_Amf_Server</code> desde su proyecto Flash
+            es ligeramente distinta a la de Flex. Sin embargo una vez que la conexión 
+            con Flash funcione con <code>Zend_Amf_Server</code> lo hará igual 
+            modo que con Flex. El siguiente ejemplo también puede ser utilizado 
+            desde un fichero Flex AS3. Para nuestra conexión vamos a reutilizar 
+            la misma configuracion <code>Zend_Amf_Server</code> junto a la clase Mundo.
+        </para>
+        <para>
+            Abra Flash CS y cree un nuevo fichero Flash (ActionScript 3). 
+            Nombre al documento como ZendExample.fla y guárdelo en una carpeta 
+            que utilizará para este ejemplo. Cree una nuevo fichero AS3 en el mismo 
+            directorio y llámelo Main.as. Abra ambos ficheros con su editor.
+            Ahora vamos a conectar las dos ficheros a través de la clase documento.
+            Seleccione ZendExample y haga clic en el escenario. 
+            Desde el panel del escenario cambie la propiedad de la clase Document a Main.
+            Esto vincula al fichero Main.as con la interfaz de usuario en ZendExample.fla. 
+            Cuando ejecute el fichero ZendExample de Flash se ejecutará ahora
+            la clase Main.as. 
+            El paso siguiente será añadir ActionScript para hacer una lamada AMF.
+        </para>
+        <para>
+            Ahora vamos a hacer una clase Main(principal) para que podamos enviar 
+            los datos al servidor y mostrar el resultado. 
+            Copie el código siguiente en su fichero Main.as y luego vamos a recorrer 
+            el código para describir cuál es el papel de cada elemento.
+        </para>
+        <programlisting role="as"><![CDATA[
+package {
+  import flash.display.MovieClip;
+  import flash.events.*;
+  import flash.net.NetConnection;
+  import flash.net.Responder;
+
+  public class Main extends MovieClip {
+    private var gateway:String = "http://example.com/server.php";
+    private var connection:NetConnection;
+    private var responder:Responder;
+
+    public function Main() {
+      responder = new Responder(onResult, onFault);
+      connection = new NetConnection;
+      connection.connect(gateway);
+    }
+
+    public function onComplete( e:Event ):void{
+      var params = "Sent to Server";
+      connection.call("World.hello", responder, params);
+    }
+
+    private function onResult(result:Object):void {
+      // Display the returned data
+      trace(String(result));
+    }
+    private function onFault(fault:Object):void {
+      trace(String(fault.description));
+    }
+  }
+}
+]]>
+        </programlisting>
+
+
+        <para>
+            Primero tenemos que importar dos bibliotecas de ActionScript que realizan 
+            la mayor parte del trabajo. La primera es NetConnection que actúa como un 
+            tubo bidireccional entre el cliente y el servidor. 
+            La segunda es un objeto Responder que maneja los valores de retorno desde 
+            el servidor, y que están relacionados con el éxito o el fracaso de la llamada.
+       </para>
+        <programlisting role="as"><![CDATA[
+import flash.net.NetConnection;
+import flash.net.Responder;
+]]>
+        </programlisting>
+        <para>
+            En la clase necesitaremos tres variables para representar a NetConnection, 
+            Responder, y la URL del gateway a nuestra instalación <code>Zend_Amf_Server</code>.
+        </para>
+        <programlisting role="as"><![CDATA[
+private var gateway:String = "http://example.com/server.php";
+private var connection:NetConnection;
+private var responder:Responder;
+]]>
+        </programlisting>
+        <para>
+            En el constructor Main creamos un Responder(respondedor) y una nueva conexión al 
+            punto final de <code>Zend_Amf_Server</code>. El respondedor define dos 
+            diferentes métodos para manejar la respuesta desde el servidor. 
+            Por simplicidad los hemos llamado onResult y onFault.
+        </para>
+        <programlisting role="as"><![CDATA[
+responder = new Responder(onResult, onFault);
+connection = new NetConnection;
+connection.connect(gateway);
+]]>
+        </programlisting>
+        <para>
+            La función onComplete se ejecuta tan pronto como la construcción 
+            ha concluido, enviando los datos al servidor. 
+            Necesitamos añadir una línea más que hace una llamada a la función  
+            <code>Zend_Amf_Server</code> Mundo->hola.
+        </para>
+        <programlisting role="as"><![CDATA[
+connection.call("Mundo.hola", responder, params);
+]]>
+        </programlisting>
+        <para>
+            Cuando creamos la variable responder hemos definido las funciones onResult y onFault 
+            para manejar la respuesta proveniente del servidor. 
+            Hemos añadido la función OnResult para el resultado exitoso desde el servidor. 
+            Cada vez que se ejecuta apropiadamente el manejo de conexión con el 
+            servidor, el manejador de eventos llama esta función.  
+        </para>
+        <programlisting role="as"><![CDATA[
+private function onResult(result:Object):void {
+    // Muestra los datos devueltos
+    trace(String(result));
+}
+]]>
+        </programlisting>
+        <para>
+            La función onFault, se llama si hubo una respuesta nula desde el servidor. 
+            Esto ocurre cuando hay un error en el servidor, la URL al servidor es inválida, 
+            el servicio remoto o método no existe o cualquier otra cuestión 
+            relacionada con la conexión.
+        </para>
+        <programlisting role="as"><![CDATA[
+private function onFault(fault:Object):void {
+    trace(String(fault.description));
+}
+]]>
+        </programlisting>
+        <para>
+            La inclusión de ActionScript para realizar la conexión remota ha finalizado.
+            Al ejecutar el fichero ZendExample, se establece una conexión con Zend_Amf. 
+            En resumen, se han añadido las variables requeridas para abrir una conexión 
+            con el servidor remoto, se han definido qué métodos se deben utilizar cuando su aplicación 
+            recibe una respuesta desde el servidor, y finalmente se han mostrado los datos de salida 
+            devueltos a través de trace().
+        </para>
+
+    </sect2>
+
+</sect1>
+<!--
+vim:se ts=4 sw=4 et:
+-->

+ 206 - 206
documentation/manual/es/module_specs/Zend_Cache-Introduction.xml

@@ -1,206 +1,206 @@
-<sect1 id="zend.cache.introduction">
-    <title>Introducción</title>
-    <para>
-        <code>Zend_Cache</code>
-        provee una forma genérica para cualquier caché de datos.
-    </para>
-    <para>
-        El almacenamiento en caché en Zend Framework se opera por
-        interfaces, mientras que los registros de caché son almacenados
-        a través de adapatadores del backend (
-        <code>Archivo</code>
-        ,
-        <code>Sqlite</code>
-        ,
-        <code>Memcache</code>
-        ...) mediante un sistema flexible de documentos de identidad y
-        etiquetas. Utilizando éstas, es fácil en el futuro eliminar
-        determinados tipos de registro.(Ejemplo: "eliminar todos los
-        registros caché de determinada etiqueta").
-    </para>
-    <para>
-        El módulo principal (
-        <code>Zend_Cache_Core</code>
-        ) es genérico, flexible y configurable. Aun para sus necesidades
-        específicas existen frontends de caché que extienden
-        <code>Zend_Cache_Core</code>
-        a conveniencia:
-        <code>Output</code>
-        ,
-        <code>File</code>
-        ,
-        <code>Function</code>
-        y
-        <code>Class</code>
-        .
-
-    </para>
-    <example id="zend.cache.introduction.example-1">
-        <title>
-            Obtener un frontend con
-            <code>Zend_Cache::factory()</code>
-        </title>
-        <para>
-            <code>Zend_Cache::factory()</code>
-            ejemplifica objetos correctos y los une. En este primer
-            ejemplo, usaremos el frontend
-            <code>Core</code>
-            junto con el backend
-            <code>File</code>
-            .
-        </para>
-
-        <programlisting role="php"><![CDATA[
-$frontendOptions = array(
-   'lifetime' => 7200, // tiempo de vida de caché de 2 horas
-   'automatic_serialization' => true
-);
-
-$backendOptions = array(
-    'cache_dir' => './tmp/' // Carpeta donde alojar los archivos de caché
-);
-
-// getting a Zend_Cache_Core object
-$cache = Zend_Cache::factory('Core',
-                             'File',
-                             $frontendOptions,
-                             $backendOptions);
-]]>
-        </programlisting>
-    </example>
-
-    <note>
-        <title>
-            Frontends y Backends Compuestos de Múltiples Palabras
-        </title>
-        <para>
-            Algunos frontends y backends se nombran usando varias
-            palabras, tal como 'ZenPlatform'. Al fabricarlas las
-            especificamos, las separamos usando un separador de
-            palabras, como un espacio (' '), guión ('-'), o punto ('.').
-        </para>
-    </note>
-
-    <example id="zend.cache.introduction.example-2">
-        <title>Almacenando en caché un resultado de consulta a una base de datos</title>
-
-        <para>
-            Ahora que tenemos un frontend, podemos almacenar en caché
-            cualquier tipo de dato (hemos activado la serialización). Por
-            ejemplo, podemos almacenar en caché un resultado de una
-            consulta de base de datos muy costosa. Después de ser
-            almacenada en caché, no es necesario ni conectar la base
-            de datos; los registros se obtienen del caché de forma no
-            serializada.
-        </para>
-
-        <programlisting role="php"><![CDATA[
-// $cache initializada en el ejemplo anterior
-
-// Verificar si la cahce existe:
-if(!$result = $cache->load('myresult')) {
-
-    // no existe cache; conectar a la base de datos
-
-    $db = Zend_Db::factory( [...] );
-
-    $result = $db->fetchAll('SELECT * FROM huge_table');
-
-    $cache->save($result, 'myresult');
-
-} else {
-
-    // cache existosa!, darlo a conocer
-    echo "Éste es de caché!\n\n";
-
-}
-
-print_r($result);
-]]>
-        </programlisting>
-    </example>
-
-    <example id="zend.cache.introduction.example-3">
-        <title>
-            El almacenamiento en caché de salida con la interfaz de
-            salida
-            <code>Zend_Cache</code>
-        </title>
-        <para>
-            ‘Resaltamos’ las secciones en las que deseamos almacenar en
-            caché la salida, mediante la adición de algunas condiciones lógicas,
-            encapsulamos la sección dentro de los métodos
-            <code>start()</code>
-            y
-            <code>end()</code>
-            (esto se parece al primer ejemplo y es la estrategia
-            fundamental para el almacenamiento en caché).
-        </para>
-        <para>
-            Dentro, los datos de salida, como siempre – todas las salidas
-            serán almacenadas en caché cuando se ordene la ejecución del
-            método
-            <code>end()</code>
-            . En la siguiente ejecución, toda la sección se saltará a
-            favor de la búsqueda de datos del caché (tanto tiempo como
-            el registro del caché sea válido).
-        </para>
-        <programlisting role="php"><![CDATA[
-$frontendOptions = array(
-   'lifetime' => 30,                   // tiempo de vida de caché de 30 segundos
-   'automatic_serialization' => false  // éste es el valor por defecto
-);
-
-$backendOptions = array('cache_dir' => './tmp/');
-
-$cache = Zend_Cache::factory('Output',
-                             'File',
-                             $frontendOptions,
-                             $backendOptions);
-
-// Pasamos un identificador único al método start() 
-if(!$cache->start('mypage')) {
-    // salida como de costumbre:
-
-    echo 'Hola mundo! ';
-    echo 'Esto está en caché ('.time().') ';
-
-    $cache->end(); // la salida es guardada y enviada al navegador
-}
-
-echo 'Esto no estará en caché nunca ('.time().').';
-]]>
-        </programlisting>
-        <para>
-            Note que delineamos el resultado de
-            <code>time()</code>
-            dos veces; esto es algo dinámico para los propósitos de la
-            demostración. Trate de ejecutarlo y entonces regenérelo
-            muchas veces; notará que el primer número no cambia mientras
-            que el segundo cambia a medida que pasa el tiempo. Esto
-            es porque el primer número esta delineado en la sección
-            caché y esta guardado en medio de otras salidas. Después de
-            medio minuto (habremos establecido el tiempo de vida de 30
-            segundos) los números deben acoplarse nuevamente porque el
-            registro caché ha expirado -- sólo para ser almacenado en
-            caché nuevamente. Deberá probarlo en su visualizador o
-            consola.
-        </para>
-    </example>
-    <note>
-        <para>
-            Cuando usamos Zend_Cache, ponemos atención a la importación
-            del identificador caché (pasado a 
-            <code>save()</code>
-            y
-            <code>start()</code>
-            ). Éste deberá ser único para cada recurso que se almacene
-            en caché, de otra manera los registros almacenados en caché
-            que no se vinculan podrían borrarse unos a otros, o peor
-            aún, mostrarse uno en lugar del otro.
-        </para>
-    </note>
-</sect1>
-<!--
-    vim:se ts=4 sw=4 et:
--->
+<sect1 id="zend.cache.introduction">
+    <title>Introducción</title>
+    <para>
+        <code>Zend_Cache</code>
+        provee una forma genérica para cualquier caché de datos.
+    </para>
+    <para>
+        El almacenamiento en caché en Zend Framework se opera por
+        interfaces, mientras que los registros de caché son almacenados
+        a través de adapatadores del backend (
+        <code>Archivo</code>
+        ,
+        <code>Sqlite</code>
+        ,
+        <code>Memcache</code>
+        ...) mediante un sistema flexible de documentos de identidad y
+        etiquetas. Utilizando éstas, es fácil en el futuro eliminar
+        determinados tipos de registro.(Ejemplo: "eliminar todos los
+        registros caché de determinada etiqueta").
+    </para>
+    <para>
+        El módulo principal (
+        <code>Zend_Cache_Core</code>
+        ) es genérico, flexible y configurable. Aun para sus necesidades
+        específicas existen frontends de caché que extienden
+        <code>Zend_Cache_Core</code>
+        a conveniencia:
+        <code>Output</code>
+        ,
+        <code>File</code>
+        ,
+        <code>Function</code>
+        y
+        <code>Class</code>
+        .
+
+    </para>
+    <example id="zend.cache.introduction.example-1">
+        <title>
+            Obtener un frontend con
+            <code>Zend_Cache::factory()</code>
+        </title>
+        <para>
+            <code>Zend_Cache::factory()</code>
+            ejemplifica objetos correctos y los une. En este primer
+            ejemplo, usaremos el frontend
+            <code>Core</code>
+            junto con el backend
+            <code>File</code>
+            .
+        </para>
+
+        <programlisting role="php"><![CDATA[
+$frontendOptions = array(
+   'lifetime' => 7200, // tiempo de vida de caché de 2 horas
+   'automatic_serialization' => true
+);
+
+$backendOptions = array(
+    'cache_dir' => './tmp/' // Carpeta donde alojar los archivos de caché
+);
+
+// getting a Zend_Cache_Core object
+$cache = Zend_Cache::factory('Core',
+                             'File',
+                             $frontendOptions,
+                             $backendOptions);
+]]>
+        </programlisting>
+    </example>
+
+    <note>
+        <title>
+            Frontends y Backends Compuestos de Múltiples Palabras
+        </title>
+        <para>
+            Algunos frontends y backends se nombran usando varias
+            palabras, tal como 'ZenPlatform'. Al fabricarlas las
+            especificamos, las separamos usando un separador de
+            palabras, como un espacio (' '), guión ('-'), o punto ('.').
+        </para>
+    </note>
+
+    <example id="zend.cache.introduction.example-2">
+        <title>Almacenando en caché un resultado de consulta a una base de datos</title>
+
+        <para>
+            Ahora que tenemos un frontend, podemos almacenar en caché
+            cualquier tipo de dato (hemos activado la serialización). Por
+            ejemplo, podemos almacenar en caché un resultado de una
+            consulta de base de datos muy costosa. Después de ser
+            almacenada en caché, no es necesario ni conectar la base
+            de datos; los registros se obtienen del caché de forma no
+            serializada.
+        </para>
+
+        <programlisting role="php"><![CDATA[
+// $cache initializada en el ejemplo anterior
+
+// Verificar si la cahce existe:
+if(!$result = $cache->load('myresult')) {
+
+    // no existe cache; conectar a la base de datos
+
+    $db = Zend_Db::factory( [...] );
+
+    $result = $db->fetchAll('SELECT * FROM huge_table');
+
+    $cache->save($result, 'myresult');
+
+} else {
+
+    // cache existosa!, darlo a conocer
+    echo "Éste es de caché!\n\n";
+
+}
+
+print_r($result);
+]]>
+        </programlisting>
+    </example>
+
+    <example id="zend.cache.introduction.example-3">
+        <title>
+            El almacenamiento en caché de salida con la interfaz de
+            salida
+            <code>Zend_Cache</code>
+        </title>
+        <para>
+            ‘Resaltamos’ las secciones en las que deseamos almacenar en
+            caché la salida, mediante la adición de algunas condiciones lógicas,
+            encapsulamos la sección dentro de los métodos
+            <code>start()</code>
+            y
+            <code>end()</code>
+            (esto se parece al primer ejemplo y es la estrategia
+            fundamental para el almacenamiento en caché).
+        </para>
+        <para>
+            Dentro, los datos de salida, como siempre – todas las salidas
+            serán almacenadas en caché cuando se ordene la ejecución del
+            método
+            <code>end()</code>
+            . En la siguiente ejecución, toda la sección se saltará a
+            favor de la búsqueda de datos del caché (tanto tiempo como
+            el registro del caché sea válido).
+        </para>
+        <programlisting role="php"><![CDATA[
+$frontendOptions = array(
+   'lifetime' => 30,                   // tiempo de vida de caché de 30 segundos
+   'automatic_serialization' => false  // éste es el valor por defecto
+);
+
+$backendOptions = array('cache_dir' => './tmp/');
+
+$cache = Zend_Cache::factory('Output',
+                             'File',
+                             $frontendOptions,
+                             $backendOptions);
+
+// Pasamos un identificador único al método start() 
+if(!$cache->start('mypage')) {
+    // salida como de costumbre:
+
+    echo 'Hola mundo! ';
+    echo 'Esto está en caché ('.time().') ';
+
+    $cache->end(); // la salida es guardada y enviada al navegador
+}
+
+echo 'Esto no estará en caché nunca ('.time().').';
+]]>
+        </programlisting>
+        <para>
+            Note que delineamos el resultado de
+            <code>time()</code>
+            dos veces; esto es algo dinámico para los propósitos de la
+            demostración. Trate de ejecutarlo y entonces regenérelo
+            muchas veces; notará que el primer número no cambia mientras
+            que el segundo cambia a medida que pasa el tiempo. Esto
+            es porque el primer número esta delineado en la sección
+            caché y esta guardado en medio de otras salidas. Después de
+            medio minuto (habremos establecido el tiempo de vida de 30
+            segundos) los números deben acoplarse nuevamente porque el
+            registro caché ha expirado -- sólo para ser almacenado en
+            caché nuevamente. Deberá probarlo en su visualizador o
+            consola.
+        </para>
+    </example>
+    <note>
+        <para>
+            Cuando usamos Zend_Cache, ponemos atención a la importación
+            del identificador caché (pasado a 
+            <code>save()</code>
+            y
+            <code>start()</code>
+            ). Éste deberá ser único para cada recurso que se almacene
+            en caché, de otra manera los registros almacenados en caché
+            que no se vinculan podrían borrarse unos a otros, o peor
+            aún, mostrarse uno en lugar del otro.
+        </para>
+    </note>
+</sect1>
+<!--
+    vim:se ts=4 sw=4 et:
+-->

+ 28 - 28
documentation/manual/es/module_specs/Zend_Captcha.xml

@@ -1,28 +1,28 @@
-<sect1 id="zend.captcha.introduction">
-    <title>Introducción</title>
-
-    <para>
-        <ulink url="http://en.wikipedia.org/wiki/Captcha">
-            CAPTCHA
-        </ulink>
-        es el acrónimo de "Completely Automated Public Turing test to
-        tell Computers and Humans Apart" (Prueba de Turing pública y
-        automática para diferenciar a máquinas y humanos). Es usado como un 
-        desafío-respuesta para asegurar que la información individual suministrada
-    viene de un humano y no de un proceso automatizado. Típicamente,
-        un captcha es usado con envío de formularios donde no es necesario que el 
-    usuario se haya autenticado, pero se desea prevenir el envío de spam.
-    </para>
-
-    <para>
-        Los Captchas pueden presentarse en multitud de formas, incluyendo 
-        preguntas lógicas, caracteres trastocados o presentar imágenes y preguntar
-        cómo se relacionan. Zend_Captcha intenta proveer una amalgama de backends
-        que pueden ser utilizados por separado o en conjunción con
-        <code>Zend_Form</code>
-        .
-    </para>
-</sect1>
-<!--
-    vim:se ts=4 sw=4 et:
--->
+<sect1 id="zend.captcha.introduction">
+    <title>Introducción</title>
+
+    <para>
+        <ulink url="http://en.wikipedia.org/wiki/Captcha">
+            CAPTCHA
+        </ulink>
+        es el acrónimo de "Completely Automated Public Turing test to
+        tell Computers and Humans Apart" (Prueba de Turing pública y
+        automática para diferenciar a máquinas y humanos). Es usado como un 
+        desafío-respuesta para asegurar que la información individual suministrada
+    viene de un humano y no de un proceso automatizado. Típicamente,
+        un captcha es usado con envío de formularios donde no es necesario que el 
+    usuario se haya autenticado, pero se desea prevenir el envío de spam.
+    </para>
+
+    <para>
+        Los Captchas pueden presentarse en multitud de formas, incluyendo 
+        preguntas lógicas, caracteres trastocados o presentar imágenes y preguntar
+        cómo se relacionan. Zend_Captcha intenta proveer una amalgama de backends
+        que pueden ser utilizados por separado o en conjunción con
+        <code>Zend_Form</code>
+        .
+    </para>
+</sect1>
+<!--
+    vim:se ts=4 sw=4 et:
+-->

+ 40 - 40
documentation/manual/es/module_specs/Zend_Config-Introduction.xml

@@ -1,45 +1,45 @@
-<sect1 id="zend.config.introduction">
-    <title>Introducción</title>
-    <para>
-
-        <code>Zend_Config</code>
-        está diseñado para simplificar el acceso y el uso de datos de
-        configuración dentro de aplicaciones. Provee una interfaz de
-        usuario basada en propiedades de objetos anidadas para acceder a
-        datos de configuración dentro del código de la aplicación. Los
-        datos de configuración pueden venir de multitud de medios que
-        soporten almacenamiento de datos de forma jerárquica.
-        Actualmente
-        <code>Zend_Config</code>
-        provee adaptadores para datos de configuración que están
-        almacenados en archivos de texto con
-        <link linkend="zend.config.adapters.ini">
-            <code>Zend_Config_Ini</code>
-        </link>
-        y
-        <link linkend="zend.config.adapters.xml">
-            <code>Zend_Config_Xml</code>
-        </link>
-        .
-    </para>
-    <example id="zend.config.introduction.example.using">
-        <title>Usando Zend_Config Per Se</title>
-        <para>
+<sect1 id="zend.config.introduction">
+    <title>Introducción</title>
+    <para>
+
+        <code>Zend_Config</code>
+        está diseñado para simplificar el acceso y el uso de datos de
+        configuración dentro de aplicaciones. Provee una interfaz de
+        usuario basada en propiedades de objetos anidadas para acceder a
+        datos de configuración dentro del código de la aplicación. Los
+        datos de configuración pueden venir de multitud de medios que
+        soporten almacenamiento de datos de forma jerárquica.
+        Actualmente
+        <code>Zend_Config</code>
+        provee adaptadores para datos de configuración que están
+        almacenados en archivos de texto con
+        <link linkend="zend.config.adapters.ini">
+            <code>Zend_Config_Ini</code>
+        </link>
+        y
+        <link linkend="zend.config.adapters.xml">
+            <code>Zend_Config_Xml</code>
+        </link>
+        .
+    </para>
+    <example id="zend.config.introduction.example.using">
+        <title>Usando Zend_Config Per Se</title>
+        <para>
             Normalmente, se espera que los usuarios usen
             una de las clases adaptadoras como
-            <link linkend="zend.config.adapters.ini">
-                <code>Zend_Config_Ini</code>
-            </link>
-            o
-            <link linkend="zend.config.adapters.xml">
-                <code>Zend_Config_Xml</code>
-            </link>
+            <link linkend="zend.config.adapters.ini">
+                <code>Zend_Config_Ini</code>
+            </link>
+            o
+            <link linkend="zend.config.adapters.xml">
+                <code>Zend_Config_Xml</code>
+            </link>
             , pero si los datos de configuración están disponibles
             en un array PHP, se puede simplemente pasar los datos al
             constructor
-            <code>Zend_Config</code>
-            para utilizar una interfaz simple orientada a objetos:
-        </para>
+            <code>Zend_Config</code>
+            para utilizar una interfaz simple orientada a objetos:
+        </para>
         <programlisting role="php"><![CDATA[
 // Dado un array de datos de configuración
 $configArray = array(
@@ -122,6 +122,6 @@ echo $config->webhost;
         </programlisting>
     </example>
 </sect1>
-<!--
-    vim:se ts=4 sw=4 et:
--->
+<!--
+    vim:se ts=4 sw=4 et:
+-->

+ 85 - 85
documentation/manual/es/module_specs/Zend_Config-TheoryOfOperation.xml

@@ -1,85 +1,85 @@
-
-
-<sect1 id="zend.config.theory_of_operation">
-    <title>Aspectos Teóricos</title>
-    <para>
-        Los datos de configuración se hacen accesibles al constructor <code>Zend_Config</code>
-        a través de un array asociativo, que puede ser multidimensional, para permitir
-        organizar los datos desde lo general a lo específico. Las clases de adaptador concretas 
-        permiten construir una tabla asociativa para el constructor de <code>Zend_Config</code> 
-        a partir de un sistema de almacenamiento de datos de configuración. Algunos scripts 
-        de usuario pueden proveer esos arrays directamente al constructor Zend_Config, 
-        sin usar una clase adaptador, lo cual puede ser apropiado en ciertas ocasiones.
-    </para>
-    <para>
-        Cada valor del array de datos de configuración se convierte en una propiedad del objeto <code>Zend_Config</code>.
-        La clave es usada como el nombre de la propiedad. Si un valor es un array por sí solo, entonces la propiedad
-        de objeto resultante es creada como un nuevo objeto
-        <code>Zend_Config</code>, cargado con los datos del array. Esto ocurre recursivamente, de forma
-        que una jerarquía de datos de configuración puede ser creada con cualquier número de niveles.
-    </para>
-    <para>
-        <code>Zend_Config</code> implementa las interfaces <code>Countable</code> e <code>Iterator</code>
-        para facilitar el aceso sencillo a los datos de configuración.
-        Así, uno puede usar la función <ulink url="http://php.net/count"><code>count()</code></ulink>
-        y constructores PHP como
-        <ulink url="http://php.net/foreach"><code>foreach</code></ulink> sobre objetos
-        <code>Zend_Config</code>.
-    </para>
-    <para>
-        Por defecto, los datos de configuración permitidos a través de <code>Zend_Config</code>
-        son de sólo lectura, y una asignación (e.g.,
-        <code>$config-&gt;database-&gt;host = 'example.com'</code>)
-        provoca que se lance una excepción. Este comportamiento por defecto puede ser sobrescrito a través
-        del constructor, sin embargo, para permitir la modificación de valores de datos. Además, cuando
-        las modificaciones están permitidas, <code>Zend_Config</code> soporta el borrado de elementos (unset) (i.e. <code>unset($config-&gt;database-&gt;host);</code>). El método
-        <code>readOnly()</code> puede ser usado para determinar si las modificaciones a un objeto <code>Zend_Config</code>
-        están permitidas y el método <code>setReadOnly()</code> puede ser usado para evitar cualquier modificación
-        posterior a un objeto <code>Zend_Config</code> que fue creado con permiso de modificaciones.
-        <note>
-            <para>
-                Es importante no confundir tales modificaciones en memoria con guardar los datos de configuración a un
-                medio de almacenamiento específico. Las herramientas para crear y modificar datos de configuración para 
-                distintos medios de almacenamiento están fuera del alcance de <code>Zend_Config</code>.
-                Existen soluciones third-party de código abierto con el propósito de crear y modificar
-                datos de configuración de distintos medios de almacenamiento.
-            </para>
-        </note>
-    </para>
-    <para>
-        Las clases del adaptador heredan de la clase <code>Zend_Config</code> debido a que utilizan su funcionalidad.
-    </para>
-    <para>
-        La familia de clases <code>Zend_Config</code> permite organizar en secciones 
-        los datos de configuración. Los objetos de adaptador <code>Zend_Config</code>
-        pueden ser cargados con una sola sección especificada, múltiples secciones especificadas,
-        o todas las secciones (si no se especifica ninguna).
-    </para>
-    <para>
-        Las clases del adaptador <code>Zend_Config</code> soportan un modelo de herencia única
-        que permite que los datos de configuración hereden de una sección de datos de configuración a otra. 
-        Esto es provisto con el fin de reducir o eliminar la necesidad de duplicar datos de configuración por
-        distintos motivos. Una sección heredada puede también sobrescribir los valores que hereda de su sección
-        padre. Al igual que la herencia de clases PHP, una sección puede heredar de una sección padre,
-        la cual puede heredar de una sección abuela, etc..., pero la herencia múltiple
-        (i.e., la sección C heredando directamente de las secciones padre A y B) no está permitida.
-    </para>
-    <para>
-        Si tiene dos objetos <code>Zend_Config</code>, puede combinarlos en un único
-        objeto usando la función <code>merge()</code>. Por ejemplo, dados <code>$config</code> y
-        <code>$localConfig</code>, puede fusionar datos de <code>$localConfig</code> a <code>$config</code> usando
-        <code>$config-&gt;merge($localConfig);</code>. Los ítemes en <code>$localConfig</code> sobrescribirán
-        cualquier item con el mismo nombre en <code>$config</code>.
-        <note>
-            <para>
-                El objeto <code>Zend_Config</code> que está ejecutando el merge debe haber sido construido
-                para permitir modificaciones, pasando <code>true</code> como el segundo parámetro del constructor.
-                El método <code>setReadOnly()</code> puede entonces ser usado para evitar cualquier
-                modificación posterior después de que el merge se haya completado.
-            </para>
-        </note>
-    </para>
-</sect1>
-<!--
-vim:se ts=4 sw=4 et:
--->
+
+
+<sect1 id="zend.config.theory_of_operation">
+    <title>Aspectos Teóricos</title>
+    <para>
+        Los datos de configuración se hacen accesibles al constructor <code>Zend_Config</code>
+        a través de un array asociativo, que puede ser multidimensional, para permitir
+        organizar los datos desde lo general a lo específico. Las clases de adaptador concretas 
+        permiten construir una tabla asociativa para el constructor de <code>Zend_Config</code> 
+        a partir de un sistema de almacenamiento de datos de configuración. Algunos scripts 
+        de usuario pueden proveer esos arrays directamente al constructor Zend_Config, 
+        sin usar una clase adaptador, lo cual puede ser apropiado en ciertas ocasiones.
+    </para>
+    <para>
+        Cada valor del array de datos de configuración se convierte en una propiedad del objeto <code>Zend_Config</code>.
+        La clave es usada como el nombre de la propiedad. Si un valor es un array por sí solo, entonces la propiedad
+        de objeto resultante es creada como un nuevo objeto
+        <code>Zend_Config</code>, cargado con los datos del array. Esto ocurre recursivamente, de forma
+        que una jerarquía de datos de configuración puede ser creada con cualquier número de niveles.
+    </para>
+    <para>
+        <code>Zend_Config</code> implementa las interfaces <code>Countable</code> e <code>Iterator</code>
+        para facilitar el aceso sencillo a los datos de configuración.
+        Así, uno puede usar la función <ulink url="http://php.net/count"><code>count()</code></ulink>
+        y constructores PHP como
+        <ulink url="http://php.net/foreach"><code>foreach</code></ulink> sobre objetos
+        <code>Zend_Config</code>.
+    </para>
+    <para>
+        Por defecto, los datos de configuración permitidos a través de <code>Zend_Config</code>
+        son de sólo lectura, y una asignación (e.g.,
+        <code>$config-&gt;database-&gt;host = 'example.com'</code>)
+        provoca que se lance una excepción. Este comportamiento por defecto puede ser sobrescrito a través
+        del constructor, sin embargo, para permitir la modificación de valores de datos. Además, cuando
+        las modificaciones están permitidas, <code>Zend_Config</code> soporta el borrado de elementos (unset) (i.e. <code>unset($config-&gt;database-&gt;host);</code>). El método
+        <code>readOnly()</code> puede ser usado para determinar si las modificaciones a un objeto <code>Zend_Config</code>
+        están permitidas y el método <code>setReadOnly()</code> puede ser usado para evitar cualquier modificación
+        posterior a un objeto <code>Zend_Config</code> que fue creado con permiso de modificaciones.
+        <note>
+            <para>
+                Es importante no confundir tales modificaciones en memoria con guardar los datos de configuración a un
+                medio de almacenamiento específico. Las herramientas para crear y modificar datos de configuración para 
+                distintos medios de almacenamiento están fuera del alcance de <code>Zend_Config</code>.
+                Existen soluciones third-party de código abierto con el propósito de crear y modificar
+                datos de configuración de distintos medios de almacenamiento.
+            </para>
+        </note>
+    </para>
+    <para>
+        Las clases del adaptador heredan de la clase <code>Zend_Config</code> debido a que utilizan su funcionalidad.
+    </para>
+    <para>
+        La familia de clases <code>Zend_Config</code> permite organizar en secciones 
+        los datos de configuración. Los objetos de adaptador <code>Zend_Config</code>
+        pueden ser cargados con una sola sección especificada, múltiples secciones especificadas,
+        o todas las secciones (si no se especifica ninguna).
+    </para>
+    <para>
+        Las clases del adaptador <code>Zend_Config</code> soportan un modelo de herencia única
+        que permite que los datos de configuración hereden de una sección de datos de configuración a otra. 
+        Esto es provisto con el fin de reducir o eliminar la necesidad de duplicar datos de configuración por
+        distintos motivos. Una sección heredada puede también sobrescribir los valores que hereda de su sección
+        padre. Al igual que la herencia de clases PHP, una sección puede heredar de una sección padre,
+        la cual puede heredar de una sección abuela, etc..., pero la herencia múltiple
+        (i.e., la sección C heredando directamente de las secciones padre A y B) no está permitida.
+    </para>
+    <para>
+        Si tiene dos objetos <code>Zend_Config</code>, puede combinarlos en un único
+        objeto usando la función <code>merge()</code>. Por ejemplo, dados <code>$config</code> y
+        <code>$localConfig</code>, puede fusionar datos de <code>$localConfig</code> a <code>$config</code> usando
+        <code>$config-&gt;merge($localConfig);</code>. Los ítemes en <code>$localConfig</code> sobrescribirán
+        cualquier item con el mismo nombre en <code>$config</code>.
+        <note>
+            <para>
+                El objeto <code>Zend_Config</code> que está ejecutando el merge debe haber sido construido
+                para permitir modificaciones, pasando <code>true</code> como el segundo parámetro del constructor.
+                El método <code>setReadOnly()</code> puede entonces ser usado para evitar cualquier
+                modificación posterior después de que el merge se haya completado.
+            </para>
+        </note>
+    </para>
+</sect1>
+<!--
+vim:se ts=4 sw=4 et:
+-->

+ 117 - 117
documentation/manual/es/module_specs/Zend_Config_Ini.xml

@@ -1,59 +1,59 @@
-<sect1 id="zend.config.adapters.ini">
-    <title>Zend_Config_Ini</title>
-    <para>
-        <code>Zend_Config_Ini</code>
-        permite a los desarrolladores almacenar datos de configuración
-        en un formato de datos INI familiar, y leer de ellos en la
-        aplicación usando una sintáxis de propiedades de objetos
-        anidados. El formato INI se especializa en proveer tanto la
-        habilidad de mantener una jerarquía de claves de datos (data
-        keys) de configuración como la de mantener una jerarquía entre
-        secciones de datos de configuración. Las jerarquías de datos de
-        configuración son provistas separando las claves mediante el
-        carácter punto (
-        <code>.</code>
-        ). Una sección puede extender o heredar de otra sección
-        indicando el nombre de la sección seguido de dos puntos (
-        <code>:</code>
-        ) y el nombre de la sección desde la cual se quieren heredar los
-        datos.
-    </para>
-    <note>
-        <title>parse_ini_file</title>
-        <para>
-            <code>Zend_Config_Ini</code>
-            utiliza la función
-            <ulink url="http://php.net/parse_ini_file">
-                <code>parse_ini_file()</code>
-            </ulink>
-            de PHP. Por favor, revise esta documentación para observar
-            sus comportamientos específicos, que se propagan a
-            <code>Zend_Config_Ini</code>
-            , tales como la forma en que los valores especiales:
-            <code>true</code>
-            ,
-            <code>false</code>
-            ,
-            <code>yes</code>
-            ,
-            <code>no</code>
-            , y
-            <code>null</code>
-            son manejados.
-        </para>
-    </note>
-    <note>
-        <title>Separador de clave</title>
-        <para>
-            Por defecto, el carácter separador de clave es el punto (
-            <code>.</code>
-            ). Puede ser reemplazado, no obstante,cambiando la clave de
-            <code>$options</code>
-            llamada
-            <code>'nestSeparator'</code>
-            al construir el objeto
-            <code>Zend_Config_Ini</code>
-            . Por ejemplo:
+<sect1 id="zend.config.adapters.ini">
+    <title>Zend_Config_Ini</title>
+    <para>
+        <code>Zend_Config_Ini</code>
+        permite a los desarrolladores almacenar datos de configuración
+        en un formato de datos INI familiar, y leer de ellos en la
+        aplicación usando una sintáxis de propiedades de objetos
+        anidados. El formato INI se especializa en proveer tanto la
+        habilidad de mantener una jerarquía de claves de datos (data
+        keys) de configuración como la de mantener una jerarquía entre
+        secciones de datos de configuración. Las jerarquías de datos de
+        configuración son provistas separando las claves mediante el
+        carácter punto (
+        <code>.</code>
+        ). Una sección puede extender o heredar de otra sección
+        indicando el nombre de la sección seguido de dos puntos (
+        <code>:</code>
+        ) y el nombre de la sección desde la cual se quieren heredar los
+        datos.
+    </para>
+    <note>
+        <title>parse_ini_file</title>
+        <para>
+            <code>Zend_Config_Ini</code>
+            utiliza la función
+            <ulink url="http://php.net/parse_ini_file">
+                <code>parse_ini_file()</code>
+            </ulink>
+            de PHP. Por favor, revise esta documentación para observar
+            sus comportamientos específicos, que se propagan a
+            <code>Zend_Config_Ini</code>
+            , tales como la forma en que los valores especiales:
+            <code>true</code>
+            ,
+            <code>false</code>
+            ,
+            <code>yes</code>
+            ,
+            <code>no</code>
+            , y
+            <code>null</code>
+            son manejados.
+        </para>
+    </note>
+    <note>
+        <title>Separador de clave</title>
+        <para>
+            Por defecto, el carácter separador de clave es el punto (
+            <code>.</code>
+            ). Puede ser reemplazado, no obstante,cambiando la clave de
+            <code>$options</code>
+            llamada
+            <code>'nestSeparator'</code>
+            al construir el objeto
+            <code>Zend_Config_Ini</code>
+            . Por ejemplo:
             <programlisting role="php"><![CDATA[
 $options['nestSeparator'] = ':';
 $config = new Zend_Config_Ini('/path/to/config.ini',
@@ -127,64 +127,64 @@ echo $config->database->params->dbname; // muestra "dbname"
                 <tbody>
                     <row>
                         <entry>
-                            <code>$filename</code>
-                        </entry>
-                        <entry>
-                            El archivo INI que se va a cargar.
-                        </entry>
-                    </row>
-                    <row>
-                        <entry>
-                            <code>$section</code>
-                        </entry>
-                        <entry>
-                            La [sección] contenida en el archivo ini que
-                            se va a cargar. Fijar este parámetro a null
-                            cargará todas las secciones.
-                            Alternativamente, se puede introducir un
-                            array de nombres de sección para cargar
-                            multiples secciones.
-                        </entry>
-                    </row>
-                    <row>
-                        <entry>
-                            <code>$options = false</code>
-                        </entry>
-                        <entry>
-                            Array de opciones. Las siguientes claves
-                            están aceptadas:
-                            <itemizedlist>
-                                <listitem>
-                                    <para>
-                                        <emphasis>
-                                            allowModifications
-                                        </emphasis>
-                                        : Fijar a
-                                        <emphasis>true</emphasis>
-                                        para permitir modificaciones
-                                        subsiguientes del archivo
-                                        cargado. Por defecto es
-                                        <emphasis>false</emphasis>
-                                    </para>
-                                </listitem>
-                                <listitem>
-                                    <para>
-                                        <emphasis>
-                                            nestSeparator
-                                        </emphasis>
-                                        : Carácter que utilizar como
-                                        separador de anidamiento. Por
-                                        defecto es "."
-                                    </para>
-                                </listitem>
-                            </itemizedlist>
-                        </entry>
-                    </row>
-                </tbody>
-            </tgroup>
-        </table>
-    </note>
-</sect1>
-<!--
-    vim:se ts=4 sw=4 et:
--->
+                            <code>$filename</code>
+                        </entry>
+                        <entry>
+                            El archivo INI que se va a cargar.
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <code>$section</code>
+                        </entry>
+                        <entry>
+                            La [sección] contenida en el archivo ini que
+                            se va a cargar. Fijar este parámetro a null
+                            cargará todas las secciones.
+                            Alternativamente, se puede introducir un
+                            array de nombres de sección para cargar
+                            multiples secciones.
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <code>$options = false</code>
+                        </entry>
+                        <entry>
+                            Array de opciones. Las siguientes claves
+                            están aceptadas:
+                            <itemizedlist>
+                                <listitem>
+                                    <para>
+                                        <emphasis>
+                                            allowModifications
+                                        </emphasis>
+                                        : Fijar a
+                                        <emphasis>true</emphasis>
+                                        para permitir modificaciones
+                                        subsiguientes del archivo
+                                        cargado. Por defecto es
+                                        <emphasis>false</emphasis>
+                                    </para>
+                                </listitem>
+                                <listitem>
+                                    <para>
+                                        <emphasis>
+                                            nestSeparator
+                                        </emphasis>
+                                        : Carácter que utilizar como
+                                        separador de anidamiento. Por
+                                        defecto es "."
+                                    </para>
+                                </listitem>
+                            </itemizedlist>
+                        </entry>
+                    </row>
+                </tbody>
+            </tgroup>
+        </table>
+    </note>
+</sect1>
+<!--
+    vim:se ts=4 sw=4 et:
+-->

+ 146 - 146
documentation/manual/es/module_specs/Zend_Config_Xml.xml

@@ -1,146 +1,146 @@
-<sect1 id="zend.config.adapters.xml">
-    <title>Zend_Config_Xml</title>
-    <para>
-        <code>Zend_Config_Xml</code> permite a los desarrolladores almacenar 
-        datos de configuración en un formato sencillo XML y leerlos a través de 
-        una sintáxis de propiedades de objetos anidados. El elemento raíz del 
-        archivo XML es irrelevante y puede ser nombrado arbitrariamente.          
-        El primer nivel de elementos XML corresponde con las secciones de datos
-        de configuración. El formato XML admite organización jerárquica a 
-        través del anidamiento de elementos XML bajo los elementos a nivel de 
-        sección. El contenido de un elemento XML a nivel de hoja corresponde al 
-        valor de un dato de configuración. La herencia de sección está permitida
-        por un atributo XML especial llamado <code>extends</code>, y el valor de
-        este atributo se corresponde con la sección de la cual los datos son 
-        heredados por la sección extendida..
-    </para>
-    <note>
-        <title>Tipo devuelto</title>
-        <para>
-        Los datos de configuración que se leen en <code>Zend_Config_Xml</code>
-        son siempre devueltos como strings.
-              La conversión de datos de string a otros tipos se deja en manos de los
-        desarrolladores para que se ajuste a sus necesidades particulares.
-        </para>
-    </note>
-    <example id="zend.config.adapters.xml.example.using">
-        <title>Usando Zend_Config_Xml</title>
-        <para>
-         Este ejemplo ilustra un uso básico de <code>Zend_Config_Xml</code>
-         para cargar datos de configuración de un archivo XML. En este ejemplo
-         hay datos de configuración tanto para un sistema de producción como
-         para un sistema de pruebas. Debido a que los datos de configuración del 
-         sistema de pruebas son muy similares a los de producción, la sección de
-         pruebas hereda de la sección de producción. En este caso, la decisión 
-         es arbitraria y podría haberse escrito a la inversa, con la sección de
-         producción heredando de la sección de pruebas, a pesar de que éste no          
-         sería el caso para situaciones más complejas. Suponga, pues, que los 
-         datos de configuración siguientes están contenidos
-            en <code>/ruta/de/config.xml</code>:
-        </para>
-        <programlisting role="xml"><![CDATA[
-<?xml version="1.0"?>
-<configdata>
-    <production>
-        <webhost>www.example.com</webhost>
-        <database>
-            <adapter>pdo_mysql</adapter>
-            <params>
-                <host>db.example.com</host>
-                <username>dbuser</username>
-                <password>secret</password>
-                <dbname>dbname</dbname>
-            </params>
-        </database>
-    </production>
-    <staging extends="production">
-        <database>
-            <params>
-                <host>dev.example.com</host>
-                <username>devuser</username>
-                <password>devsecret</password>
-            </params>
-        </database>
-    </staging>
-</configdata>
-]]>
-</programlisting>
-        <para>
-            Ahora, asuma que el desarrollador de aplicaciones necesita los datos
-            de configuración de la fase de pruebas del archivo XML. Es una tarea
-            sencilla cargar estos datos, especificando el archivo XML y la 
-            sección de pruebas:
-        </para>
-        <programlisting role="php"><![CDATA[
-$config = new Zend_Config_Xml('/ruta/de/config.xml', 'pruebas');
-
-echo $config->database->params->host;   // muestra "dev.example.com"
-echo $config->database->params->dbname; // muestra "dbname"
-]]>
-        </programlisting>
-    </example>
-    <example id="zend.config.adapters.xml.example.attributes">
-        <title>Usando atributos de etiqueta en Zend_Config_Xml</title>
-        <para>
-            Zend_Config_Xml también soporta dos formas adicionales de definir 
-            nodos en la configuración.  Ambas hacen uso de atributos. Dado que 
-            los atributos <code>extends</code> y <code>value</code> son palabras
-            reservadas (la última por la segunda manera de usar atributos),
-            pueden no ser utilizadas. 
-                  La primera manera de utilizar atributos es añadir atributos en un
-            nodo padre, el cual será interpretado como hijo de ese nodo:
-        </para>
-        <programlisting role="xml"><![CDATA[
-<?xml version="1.0"?>
-<configdata>
-    <production webhost="www.example.com">
-        <database adapter="pdo_mysql">
-            <params host="db.example.com" username="dbuser" password="secret" dbname="dbname"/>
-        </database>
-    </production>
-    <staging extends="production">
-        <database>
-            <params host="dev.example.com" username="devuser" password="devsecret"/>
-        </database>
-    </staging>
-</configdata>
-]]>
-</programlisting>
-        <para>
-        La otra forma no reduce la configuración, sino que permite mantenerla de
-        forma más fácil dado que no es necesario escribir el nombre de la 
-        etiqueta dos veces. Simplemente, cree una etiqueta vacía con el valor en 
-        el atributo <code>value</code>:
-        </para>
-        <programlisting role="xml"><![CDATA[
-<?xml version="1.0"?>
-<configdata>
-    <production>
-        <webhost>www.example.com</webhost>
-        <database>
-            <adapter value="pdo_mysql"/>
-            <params>
-                <host value="db.example.com"/>
-                <username value="dbuser"/>
-                <password value="secret"/>
-                <dbname value="dbname"/>
-            </params>
-        </database>
-    </production>
-    <staging extends="production">
-        <database>
-            <params>
-                <host value="dev.example.com"/>
-                <username value="devuser"/>
-                <password value="devsecret"/>
-            </params>
-        </database>
-    </staging>
-</configdata>
-]]>
-</programlisting>
-    </example>
-</sect1>
-<!--
-vim:se ts=4 sw=4 et:
--->
+<sect1 id="zend.config.adapters.xml">
+    <title>Zend_Config_Xml</title>
+    <para>
+        <code>Zend_Config_Xml</code> permite a los desarrolladores almacenar 
+        datos de configuración en un formato sencillo XML y leerlos a través de 
+        una sintáxis de propiedades de objetos anidados. El elemento raíz del 
+        archivo XML es irrelevante y puede ser nombrado arbitrariamente.          
+        El primer nivel de elementos XML corresponde con las secciones de datos
+        de configuración. El formato XML admite organización jerárquica a 
+        través del anidamiento de elementos XML bajo los elementos a nivel de 
+        sección. El contenido de un elemento XML a nivel de hoja corresponde al 
+        valor de un dato de configuración. La herencia de sección está permitida
+        por un atributo XML especial llamado <code>extends</code>, y el valor de
+        este atributo se corresponde con la sección de la cual los datos son 
+        heredados por la sección extendida..
+    </para>
+    <note>
+        <title>Tipo devuelto</title>
+        <para>
+        Los datos de configuración que se leen en <code>Zend_Config_Xml</code>
+        son siempre devueltos como strings.
+              La conversión de datos de string a otros tipos se deja en manos de los
+        desarrolladores para que se ajuste a sus necesidades particulares.
+        </para>
+    </note>
+    <example id="zend.config.adapters.xml.example.using">
+        <title>Usando Zend_Config_Xml</title>
+        <para>
+         Este ejemplo ilustra un uso básico de <code>Zend_Config_Xml</code>
+         para cargar datos de configuración de un archivo XML. En este ejemplo
+         hay datos de configuración tanto para un sistema de producción como
+         para un sistema de pruebas. Debido a que los datos de configuración del 
+         sistema de pruebas son muy similares a los de producción, la sección de
+         pruebas hereda de la sección de producción. En este caso, la decisión 
+         es arbitraria y podría haberse escrito a la inversa, con la sección de
+         producción heredando de la sección de pruebas, a pesar de que éste no          
+         sería el caso para situaciones más complejas. Suponga, pues, que los 
+         datos de configuración siguientes están contenidos
+            en <code>/ruta/de/config.xml</code>:
+        </para>
+        <programlisting role="xml"><![CDATA[
+<?xml version="1.0"?>
+<configdata>
+    <production>
+        <webhost>www.example.com</webhost>
+        <database>
+            <adapter>pdo_mysql</adapter>
+            <params>
+                <host>db.example.com</host>
+                <username>dbuser</username>
+                <password>secret</password>
+                <dbname>dbname</dbname>
+            </params>
+        </database>
+    </production>
+    <staging extends="production">
+        <database>
+            <params>
+                <host>dev.example.com</host>
+                <username>devuser</username>
+                <password>devsecret</password>
+            </params>
+        </database>
+    </staging>
+</configdata>
+]]>
+</programlisting>
+        <para>
+            Ahora, asuma que el desarrollador de aplicaciones necesita los datos
+            de configuración de la fase de pruebas del archivo XML. Es una tarea
+            sencilla cargar estos datos, especificando el archivo XML y la 
+            sección de pruebas:
+        </para>
+        <programlisting role="php"><![CDATA[
+$config = new Zend_Config_Xml('/ruta/de/config.xml', 'pruebas');
+
+echo $config->database->params->host;   // muestra "dev.example.com"
+echo $config->database->params->dbname; // muestra "dbname"
+]]>
+        </programlisting>
+    </example>
+    <example id="zend.config.adapters.xml.example.attributes">
+        <title>Usando atributos de etiqueta en Zend_Config_Xml</title>
+        <para>
+            Zend_Config_Xml también soporta dos formas adicionales de definir 
+            nodos en la configuración.  Ambas hacen uso de atributos. Dado que 
+            los atributos <code>extends</code> y <code>value</code> son palabras
+            reservadas (la última por la segunda manera de usar atributos),
+            pueden no ser utilizadas. 
+                  La primera manera de utilizar atributos es añadir atributos en un
+            nodo padre, el cual será interpretado como hijo de ese nodo:
+        </para>
+        <programlisting role="xml"><![CDATA[
+<?xml version="1.0"?>
+<configdata>
+    <production webhost="www.example.com">
+        <database adapter="pdo_mysql">
+            <params host="db.example.com" username="dbuser" password="secret" dbname="dbname"/>
+        </database>
+    </production>
+    <staging extends="production">
+        <database>
+            <params host="dev.example.com" username="devuser" password="devsecret"/>
+        </database>
+    </staging>
+</configdata>
+]]>
+</programlisting>
+        <para>
+        La otra forma no reduce la configuración, sino que permite mantenerla de
+        forma más fácil dado que no es necesario escribir el nombre de la 
+        etiqueta dos veces. Simplemente, cree una etiqueta vacía con el valor en 
+        el atributo <code>value</code>:
+        </para>
+        <programlisting role="xml"><![CDATA[
+<?xml version="1.0"?>
+<configdata>
+    <production>
+        <webhost>www.example.com</webhost>
+        <database>
+            <adapter value="pdo_mysql"/>
+            <params>
+                <host value="db.example.com"/>
+                <username value="dbuser"/>
+                <password value="secret"/>
+                <dbname value="dbname"/>
+            </params>
+        </database>
+    </production>
+    <staging extends="production">
+        <database>
+            <params>
+                <host value="dev.example.com"/>
+                <username value="devuser"/>
+                <password value="devsecret"/>
+            </params>
+        </database>
+    </staging>
+</configdata>
+]]>
+</programlisting>
+    </example>
+</sect1>
+<!--
+vim:se ts=4 sw=4 et:
+-->

+ 379 - 379
documentation/manual/es/module_specs/Zend_Controller-QuickStart.xml

@@ -1,379 +1,379 @@
-<sect1 id="zend.controller.quickstart">
-    <title>Zend_Controller Quick Start</title>
-
-    <sect2 id="zend.controller.quickstart.introduction">
-        <title>Introducción</title>
-        <para>
-            <code>Zend_Controller</code>
-            es el corazón del sistema de MVC de Zend Framework MVC. MVC
-            son las siglas de
-            <ulink url="http://en.wikipedia.org/wiki/Model-view-controller">
-                Modelo-Vista-Controlador
-            </ulink>
-            y es un patrón de diseño con el objetivo de separar la
-            lógica de la aplicación de la lógica de visualización.
-            <code>Zend_Controller_Front</code>
-            implementa el patrón
-            <ulink url="http://www.martinfowler.com/eaaCatalog/frontController.html">
-                Front Controller (Controlador Frontal)
-            </ulink>
-            en el cual todas las transacciones HTTP (requests) son
-            interceptadas por el controlador frontal y despachado a una
-            Acción particular de un Controlador según la URL pedida.
-
-
-        </para>
-        <para>
-            El sistema
-            <code>Zend_Controller</code>
-            fue construido con la extensibilidad en mente, ya sea
-            heredando las clases existentes, escribiendo nuevas clases
-            que implementan varias interfaces o clases abstractas que
-            forman la base de la familia de clases del controlador, o
-            escribiendo plugins o helpers de las acciones para aumentar
-            o manipular la funcionalidad del sistema.
-        </para>
-    </sect2>
-
-    <sect2 id="zend.controller.quickstart.go">
-        <title>Quick Start</title>
-
-        <para>
-            Si necesita información más detallada, mire las secciones
-            siguientes. Si solamente quiere inicializar y ejecutar una
-            aplicación rápidamente, siga leyendo.
-        </para>
-
-        <sect3 id="zend.controller.quickstart.go.directory">
-            <title>Cree su estructura de archivos</title>
-
-            <para>
-                El primer paso es crear su estructura de archivos. La
-                estructura típica es la siguiente:
-            </para>
-
-            <programlisting role="php"><![CDATA[
-application/
-    controllers/
-        IndexController.php
-    models/
-    views/
-        scripts/
-            index/
-                index.phtml
-        helpers/
-        filters/
-html/
-    .htaccess
-    index.php
-]]>
-            </programlisting>
-
-        </sect3>
-
-        <sect3 id="zend.controller.quickstart.go.docroot">
-            <title>Establezca su document root</title>
-
-            <para>
-                Apunte su document root en su servidor web hacia el
-                directorio
-                <code>html</code>
-                de la estrctura de archivos de arriba.
-            </para>
-        </sect3>
-
-        <sect3 id="zend.controller.quickstart.go.rewrite">
-            <title>Cree sus reglas de reescritura</title>
-
-            <para>
-                Edite el archivo
-                <code>html/.htaccess</code>
-                que aparece arriba de la siguiente forma:
-            </para>
-
-            <programlisting role="php"><![CDATA[
-RewriteEngine On
-RewriteCond %{REQUEST_FILENAME} -s [OR]
-RewriteCond %{REQUEST_FILENAME} -l [OR]
-RewriteCond %{REQUEST_FILENAME} -d
-RewriteRule ^.*$ - [NC,L]
-RewriteRule ^.*$ index.php [NC,L]
-]]>
-            </programlisting>
-
-            <para>
-                La regla de arriba redigirá las peticiones a recuros existentes
-                (enlaces simbólicos existentes, archivos no vacíos, o directorios no vacíos) 
-        en consecuencia, y todas las otras peticiones al front controller.
-            </para>
-
-            <note>
-                <para>
-                    Las reglas de arriba pertenecen a Apache. Para ejemplos de reglas
-                    de rewrite para otros servidores web, mire la 
-                    <link linkend="zend.controller.router.introduction">
-                        documentación de router
-                    </link>
-                    .
-                </para>
-            </note>
-        </sect3>
-
-        <sect3 id="zend.controller.quickstart.go.bootstrap">
-            <title>Cree su archivo bootstrap</title>
-
-            <para>
-                El archivo bootstrap es la página a la que todas las peticiones
-                son redirigidas a través de --
-                <code>html/index.php</code>
-                en este caso. Abra el archivo 
-                <code>html/index.php</code>
-                en el editor de su elección y añada lo siguiente:
-            </para>
-
-            <programlisting role="php"><![CDATA[
-Zend_Controller_Front::run('/path/to/app/controllers');
-]]>
-            </programlisting>
-
-            <para>
-                Esto instanciará y hará un dispatch del front controller, que 
-                redigirá las peticiones a los action controllers.
-            </para>
-        </sect3>
-
-        <sect3 id="zend.controller.quickstart.go.controller">
-            <title>Cree su action controller por defecto</title>
-
-            <para>
-                Antes de tratar los action controllers, debe primero
-                entender cómo las peticiones son redirigidas en Zend Framework.
-                Por defecto, el primero segmento de una ruta URL apunta
-                a un controlador, y el segundo a una acción. Por ejemplo,
-                dada la URL
-                <code>
-                    http://framework.zend.com/roadmap/components
-                </code>
-                , la ruta es
-                <code>/roadmap/components</code>
-                , que apuntará al controlador
-                <code>roadmap</code>
-                y la acción
-                <code>components</code>
-                . Si no se suministra una acción, se asume la acción
-                <code>index</code>
-                , y si no se suministra un controlador, se asume el controlador
-                <code>index</code>
-                (siguiendo la convención de Apache de apuntar a 
-                <code>DirectoryIndex</code>
-                automáticamente).
-            </para>
-
-            <para>
-                El dispatcher de <code>Zend_Controller</code>
-                toma entonces el valor del controlador y lo apunta
-                a una clase. Por defecto, pone en mayúsculas la primera letra
-                del nombre de controlador y agrega la palabra
-                <code>Controller</code>
-                . De esta forma, en nuestro ejemplo de arriba, el controlador
-                <code>roadmap</code>
-                es dirigido a la clase
-                <code>RoadmapController</code>
-                .
-            </para>
-
-            <para>
-                De la misma forma, el valor de action es dirigido
-                a un método de la clase controladora. Por defecto, el valor se
-                pasa a minúsculas, y la palabra
-                <code>Action</code>
-                es añadida. De esta forma, en nuestro ejemplo de arriba, la acción
-                <code>components</code>
-                se convierte en
-                <code>componentsAction</code>
-                , y el método final llamado es
-                <code>RoadmapController::componentsAction()</code>
-                .
-            </para>
-
-            <para>
-                Continuando, creemos ahora un action controller 
-                y un método de acción por defecto. Como se ha dicho antes,
-                el controlador por defecto y la acción llamada son ambos
-                <code>index</code>
-                . Abra el archivo
-                <code>application/controllers/IndexController.php</code>
-                , e introduzca lo siguiente:
-            </para>
-
-            <programlisting role="php"><![CDATA[
-/** Zend_Controller_Action */
-class IndexController extends Zend_Controller_Action
-{
-    public function indexAction()
-    {
-    }
-}
-]]>
-            </programlisting>
-
-            <para>
-                Por defecto, el action helper
-                <link linkend="zend.controller.actionhelpers.viewrenderer">
-                    ViewRenderer
-                </link>
-                está activado. Esto significa que simplemente
-                definiendo un action method y un view script correspondiente,
-                tendrá su contenido generado inmediatamente.
-                Por defecto,
-                <code>Zend_View</code>
-                es usado como la capa Vista en el patrón MVC. El
-                <code>ViewRenderer</code>
-                hace algo de magia, y usa el nombre de controlador (e.g.,
-                <code>index</code>
-                ) y el nombre de acción actual (e.g.,
-                <code>index</code>
-                ) para determinar qué plantilla traer. Por defecto,
-                las plantillas terminan con la extensión
-                <code>.phtml</code>
-                , lo que significa que en el ejemplo de arriba, la
-                plantilla
-                <code>index/index.phtml</code>
-                será generada. Adicionalmente, el
-                <code>ViewRenderer</code>
-                asume automáticamente que la carpeta
-                <code>views</code>
-                al mismo nivel que la carpeta controller será
-                la carpeta raíz de la vista, y que el script de vista actual
-                estará en la subcarpeta
-                <code>views/scripts/</code>.
-                De esta forma, la plantilla generada será encontrada en
-                <code>application/views/scripts/index/index.phtml</code>
-                .
-            </para>
-        </sect3>
-
-        <sect3 id="zend.controller.quickstart.go.view">
-            <title>Cree su view script</title>
-
-            <para>
-                Como hemos mencionado
-                <link linkend="zend.controller.quickstart.go.controller">
-                    en la sección anterior
-                </link>
-                , los scripts de vista se encuentran en 
-                <code>application/views/scripts/</code>
-                ; el view script para el controlador y la acción por defecto 
-                está en
-                <code>application/views/scripts/index/index.phtml</code>
-                . Cree este archivo, y escriba un poco de HTML:
-            </para>
-
-            <programlisting role="php"><![CDATA[
-<!DOCTYPE html
-PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html>
-<head>
-  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-  <title>Mi primera aplicación Zend Framework</title>
-</head>
-<body>
-    <h1>>¡Hola, Mundo!</h1>
-</body>
-</html>
-]]>
-            </programlisting>
-        </sect3>
-
-        <sect3 id="zend.controller.quickstart.go.errorhandler">
-            <title>Cree su controlador de errores</title>
-
-            <para>
-                Por defecto, está registrado
-                <link linkend="zend.controller.plugins.standard.errorhandler">
-                    el plugin 'error handler'
-                </link>. Este plugin espera que exista
-                un controlador para manejar los errores.
-                Por defecto, asume un 
-                <code>ErrorController</code>
-                en el módulo default con un método
-                <code>errorAction</code>
-                :
-            </para>
-
-            <programlisting role="php"><![CDATA[
-class ErrorController extends Zend_Controller_Action
-{
-    public function errorAction()
-    {
-    }
-}
-]]>
-            </programlisting>
-
-            <para>
-                Asumiendo el sistema de carpetas discutido anteriormente, 
-                este archivo irá en
-                <code>application/controllers/ErrorController.php</code>
-                . También necesitará crear un view script en
-                <code>application/views/scripts/error/error.phtml</code>
-                ; el contenido de ejemplo será parecido a:
-            </para>
-
-            <programlisting role="php"><![CDATA[
-<!DOCTYPE html
-PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html>
-<head>
-  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-  <title>Error</title>
-</head>
-<body>
-    <h1>Ocurrió un error</h1>
-    <p>Ocurrió un error; Por favor, inténtelo de nuevo más tarde.</p>
-</body>
-</html>
-]]>
-            </programlisting>
-        </sect3>
-
-        <sect3 id="zend.controller.quickstart.go.finish">
-            <title>¡Vea el sitio!</title>
-
-            <para>
-                Con su primer controlador y vista, ya puede arrancar su navegador y acceder a su sitio.
-                Asumiendo que
-                <code>example.com</code>
-                es su dominio, cualquiera de las siguientes URLs le llevará a 
-                la página que acaba de crear:
-            </para>
-
-            <itemizedlist>
-                <listitem>
-                    <para>
-                        <code>http://example.com/</code>
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        <code>http://example.com/index</code>
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        <code>http://example.com/index/index</code>
-                    </para>
-                </listitem>
-            </itemizedlist>
-
-            <para>
-                Ya está listo para empezar a crear más métodos de controladores y acciones. ¡Felicidades!
-            </para>
-        </sect3>
-    </sect2>
-</sect1>
-<!--
-    vim:se ts=4 sw=4 et:
--->
+<sect1 id="zend.controller.quickstart">
+    <title>Zend_Controller Quick Start</title>
+
+    <sect2 id="zend.controller.quickstart.introduction">
+        <title>Introducción</title>
+        <para>
+            <code>Zend_Controller</code>
+            es el corazón del sistema de MVC de Zend Framework MVC. MVC
+            son las siglas de
+            <ulink url="http://en.wikipedia.org/wiki/Model-view-controller">
+                Modelo-Vista-Controlador
+            </ulink>
+            y es un patrón de diseño con el objetivo de separar la
+            lógica de la aplicación de la lógica de visualización.
+            <code>Zend_Controller_Front</code>
+            implementa el patrón
+            <ulink url="http://www.martinfowler.com/eaaCatalog/frontController.html">
+                Front Controller (Controlador Frontal)
+            </ulink>
+            en el cual todas las transacciones HTTP (requests) son
+            interceptadas por el controlador frontal y despachado a una
+            Acción particular de un Controlador según la URL pedida.
+
+
+        </para>
+        <para>
+            El sistema
+            <code>Zend_Controller</code>
+            fue construido con la extensibilidad en mente, ya sea
+            heredando las clases existentes, escribiendo nuevas clases
+            que implementan varias interfaces o clases abstractas que
+            forman la base de la familia de clases del controlador, o
+            escribiendo plugins o helpers de las acciones para aumentar
+            o manipular la funcionalidad del sistema.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.controller.quickstart.go">
+        <title>Quick Start</title>
+
+        <para>
+            Si necesita información más detallada, mire las secciones
+            siguientes. Si solamente quiere inicializar y ejecutar una
+            aplicación rápidamente, siga leyendo.
+        </para>
+
+        <sect3 id="zend.controller.quickstart.go.directory">
+            <title>Cree su estructura de archivos</title>
+
+            <para>
+                El primer paso es crear su estructura de archivos. La
+                estructura típica es la siguiente:
+            </para>
+
+            <programlisting role="php"><![CDATA[
+application/
+    controllers/
+        IndexController.php
+    models/
+    views/
+        scripts/
+            index/
+                index.phtml
+        helpers/
+        filters/
+html/
+    .htaccess
+    index.php
+]]>
+            </programlisting>
+
+        </sect3>
+
+        <sect3 id="zend.controller.quickstart.go.docroot">
+            <title>Establezca su document root</title>
+
+            <para>
+                Apunte su document root en su servidor web hacia el
+                directorio
+                <code>html</code>
+                de la estrctura de archivos de arriba.
+            </para>
+        </sect3>
+
+        <sect3 id="zend.controller.quickstart.go.rewrite">
+            <title>Cree sus reglas de reescritura</title>
+
+            <para>
+                Edite el archivo
+                <code>html/.htaccess</code>
+                que aparece arriba de la siguiente forma:
+            </para>
+
+            <programlisting role="php"><![CDATA[
+RewriteEngine On
+RewriteCond %{REQUEST_FILENAME} -s [OR]
+RewriteCond %{REQUEST_FILENAME} -l [OR]
+RewriteCond %{REQUEST_FILENAME} -d
+RewriteRule ^.*$ - [NC,L]
+RewriteRule ^.*$ index.php [NC,L]
+]]>
+            </programlisting>
+
+            <para>
+                La regla de arriba redigirá las peticiones a recuros existentes
+                (enlaces simbólicos existentes, archivos no vacíos, o directorios no vacíos) 
+        en consecuencia, y todas las otras peticiones al front controller.
+            </para>
+
+            <note>
+                <para>
+                    Las reglas de arriba pertenecen a Apache. Para ejemplos de reglas
+                    de rewrite para otros servidores web, mire la 
+                    <link linkend="zend.controller.router.introduction">
+                        documentación de router
+                    </link>
+                    .
+                </para>
+            </note>
+        </sect3>
+
+        <sect3 id="zend.controller.quickstart.go.bootstrap">
+            <title>Cree su archivo bootstrap</title>
+
+            <para>
+                El archivo bootstrap es la página a la que todas las peticiones
+                son redirigidas a través de --
+                <code>html/index.php</code>
+                en este caso. Abra el archivo 
+                <code>html/index.php</code>
+                en el editor de su elección y añada lo siguiente:
+            </para>
+
+            <programlisting role="php"><![CDATA[
+Zend_Controller_Front::run('/path/to/app/controllers');
+]]>
+            </programlisting>
+
+            <para>
+                Esto instanciará y hará un dispatch del front controller, que 
+                redigirá las peticiones a los action controllers.
+            </para>
+        </sect3>
+
+        <sect3 id="zend.controller.quickstart.go.controller">
+            <title>Cree su action controller por defecto</title>
+
+            <para>
+                Antes de tratar los action controllers, debe primero
+                entender cómo las peticiones son redirigidas en Zend Framework.
+                Por defecto, el primero segmento de una ruta URL apunta
+                a un controlador, y el segundo a una acción. Por ejemplo,
+                dada la URL
+                <code>
+                    http://framework.zend.com/roadmap/components
+                </code>
+                , la ruta es
+                <code>/roadmap/components</code>
+                , que apuntará al controlador
+                <code>roadmap</code>
+                y la acción
+                <code>components</code>
+                . Si no se suministra una acción, se asume la acción
+                <code>index</code>
+                , y si no se suministra un controlador, se asume el controlador
+                <code>index</code>
+                (siguiendo la convención de Apache de apuntar a 
+                <code>DirectoryIndex</code>
+                automáticamente).
+            </para>
+
+            <para>
+                El dispatcher de <code>Zend_Controller</code>
+                toma entonces el valor del controlador y lo apunta
+                a una clase. Por defecto, pone en mayúsculas la primera letra
+                del nombre de controlador y agrega la palabra
+                <code>Controller</code>
+                . De esta forma, en nuestro ejemplo de arriba, el controlador
+                <code>roadmap</code>
+                es dirigido a la clase
+                <code>RoadmapController</code>
+                .
+            </para>
+
+            <para>
+                De la misma forma, el valor de action es dirigido
+                a un método de la clase controladora. Por defecto, el valor se
+                pasa a minúsculas, y la palabra
+                <code>Action</code>
+                es añadida. De esta forma, en nuestro ejemplo de arriba, la acción
+                <code>components</code>
+                se convierte en
+                <code>componentsAction</code>
+                , y el método final llamado es
+                <code>RoadmapController::componentsAction()</code>
+                .
+            </para>
+
+            <para>
+                Continuando, creemos ahora un action controller 
+                y un método de acción por defecto. Como se ha dicho antes,
+                el controlador por defecto y la acción llamada son ambos
+                <code>index</code>
+                . Abra el archivo
+                <code>application/controllers/IndexController.php</code>
+                , e introduzca lo siguiente:
+            </para>
+
+            <programlisting role="php"><![CDATA[
+/** Zend_Controller_Action */
+class IndexController extends Zend_Controller_Action
+{
+    public function indexAction()
+    {
+    }
+}
+]]>
+            </programlisting>
+
+            <para>
+                Por defecto, el action helper
+                <link linkend="zend.controller.actionhelpers.viewrenderer">
+                    ViewRenderer
+                </link>
+                está activado. Esto significa que simplemente
+                definiendo un action method y un view script correspondiente,
+                tendrá su contenido generado inmediatamente.
+                Por defecto,
+                <code>Zend_View</code>
+                es usado como la capa Vista en el patrón MVC. El
+                <code>ViewRenderer</code>
+                hace algo de magia, y usa el nombre de controlador (e.g.,
+                <code>index</code>
+                ) y el nombre de acción actual (e.g.,
+                <code>index</code>
+                ) para determinar qué plantilla traer. Por defecto,
+                las plantillas terminan con la extensión
+                <code>.phtml</code>
+                , lo que significa que en el ejemplo de arriba, la
+                plantilla
+                <code>index/index.phtml</code>
+                será generada. Adicionalmente, el
+                <code>ViewRenderer</code>
+                asume automáticamente que la carpeta
+                <code>views</code>
+                al mismo nivel que la carpeta controller será
+                la carpeta raíz de la vista, y que el script de vista actual
+                estará en la subcarpeta
+                <code>views/scripts/</code>.
+                De esta forma, la plantilla generada será encontrada en
+                <code>application/views/scripts/index/index.phtml</code>
+                .
+            </para>
+        </sect3>
+
+        <sect3 id="zend.controller.quickstart.go.view">
+            <title>Cree su view script</title>
+
+            <para>
+                Como hemos mencionado
+                <link linkend="zend.controller.quickstart.go.controller">
+                    en la sección anterior
+                </link>
+                , los scripts de vista se encuentran en 
+                <code>application/views/scripts/</code>
+                ; el view script para el controlador y la acción por defecto 
+                está en
+                <code>application/views/scripts/index/index.phtml</code>
+                . Cree este archivo, y escriba un poco de HTML:
+            </para>
+
+            <programlisting role="php"><![CDATA[
+<!DOCTYPE html
+PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+  <title>Mi primera aplicación Zend Framework</title>
+</head>
+<body>
+    <h1>>¡Hola, Mundo!</h1>
+</body>
+</html>
+]]>
+            </programlisting>
+        </sect3>
+
+        <sect3 id="zend.controller.quickstart.go.errorhandler">
+            <title>Cree su controlador de errores</title>
+
+            <para>
+                Por defecto, está registrado
+                <link linkend="zend.controller.plugins.standard.errorhandler">
+                    el plugin 'error handler'
+                </link>. Este plugin espera que exista
+                un controlador para manejar los errores.
+                Por defecto, asume un 
+                <code>ErrorController</code>
+                en el módulo default con un método
+                <code>errorAction</code>
+                :
+            </para>
+
+            <programlisting role="php"><![CDATA[
+class ErrorController extends Zend_Controller_Action
+{
+    public function errorAction()
+    {
+    }
+}
+]]>
+            </programlisting>
+
+            <para>
+                Asumiendo el sistema de carpetas discutido anteriormente, 
+                este archivo irá en
+                <code>application/controllers/ErrorController.php</code>
+                . También necesitará crear un view script en
+                <code>application/views/scripts/error/error.phtml</code>
+                ; el contenido de ejemplo será parecido a:
+            </para>
+
+            <programlisting role="php"><![CDATA[
+<!DOCTYPE html
+PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+  <title>Error</title>
+</head>
+<body>
+    <h1>Ocurrió un error</h1>
+    <p>Ocurrió un error; Por favor, inténtelo de nuevo más tarde.</p>
+</body>
+</html>
+]]>
+            </programlisting>
+        </sect3>
+
+        <sect3 id="zend.controller.quickstart.go.finish">
+            <title>¡Vea el sitio!</title>
+
+            <para>
+                Con su primer controlador y vista, ya puede arrancar su navegador y acceder a su sitio.
+                Asumiendo que
+                <code>example.com</code>
+                es su dominio, cualquiera de las siguientes URLs le llevará a 
+                la página que acaba de crear:
+            </para>
+
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        <code>http://example.com/</code>
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <code>http://example.com/index</code>
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <code>http://example.com/index/index</code>
+                    </para>
+                </listitem>
+            </itemizedlist>
+
+            <para>
+                Ya está listo para empezar a crear más métodos de controladores y acciones. ¡Felicidades!
+            </para>
+        </sect3>
+    </sect2>
+</sect1>
+<!--
+    vim:se ts=4 sw=4 et:
+-->

+ 172 - 172
documentation/manual/es/module_specs/Zend_Date-Introduction.xml

@@ -1,172 +1,172 @@
-<sect1 id="zend.date.introduction">
-
-    <title>Introducción</title>
-
-    <para>
-        El componente
-        <code>Zend_Date</code>
-        ofrece una API detallada pero simple para manipular fechas y
-        horas. Sus métodos aceptan una gran variedad de tipos de
-        información, incluyendo partes de fecha, en numerosas
-        combinaciones provocando muchas características y posibilidades
-        más allá de las funciones de fecha PHP relacionadas. Para
-        las últimas actualizaciones manuales, por favor ver el siguiente
-        link <ulink
-        url="http://framework.zend.com/wiki/display/ZFDOCDEV/Home">our
-        online manual (sincronizado frecuentemente con Subversion)
-        </ulink>
-        .
-    </para>
-
-    <para>
-        Aunque la simplicidad sea el objetivo, trabajar con fechas y
-        tiempos localizados mientras se modifican, combinan y comparan
-        partes, provoca una complejidad inevitable. Las fechas, así como
-        los tiempos, a menudo son escritos de forma diferente en
-        zonas locales distintas. Por ejemplo, algunos colocan primero el
-        mes, mientras otros escriben el año en primer lugar cuando
-        expresan fechas del calendario. Para más información relacionada
-        con manejo de localizaciones y normalización, por favor
-        vea el manual de
-        <link linkend="zend.locale.date.datesandtimes">
-            <code>Zend_Locale</code>
-        </link>
-        .
-    </para>
-
-    <para>
-        <code>Zend_Date</code>
-        también soporta nombres de meses abreviados en varios idiomas.
-        <code>Zend_Locale</code>
-        facilita la normalización de meses localizados y nombres de días
-        de la semana a timestamps, los cuales pueden, a su vez, ser
-        mostrados localizados a otras regiones.
-    </para>
-
-    <sect2 id="zend.date.setdefaulttimezone">
-
-        <title>Asigne Siempre una Zona Horaria por Defecto</title>
-
-        <para>
-            Antes de utilizar funciones relacionadas con fechas en PHP o
-            en el Zend Framework, primero debe asegurarse que su
-            aplicación tiene una zona horaria correcta por defecto,
-            configurando la variable de entorno TZ, usando el
-            parametro del php.ini
-            <code>date.timezone</code>
-            , o usando
-            <ulink url="http://php.net/date_default_timezone_set">
-                date_default_timezone_set()
-            </ulink>
-            . En PHP, podemos ajustar todas las funciones relacionadas
-            con fechas y hora para trabajar para un usuario particular
-            configurando por defecto una zona horaria de acuerdo a las
-            expectativas del usuario. Para una lista completa de
-            configuraciones de zona horaria, vea el siguiente link
-            <ulink url="http://unicode.org/cldr/data/diff/supplemental/territory_containment_un_m_49.html">
-                Lista de Identificadores de Zonas Horarias CLDR
-            </ulink>
-            .
-            <example id="zend.date.setdefaulttimezone.example-1">
-                <title>Configurando una Zona Horaria por Defecto</title>
-                <programlisting role="php"><![CDATA[
-                // zona horaria para un estadounidense en California
-date_default_timezone_set('America/Los_Angeles');
-// zona horaria para un alemán en Alemania
-date_default_timezone_set('Europe/Berlin');
-]]>
-                </programlisting>
-            </example>
-            <emphasis role="strong">¡Al crear instancias de Zend_Date, su zona horaria se convertirá automáticamente
-            en la zona horaria por defecto actual!</emphasis> De esta forma, la configuración de zona horaria tendrá
-            en cuenta cualquier cambio de hora de invierno/verano (Daylight Saving Time, DST), eliminando la necesidad
-            de especificarlo explícitamente.
-        </para>
-
-        <para>
-            Tenga en cuenta que las zonas horarias <emphasis role="strong">UTC</emphasis> y
-            <emphasis role="strong">GMT</emphasis> no incluyen el cambio de hora de invierno/verano (Daylight Saving Time, DST). 
-            Esto significa que aunque defina a mano que <code>Zend_Date</code> deba trabajar con DST, podría
-            ser anulado por las instancias de <code>Zend_Date</code> que han sido fijadas a
-            UTC o GMT.
-        </para>
-    </sect2>
-
-    <sect2 id="zend.date.why">
-
-        <title>¿Por Qué Usar Zend_Date?</title>
-
-        <para>
-            <code>Zend_Date</code> ofrece las siguientes prestaciones, las cuales extienden el alcance de las funciones de fecha de PHP:
-        </para>
-
-        <itemizedlist mark="opencircle">
-            <listitem>
-                <para>
-                    API sencilla
-                </para>
-                <para>
-                    <code>Zend_Date</code> aporta una API muy sencilla, que combina lo mejor de la funcionalidad
-                    fecha/hora de cuatro lenguajes de programación. Es posible, por ejemplo, añadir o comparar dos horas 
-                    dentro de una misma columna.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                    Completamente internacionalizado
-                </para>
-                <para>
-                    Todos los nombres de meses y días de la semana completos y abreviados están incluidos para más de 130 idiomas.
-                    Los métodos admiten tanto entrada como salida de fechas usando los nombres localizados de meses y días de la semana.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                    Timestamps ilimitados
-                </para>
-                <para>
-                    A pesar de que la documentación de PHP 5.2 indice: "El intervalo de valores admitidos de timestamps es
-                    desde el 13 Dec 1901 20:45:54 GMT al 19 Ene 2038 03:14:07 GMT," <code>Zend_Date</code> admite un rango
-                    casi ilimitado, con la ayuda de la extensión BCMath. Si BCMath no está disponible, Zend_Date tendrá una 
-                    funcionalidad de timestamps reducida al rango del tipo <code>float</code> soportado por su servidor.
-                    El tamaño de un float es dependiente de la plataforma, aunque un máximo de ~1.8e308 con una precisión
-                    de cerca de 14 dígitos decimales es un valor habitual (formato 64 bit IEEE)." [
-                    <ulink url="http://www.php.net/float">http://www.php.net/float</ulink>
-                    ].  Adicionalmente, las limitaciones heredadas de los tipos de dato float, y errores de redondeo de números
-                    flotantes pueden introducir errores en los cálculos. Para evitar estos problemas, los componentes ZF I18n 
-                    usan la extensión BCMath, si está disponible.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                    Soporte para especificaciones de fecha ISO_8601
-                </para>
-                <para>
-                    Las especificaciones de fecha ISO_8601 están aceptadas. Incluso las especificaciones de fecha ISO_8601 
-                    parcialmente autorizadas serán identificadas. Estos formatos de fecha son particularmente útiles al
-                    trabajar con bases de datos. Por ejemplo, aunque MsSQL y 
-                    <ulink url="http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html">MySQL</ulink>
-                    difieren ligeramente uno de otro, ambos tienen soporte por parte de <code>Zend_Date</code> usando la constante 
-                    de especificación de formato 
-                    <link linkend="zend.date.constants.list">Zend_Date::ISO_8601</link>.
-                    Cuando las cadenas de fecha sean del tipo "Y/m/d" o "Y-m-d H:i:s", de acuerdo con los tokens de formato
-                    PHP date(), use el soporte integrado de Zend_Date para fechas formateadas ISO 8601.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                    Calcular amanecer y puesta de sol
-                </para>
-                <para>
-                    Las horas de amanecer y puesta de sol pueden mostrarse para cualquier lugar y día, para que no pierda ni un segundo de luz diurna 
-                    para trabajar en su proyecto PHP favorito :)
-                </para>
-            </listitem>
-        </itemizedlist>
-
-    </sect2>
-
-</sect1>
-<!--
-    vim:se ts=4 sw=4 et:
--->
+<sect1 id="zend.date.introduction">
+
+    <title>Introducción</title>
+
+    <para>
+        El componente
+        <code>Zend_Date</code>
+        ofrece una API detallada pero simple para manipular fechas y
+        horas. Sus métodos aceptan una gran variedad de tipos de
+        información, incluyendo partes de fecha, en numerosas
+        combinaciones provocando muchas características y posibilidades
+        más allá de las funciones de fecha PHP relacionadas. Para
+        las últimas actualizaciones manuales, por favor ver el siguiente
+        link <ulink
+        url="http://framework.zend.com/wiki/display/ZFDOCDEV/Home">our
+        online manual (sincronizado frecuentemente con Subversion)
+        </ulink>
+        .
+    </para>
+
+    <para>
+        Aunque la simplicidad sea el objetivo, trabajar con fechas y
+        tiempos localizados mientras se modifican, combinan y comparan
+        partes, provoca una complejidad inevitable. Las fechas, así como
+        los tiempos, a menudo son escritos de forma diferente en
+        zonas locales distintas. Por ejemplo, algunos colocan primero el
+        mes, mientras otros escriben el año en primer lugar cuando
+        expresan fechas del calendario. Para más información relacionada
+        con manejo de localizaciones y normalización, por favor
+        vea el manual de
+        <link linkend="zend.locale.date.datesandtimes">
+            <code>Zend_Locale</code>
+        </link>
+        .
+    </para>
+
+    <para>
+        <code>Zend_Date</code>
+        también soporta nombres de meses abreviados en varios idiomas.
+        <code>Zend_Locale</code>
+        facilita la normalización de meses localizados y nombres de días
+        de la semana a timestamps, los cuales pueden, a su vez, ser
+        mostrados localizados a otras regiones.
+    </para>
+
+    <sect2 id="zend.date.setdefaulttimezone">
+
+        <title>Asigne Siempre una Zona Horaria por Defecto</title>
+
+        <para>
+            Antes de utilizar funciones relacionadas con fechas en PHP o
+            en el Zend Framework, primero debe asegurarse que su
+            aplicación tiene una zona horaria correcta por defecto,
+            configurando la variable de entorno TZ, usando el
+            parametro del php.ini
+            <code>date.timezone</code>
+            , o usando
+            <ulink url="http://php.net/date_default_timezone_set">
+                date_default_timezone_set()
+            </ulink>
+            . En PHP, podemos ajustar todas las funciones relacionadas
+            con fechas y hora para trabajar para un usuario particular
+            configurando por defecto una zona horaria de acuerdo a las
+            expectativas del usuario. Para una lista completa de
+            configuraciones de zona horaria, vea el siguiente link
+            <ulink url="http://unicode.org/cldr/data/diff/supplemental/territory_containment_un_m_49.html">
+                Lista de Identificadores de Zonas Horarias CLDR
+            </ulink>
+            .
+            <example id="zend.date.setdefaulttimezone.example-1">
+                <title>Configurando una Zona Horaria por Defecto</title>
+                <programlisting role="php"><![CDATA[
+                // zona horaria para un estadounidense en California
+date_default_timezone_set('America/Los_Angeles');
+// zona horaria para un alemán en Alemania
+date_default_timezone_set('Europe/Berlin');
+]]>
+                </programlisting>
+            </example>
+            <emphasis role="strong">¡Al crear instancias de Zend_Date, su zona horaria se convertirá automáticamente
+            en la zona horaria por defecto actual!</emphasis> De esta forma, la configuración de zona horaria tendrá
+            en cuenta cualquier cambio de hora de invierno/verano (Daylight Saving Time, DST), eliminando la necesidad
+            de especificarlo explícitamente.
+        </para>
+
+        <para>
+            Tenga en cuenta que las zonas horarias <emphasis role="strong">UTC</emphasis> y
+            <emphasis role="strong">GMT</emphasis> no incluyen el cambio de hora de invierno/verano (Daylight Saving Time, DST). 
+            Esto significa que aunque defina a mano que <code>Zend_Date</code> deba trabajar con DST, podría
+            ser anulado por las instancias de <code>Zend_Date</code> que han sido fijadas a
+            UTC o GMT.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.date.why">
+
+        <title>¿Por Qué Usar Zend_Date?</title>
+
+        <para>
+            <code>Zend_Date</code> ofrece las siguientes prestaciones, las cuales extienden el alcance de las funciones de fecha de PHP:
+        </para>
+
+        <itemizedlist mark="opencircle">
+            <listitem>
+                <para>
+                    API sencilla
+                </para>
+                <para>
+                    <code>Zend_Date</code> aporta una API muy sencilla, que combina lo mejor de la funcionalidad
+                    fecha/hora de cuatro lenguajes de programación. Es posible, por ejemplo, añadir o comparar dos horas 
+                    dentro de una misma columna.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Completamente internacionalizado
+                </para>
+                <para>
+                    Todos los nombres de meses y días de la semana completos y abreviados están incluidos para más de 130 idiomas.
+                    Los métodos admiten tanto entrada como salida de fechas usando los nombres localizados de meses y días de la semana.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Timestamps ilimitados
+                </para>
+                <para>
+                    A pesar de que la documentación de PHP 5.2 indice: "El intervalo de valores admitidos de timestamps es
+                    desde el 13 Dec 1901 20:45:54 GMT al 19 Ene 2038 03:14:07 GMT," <code>Zend_Date</code> admite un rango
+                    casi ilimitado, con la ayuda de la extensión BCMath. Si BCMath no está disponible, Zend_Date tendrá una 
+                    funcionalidad de timestamps reducida al rango del tipo <code>float</code> soportado por su servidor.
+                    El tamaño de un float es dependiente de la plataforma, aunque un máximo de ~1.8e308 con una precisión
+                    de cerca de 14 dígitos decimales es un valor habitual (formato 64 bit IEEE)." [
+                    <ulink url="http://www.php.net/float">http://www.php.net/float</ulink>
+                    ].  Adicionalmente, las limitaciones heredadas de los tipos de dato float, y errores de redondeo de números
+                    flotantes pueden introducir errores en los cálculos. Para evitar estos problemas, los componentes ZF I18n 
+                    usan la extensión BCMath, si está disponible.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Soporte para especificaciones de fecha ISO_8601
+                </para>
+                <para>
+                    Las especificaciones de fecha ISO_8601 están aceptadas. Incluso las especificaciones de fecha ISO_8601 
+                    parcialmente autorizadas serán identificadas. Estos formatos de fecha son particularmente útiles al
+                    trabajar con bases de datos. Por ejemplo, aunque MsSQL y 
+                    <ulink url="http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html">MySQL</ulink>
+                    difieren ligeramente uno de otro, ambos tienen soporte por parte de <code>Zend_Date</code> usando la constante 
+                    de especificación de formato 
+                    <link linkend="zend.date.constants.list">Zend_Date::ISO_8601</link>.
+                    Cuando las cadenas de fecha sean del tipo "Y/m/d" o "Y-m-d H:i:s", de acuerdo con los tokens de formato
+                    PHP date(), use el soporte integrado de Zend_Date para fechas formateadas ISO 8601.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Calcular amanecer y puesta de sol
+                </para>
+                <para>
+                    Las horas de amanecer y puesta de sol pueden mostrarse para cualquier lugar y día, para que no pierda ni un segundo de luz diurna 
+                    para trabajar en su proyecto PHP favorito :)
+                </para>
+            </listitem>
+        </itemizedlist>
+
+    </sect2>
+
+</sect1>
+<!--
+    vim:se ts=4 sw=4 et:
+-->

+ 2468 - 2468
documentation/manual/es/module_specs/Zend_Db_Adapter.xml

@@ -1,2468 +1,2468 @@
-<sect1 id="zend.db.adapter">
-
-    <title>Zend_Db_Adapter</title>
-
-    <para>
-        Zend_Db y sus clases relacionadas proporcionan una interfaz
-        simple de base de datos SQL para Zend Framework. El
-        Zend_Db_Adapter es la clase base que se utiliza para conectar su
-        aplicación PHP A una base de datos (RDBMS). Existen diferentes
-        clases Adapters(Adaptador) para cada tipo de base de datos
-        (RDBMS).
-    </para>
-
-    <para>
-        Las clases
-        <code>Adapters</code>
-        de Zend_Db crean un puente entre las extensiones de base de
-        datos de PHP hacia una interfaz común, para ayudarle a escribir
-        aplicaciones PHP una sola vez y poder desplegar múltiples
-        tipos de base de datos (RDBMS) con muy poco esfuerzo.
-    </para>
-
-    <para>
-        La Interfaz de la clase adaptador (adapter) es similar a la
-        intefaz de la extensión
-        <ulink url="http://www.php.net/pdo">PHP Data Objects</ulink>
-        . Zend_Db proporciona clases Adaptadoras para los drivers PDO de
-        los siguientes tipos de RDBMS:
-    </para>
-
-    <itemizedlist>
-        <listitem>
-            <para>
-                IBM DB2 e Informix Dynamic Server (IDS), usando la
-                extensión PHP
-                <ulink url="http://www.php.net/pdo-ibm">pdo_ibm</ulink>
-            </para>
-        </listitem>
-        <listitem>
-            <para>
-                MySQL, usando la extensión PHP
-                <ulink url="http://www.php.net/pdo-mysql">
-                    pdo_mysql
-                </ulink>
-            </para>
-        </listitem>
-        <listitem>
-            <para>
-                Microsoft SQL Server, usando la extensión PHP
-                <ulink url="http://www.php.net/pdo-mssql">
-                    pdo_mssql
-                </ulink>
-            </para>
-        </listitem>
-        <listitem>
-            <para>
-                Oracle, usando la extensión PHP
-                <ulink url="http://www.php.net/pdo-oci">pdo_oci</ulink>
-            </para>
-        </listitem>
-        <listitem>
-            <para>
-                PostgreSQL, usando la extensión PHP
-                <ulink url="http://www.php.net/pdo-pgsql">
-                    pdo_pgsql
-                </ulink>
-            </para>
-        </listitem>
-        <listitem>
-            <para>
-                SQLite, usando la extensión PHP
-                <ulink url="http://www.php.net/pdo-sqlite">
-                    pdo_sqlite
-                </ulink>
-            </para>
-        </listitem>
-
-    </itemizedlist>
-
-    <para>
-        Ademas, Zend_Db proporciona clases Adaptadoras que utilizan las
-        extensiones de base de datos de PHP de los siguientes tipos:
-    </para>
-
-    <itemizedlist>
-        <listitem>
-            <para>
-                MySQL, usando la extensión PHP
-                <ulink url="http://www.php.net/mysqli">mysqli</ulink>
-            </para>
-        </listitem>
-        <listitem>
-            <para>
-                Oracle, usando la extensión PHP
-                <ulink url="http://www.php.net/oci8">oci8</ulink>
-            </para>
-        </listitem>
-        <listitem>
-            <para>
-                IBM DB2, usando la extensión PHP
-                <ulink url="http://www.php.net/ibm_db2">ibm_db2</ulink>
-            </para>
-        </listitem>
-        <listitem>
-            <para>
-                Firebird/Interbase, usando la extensión PHP
-                <ulink url="http://www.php.net/ibase">
-                    php_interbase
-                </ulink>
-            </para>
-        </listitem>
-    </itemizedlist>
-
-    <note>
-        <para>
-            Cada Zend_Db_Adaptador utiliza una extensión PHP. Se debe de
-            tener habilitada la respectiva extensión en su entorno PHP
-            para utilizar un Zend_Db_Adapter. Por ejemplo, si se utiliza
-            una clase Zend_Db_Adapter basada en PDO, tiene que
-            habilitar tanto la extensión PDO como el driver PDO del tipo
-            de base de datos que se utiliza.
-
-        </para>
-    </note>
-
-    <sect2 id="zend.db.adapter.connecting">
-
-        <title>
-            Conexión a una Base de Datos utilizando un Adaptador
-        </title>
-
-        <para>
-            Esta sección describe cómo crear una instancia de un
-            Adaptador de base de datos. Esto corresponde a establecer
-            una conexión a un servidor de Base de Datos (RDBMS) desde su
-            aplicación PHP.
-        </para>
-
-        <sect3 id="zend.db.adapter.connecting.constructor">
-
-            <title>Usando un Constructor de Zend_Db Adapter</title>
-
-            <para>
-                Se puede crear una instancia de un Adaptador utilizando
-                su constructor. Un constructor de adaptador toma un
-                argumento, que es un conjunto de parámetros utilizados
-                para declarar la conexión.
-            </para>
-
-
-            <example id="zend.db.adapter.connecting.constructor.example">
-                <title>Usando el Constructor de un Adaptador</title>
-                <programlisting role="php"><![CDATA[
-$db = new Zend_Db_Adapter_Pdo_Mysql(array(
-    'host'     => '127.0.0.1',
-    'username' => 'webuser',
-    'password' => 'xxxxxxxx',
-    'dbname'   => 'test'
-));
-]]>
-                </programlisting>
-            </example>
-
-        </sect3>
-
-        <sect3 id="zend.db.adapter.connecting.factory">
-
-            <title>Usando el Factory de Zend_Db</title>
-
-            <para>
-                Como alternativa a la utilización directa del
-                constructor de un adaptador, se puede crear una
-                instancia del adaptador que use el método estático
-                <code>Zend_Db::factory()</code>
-                . Este método carga dinámicamente el archivo de clase
-                Adaptador bajo demanda, usando
-                <link linkend="zend.loader.load.class">
-                    Zend_Loader::loadClass()
-                </link>
-                .
-            </para>
-
-            <para>
-                El primer argumento es una cadena que nombra al nombre base
-                de la clase Adaptador. Por ejemplo, la cadena
-                'Pdo_Mysql' corresponde a la clase
-                Zend_Db_Adapter_Pdo_Mysql. El segundo argumento es el
-                mismo array de parámetros que hubiera enviado al
-                constructor del adaptador.
-            </para>
-
-
-
-
-
-            <example id="zend.db.adapter.connecting.factory.example">
-                <title>Usando el Adaptador del método factory</title>
-                <programlisting role="php"><![CDATA[
-// No necesitamos la siguiente declaración, porque 
-// el archivo Zend_Db_Adapter_Pdo_Mysql será cargado para nosotros por el método  
-// factory de Zend_Db.
-
-// require_once 'Zend/Db/Adapter/Pdo/Mysql.php';
-
-// carga automaticamente la clase Zend_Db_Adapter_Pdo_Mysql
-// y crea una instancia de la misma 
-$db = Zend_Db::factory('Pdo_Mysql', array(
-    'host'     => '127.0.0.1',
-    'username' => 'webuser',
-    'password' => 'xxxxxxxx',
-    'dbname'   => 'test'
-));
-]]>
-                </programlisting>
-            </example>
-
-            <para>
-            Si crea su propia clase que extiende a
-            Zend_Db_Adapter_Abstract, pero no nombra su clase con el prefijo
-            de paquete "Zend_Db_Adapter", se puede utilizar el método
-            <code>factory()</code>
-            para cargar su adaptador si se especifica la parte principal
-            de la clase del adaptador con la clave "adapterNamespace" en
-            el conjunto de parámetros
-            </para>
-        
-            <example id="zend.db.adapter.connecting.factory.example2">
-                <title>
-                    Usando el método factory para una clase Adaptador
-                    personalizada
-                </title>
-                <programlisting role="php"><![CDATA[
-// No tenemos que cargar el archivo de clase Adaptador 
-// porque será cargado para nosotros por el método factory de Zend_Db.
-
-// Automáticamente carga la clase MyProject_Db_Adapter_Pdo_Mysql
-// y crea una instancia de ella.
-
-$db = Zend_Db::factory('Pdo_Mysql', array(
-    'host'             => '127.0.0.1',
-    'username'         => 'webuser',
-    'password'         => 'xxxxxxxx',
-    'dbname'           => 'test',
-    'adapterNamespace' => 'MyProject_Db_Adapter'
-));
-]]>
-                </programlisting>
-            </example>
-
-        </sect3>
-
-        <sect3 id="zend.db.adapter.connecting.factory-config">
-
-            <title>Uso de Zend_Config con Zend_Db Factory</title>
-
-            <para>
-                Opcionalmente, se puede especificar cualquier
-                argumento del método
-                <code>factory()</code>
-                como un objeto de tipo
-                <link linkend="zend.config">Zend_Config</link>
-                .
-            </para>
-
-            <para>
-                Si el primer argumento es un objeto de configuración, se
-                espera que contenga una propiedad llamada
-                <code>adapter</code>
-                , conteniendo la cadena que da nombre al nombre base de la
-                clase de adaptador. Opcionalmente, el objeto puede
-                contener una propiedad llamada
-                <code>params</code>
-                , con subpropiedades correspondientes a nombres de parámetros
-                del adaptador. Esto es usado sólo si el segundo
-                argumento del método <code>factory()</code> se ha omitido.
-            </para>
-
-            <example id="zend.db.adapter.connecting.factory.example1">
-                <title>
-                    Uso del método factory del Adaptador con un objeto Zend_Config            
-                </title>
-                <para>
-                    En el siguiente ejemplo, un objeto Zend_Config es
-                    creado usando un array. También puedes cargar los datos de
-                    un archivo externo, por ejemplo con
-                    <link linkend="zend.config.adapters.ini">
-                        Zend_Config_Ini
-                    </link>
-                    o
-                    <link linkend="zend.config.adapters.xml">
-                        Zend_Config_Xml
-                    </link>
-                    .
-                </para>
-                <programlisting role="php"><![CDATA[
-$config = new Zend_Config(
-    array(
-        'database' => array(
-            'adapter' => 'Mysqli',
-            'params' => array(
-                'dbname' => 'test',
-                'username' => 'webuser',
-                'password' => 'secret',
-            )
-        )
-    )
-);
-
-$db = Zend_Db::factory($config->database);
-]]>
-                </programlisting>
-            </example>
-
-            <para>
-                El segundo argumento del método
-                <code>factory()</code>
-                puede ser un array asociativo con entradas
-                correspondientes a los parámetros del adaptador. Este argumento es
-                opcional. Si el primer argumento es de tipo Zend_Config,
-                se asume que tiene todos los parametros, y el segundo
-                argumento es ignorado.
-            </para>
-
-        </sect3>
-
-        <sect3 id="zend.db.adapter.connecting.parameters">
-
-            <title>Parámetros del Adaptador</title>
-
-            <para>
-                El siguiente listado explica parámetros comunes reconocidos por 
-                Adaptador de clases Zend_Db.
-            </para>
-
-            <itemizedlist>
-                <listitem>
-                    <para>
-                        <emphasis role="strong">host</emphasis>
-                        : una string conteniendo un nombre de host o dirección IP
-                        del servidor de base de datos. Si la base de datos está corriendo
-            sobre el mismo host que la aplicación PHP,
-                        usted puede utilizar 'localhost' o '127.0.0.1'.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        <emphasis role="strong">username</emphasis>
-                        : identificador de cuenta para autenticar una conexión al 
-            servidor RDBMS.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        <emphasis role="strong">password</emphasis>
-                        : la contraseña de la cuenta para la autenticación de credenciales
-            de conexión con el servidor RDBMS
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        <emphasis role="strong">dbname</emphasis>
-                        : nombre de la base de datos en el servidor RDBMS.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        <emphasis role="strong">port</emphasis>
-                        : algunos servidores RDBMS pueden aceptar conexiones de red
-                        sobre un número de puerto específico.
-            El parámetro del puerto le permite especificar el puerto al 
-            que su aplicación PHP se conecta, para que concuerde el puerto            
-            configurado en el servidor RDBMS.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        <emphasis role="strong">options</emphasis>
-                        : este parámetro es un array asociativo de
-                        opciones que son genéricas a todas las clases Zend_Db_Adapter.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        <emphasis role="strong">
-                            driver_options
-                        </emphasis>
-                        : este parámetro es un array asociativo de opciones adicionales
-                        para una extensión de base de datos dada.
-            un uso típico de este parámetro es establecer atributos 
-            de un driver PDO.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        <emphasis role="strong">
-                            adapterNamespace
-                        </emphasis>
-                        : nombre de la parte inicial del nombre de las clase para el
-            adaptador, en lugar de 'Zend_Db_Adapter'. Utilice 
-                        esto si usted necesita usar el método 
-                        <code>factory()</code>
-                        para cargar un adaptador de clase de base de datos que no sea 
-            de Zend.
-                    </para>
-                </listitem>
-            </itemizedlist>
-
-            <example id="zend.db.adapter.connecting.parameters.example1">
-                <title>
-                    Passing the case-folding option to the factory
-                </title>
-                <para>
-                    Usted puede pasar esta opción específica por la constante
-                    <code>Zend_Db::CASE_FOLDING</code>
-                    . Este corresponde al atributo
-                    <code>ATTR_CASE</code>
-                    en los drivers de base de datos PDO e IBM DB2,
-                    ajustando la sensibilidad de las claves tipo cadena en los resultados
-          de consultas. La opción toma los valores
-                    <code>Zend_Db::CASE_NATURAL</code>
-                    (el predeterminado),
-                    <code>Zend_Db::CASE_UPPER</code>
-                    , y
-                    <code>Zend_Db::CASE_LOWER</code>
-                    .
-                </para>
-                <programlisting role="php"><![CDATA[
-$options = array(
-    Zend_Db::CASE_FOLDING => Zend_Db::CASE_UPPER
-);
-
-$params = array(
-    'host'           => '127.0.0.1',
-    'username'       => 'webuser',
-    'password'       => 'xxxxxxxx',
-    'dbname'         => 'test',
-    'options'        => $options
-);
-
-$db = Zend_Db::factory('Db2', $params);
-]]>
-                </programlisting>
-            </example>
-
-            <example id="zend.db.adapter.connecting.parameters.example2">
-                <title>
-                    Passing the auto-quoting option to the factory
-                </title>
-                <para>
-                    Usted puede especificar esta opción por la constante
-                    <code>Zend_Db::AUTO_QUOTE_IDENTIFIERS</code>
-                    . Si el valor es 
-                    <code>true</code>
-                    (el predeterminado), los identificadores como nombres de tabla,
-          nombres de columna, e incluso los alias son delimitados en la
-          sintaxis SQL generada por el Adatador del objeto.
-          Esto hace que sea sencillo utilizar identificadores que contengan 
-          palabras reservadas de SQL, o caracteres especiales. Si el valor es 
-                    <code>false</code>
-                    , los identificadores no son delimitados automáticamente. Si 
-                    usted necesita delimitar identificadores, debe hacer usted mismo 
-          utilizando el método
-                    <code>quoteIdentifier()</code>
-                    .
-                </para>
-                <programlisting role="php"><![CDATA[
-$options = array(
-    Zend_Db::AUTO_QUOTE_IDENTIFIERS => false
-);
-
-$params = array(
-    'host'           => '127.0.0.1',
-    'username'       => 'webuser',
-    'password'       => 'xxxxxxxx',
-    'dbname'         => 'test',
-    'options'        => $options
-);
-
-$db = Zend_Db::factory('Pdo_Mysql', $params);
-]]>
-                </programlisting>
-            </example>
-
-            <example id="zend.db.adapter.connecting.parameters.example3">
-                <title>Passing PDO driver options to the factory</title>
-                <programlisting role="php"><![CDATA[
-$pdoParams = array(
-    PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true
-);
-
-$params = array(
-    'host'           => '127.0.0.1',
-    'username'       => 'webuser',
-    'password'       => 'xxxxxxxx',
-    'dbname'         => 'test',
-    'driver_options' => $pdoParams
-);
-
-$db = Zend_Db::factory('Pdo_Mysql', $params);
-
-echo $db->getConnection()
-        ->getAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY);
-]]>
-                </programlisting>
-            </example>
-
-        </sect3>
-
-        <sect3 id="zend.db.adapter.connecting.getconnection">
-            <title>Managing Lazy Connections</title>
-
-            <para>
-                Creating an instance of an Adapter class does not
-                immediately connect to the RDBMS server. The Adapter
-                saves the connection parameters, and makes the actual
-                connection on demand, the first time you need to execute
-                a query. This ensures that creating an Adapter object is
-                quick and inexpensive. You can create an instance of an
-                Adapter even if you are not certain that you need to run
-                any database queries during the current request your
-                application is serving.
-            </para>
-
-            <para>
-                If you need to force the Adapter to connect to the
-                RDBMS, use the
-                <code>getConnection()</code>
-                method. This method returns an object for the connection
-                as represented by the respective PHP database extension.
-                For example, if you use any of the Adapter classes for
-                PDO drivers, then
-                <code>getConnection()</code>
-                returns the PDO object, after initiating it as a live
-                connection to the specific database.
-            </para>
-
-            <para>
-                It can be useful to force the connection if you want to
-                catch any exceptions it throws as a result of invalid
-                account credentials, or other failure to connect to the
-                RDBMS server. These exceptions are not thrown until the
-                connection is made, so it can help simplify your
-                application code if you handle the exceptions in one
-                place, instead of at the time of the first query against
-                the database.
-            </para>
-
-            <example id="zend.db.adapter.connecting.getconnection.example">
-                <title>Handling connection exceptions</title>
-                <programlisting role="php"><![CDATA[
-try {
-    $db = Zend_Db::factory('Pdo_Mysql', $parameters);
-    $db->getConnection();
-} catch (Zend_Db_Adapter_Exception $e) {
-    // perhaps a failed login credential, or perhaps the RDBMS is not running
-} catch (Zend_Exception $e) {
-    // perhaps factory() failed to load the specified Adapter class
-}
-]]>
-                </programlisting>
-            </example>
-
-        </sect3>
-
-    </sect2>
-
-    <sect2 id="zend.db.adapter.example-database">
-
-        <title>La base de datos de ejemplo</title>
-
-        <para>
-            En la documentación de las clases Zend_Db, usamos un
-            conjunto sencillo de tablas para ilustrar el uso de las
-            clases y métodos. Estas tablas de ejemplo permiten almacenar
-            información para localizar bugs en un proyecto de desarrollo
-            de software. La base de datos contiene cuatro tablas:
-        </para>
-
-        <itemizedlist>
-            <listitem>
-                <para>
-                    <emphasis role="strong">accounts</emphasis>
-                    almacena información sobre cada usuario que hace el
-                    seguimiento de bugs.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                    <emphasis role="strong">products</emphasis>
-                    almacena información sobre cada producto para el que
-                    pueden registrarse bugs.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                    <emphasis role="strong">bugs</emphasis>
-                    almacena información sobre bugs, incluyendo el
-                    estado actual del bug, la persona que informó sobre
-                    el bug, la persona que está asignada para corregir
-                    el bug, y la persona que está asignada para
-                    verificar la corrección.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                    <emphasis role="strong">bugs_products</emphasis>
-                    stores a relationship between bugs and products.
-                    This implements a many-to-many relationship, because
-                    a given bug may be relevant to multiple products,
-                    and of course a given product can have multiple
-                    bugs.
-                </para>
-            </listitem>
-        </itemizedlist>
-
-        <para>
-            La siguiente definición de datos SQL en lenguaje
-            pseudocódigo describe las tablas de esta base de datos de
-            ejemplo. Estas tablas de ejemplo son usadas ampliamente por
-            los tests unitarios automatizados de Zend_Db.
-        </para>
-
-        <programlisting role="sql"><![CDATA[
-CREATE TABLE accounts (
-  account_name      VARCHAR(100) NOT NULL PRIMARY KEY
-);
-
-CREATE TABLE products (
-  product_id        INTEGER NOT NULL PRIMARY KEY,
-  product_name      VARCHAR(100)
-);
-
-CREATE TABLE bugs (
-  bug_id            INTEGER NOT NULL PRIMARY KEY,
-  bug_description   VARCHAR(100),
-  bug_status        VARCHAR(20),
-  reported_by       VARCHAR(100) REFERENCES accounts(account_name),
-  assigned_to       VARCHAR(100) REFERENCES accounts(account_name),
-  verified_by       VARCHAR(100) REFERENCES accounts(account_name)
-);
-
-CREATE TABLE bugs_products (
-  bug_id            INTEGER NOT NULL REFERENCES bugs,
-  product_id        INTEGER NOT NULL REFERENCES products,
-  PRIMARY KEY       (bug_id, product_id)
-);
-]]>
-        </programlisting>
-
-        <para>
-            Also notice that the
-            <code>bugs</code>
-            table contains multiple foreign key references to the
-            <code>accounts</code>
-            table. Each of these foreign keys may reference a different
-            row in the
-            <code>accounts</code>
-            table for a given bug.
-        </para>
-
-        <para>
-            The diagram below illustrates the physical data model of the
-            example database.
-        </para>
-
-        <para>
-            <inlinegraphic width="387" scale="100" align="center" valign="middle" fileref="figures/zend.db.adapter.example-database.png" format="PNG"></inlinegraphic>
-        </para>
-
-    </sect2>
-
-    <sect2 id="zend.db.adapter.select">
-
-        <title>Reading Query Results</title>
-
-        <para>
-            This section describes methods of the Adapter class with
-            which you can run SELECT queries and retrieve the query
-            results.
-        </para>
-
-        <sect3 id="zend.db.adapter.select.fetchall">
-
-            <title>Fetching a Complete Result Set</title>
-
-            <para>
-                You can run a SQL SELECT query and retrieve its results
-                in one step using the
-                <code>fetchAll()</code>
-                method.
-            </para>
-
-            <para>
-                The first argument to this method is a string containing
-                a SELECT statement. Alternatively, the first argument
-                can be an object of class
-                <link linkend="zend.db.select">Zend_Db_Select</link>
-                . The Adapter automatically converts this object to a
-                string representation of the SELECT statement.
-            </para>
-
-            <para>
-                The second argument to
-                <code>fetchAll()</code>
-                is an array of values to substitute for parameter
-                placeholders in the SQL statement.
-            </para>
-
-            <example id="zend.db.adapter.select.fetchall.example">
-                <title>Using fetchAll()</title>
-                <programlisting role="php"><![CDATA[
-$sql = 'SELECT * FROM bugs WHERE bug_id = ?';
-
-$result = $db->fetchAll($sql, 2);
-]]>
-                </programlisting>
-            </example>
-
-        </sect3>
-
-        <sect3 id="zend.db.adapter.select.fetch-mode">
-
-            <title>Changing the Fetch Mode</title>
-
-            <para>
-                By default,
-                <code>fetchAll()</code>
-                returns an array of rows, each of which is an
-                associative array. The keys of the associative array are
-                the columns or column aliases named in the select query.
-            </para>
-
-            <para>
-                You can specify a different style of fetching results
-                using the
-                <code>setFetchMode()</code>
-                method. The modes supported are identified by constants:
-            </para>
-
-            <itemizedlist>
-                <listitem>
-                    <para>
-                        <emphasis role="strong">
-                            Zend_Db::FETCH_ASSOC
-                        </emphasis>
-                        : return data in an array of associative arrays.
-                        The array keys are column names, as strings.
-                        This is the default fetch mode for
-                        Zend_Db_Adapter classes.
-                    </para>
-                    <para>
-                        Note that if your select-list contains more than
-                        one column with the same name, for example if
-                        they are from two different tables in a JOIN,
-                        there can be only one entry in the associative
-                        array for a given name. If you use the
-                        FETCH_ASSOC mode, you should specify column
-                        aliases in your SELECT query to ensure that the
-                        names result in unique array keys.
-                    </para>
-                    <para>
-                        By default, these strings are returned as they
-                        are returned by the database driver. This is
-                        typically the spelling of the column in the
-                        RDBMS server. You can specify the case for these
-                        strings, using the
-                        <code>Zend_Db::CASE_FOLDING</code>
-                        option. Specify this when instantiating the
-                        Adapter. See
-                        <xref linkend="zend.db.adapter.connecting.parameters.example1"></xref>
-                        .
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        <emphasis role="strong">
-                            Zend_Db::FETCH_NUM
-                        </emphasis>
-                        : return data in an array of arrays. The arrays
-                        are indexed by integers, corresponding to the
-                        position of the respective field in the
-                        select-list of the query.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        <emphasis role="strong">
-                            Zend_Db::FETCH_BOTH
-                        </emphasis>
-                        : return data in an array of arrays. The array
-                        keys are both strings as used in the FETCH_ASSOC
-                        mode, and integers as used in the FETCH_NUM
-                        mode. Note that the number of elements in the
-                        array is double that which would be in the array
-                        if you used either FETCH_ASSOC or FETCH_NUM.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        <emphasis role="strong">
-                            Zend_Db::FETCH_COLUMN
-                        </emphasis>
-                        : return data in an array of values. The value
-                        in each array is the value returned by one
-                        column of the result set. By default, this is
-                        the first column, indexed by 0.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        <emphasis role="strong">
-                            Zend_Db::FETCH_OBJ
-                        </emphasis>
-                        : return data in an array of objects. The
-                        default class is the PHP built-in class
-                        stdClass. Columns of the result set are
-                        available as public properties of the object.
-                    </para>
-                </listitem>
-            </itemizedlist>
-
-            <example id="zend.db.adapter.select.fetch-mode.example">
-                <title>Using setFetchMode()</title>
-                <programlisting role="php"><![CDATA[
-$db->setFetchMode(Zend_Db::FETCH_OBJ);
-
-$result = $db->fetchAll('SELECT * FROM bugs WHERE bug_id = ?', 2);
-
-// $result is an array of objects
-echo $result[0]->bug_description;
-]]>
-                </programlisting>
-            </example>
-
-        </sect3>
-
-        <sect3 id="zend.db.adapter.select.fetchassoc">
-
-            <title>Fetching a Result Set as an Associative Array</title>
-
-            <para>
-                The
-                <code>fetchAssoc()</code>
-                method returns data in an array of associative arrays,
-                regardless of what value you have set for the fetch
-                mode.
-            </para>
-
-            <example id="zend.db.adapter.select.fetchassoc.example">
-                <title>Using fetchAssoc()</title>
-                <programlisting role="php"><![CDATA[
-$db->setFetchMode(Zend_Db::FETCH_OBJ);
-
-$result = $db->fetchAssoc('SELECT * FROM bugs WHERE bug_id = ?', 2);
-
-// $result is an array of associative arrays, in spite of the fetch mode
-echo $result[0]['bug_description'];
-]]>
-                </programlisting>
-            </example>
-
-        </sect3>
-
-        <sect3 id="zend.db.adapter.select.fetchcol">
-
-            <title>Fetching a Single Column from a Result Set</title>
-
-            <para>
-                The
-                <code>fetchCol()</code>
-                method returns data in an array of values, regardless of
-                the value you have set for the fetch mode. This only
-                returns the first column returned by the query. Any
-                other columns returned by the query are discarded. If
-                you need to return a column other than the first, see
-                <xref linkend="zend.db.statement.fetching.fetchcolumn"></xref>
-                .
-            </para>
-
-            <example id="zend.db.adapter.select.fetchcol.example">
-                <title>Using fetchCol()</title>
-                <programlisting role="php"><![CDATA[
-$db->setFetchMode(Zend_Db::FETCH_OBJ);
-
-$result = $db->fetchCol(
-    'SELECT bug_description, bug_id FROM bugs WHERE bug_id = ?', 2);
-
-// contains bug_description; bug_id is not returned
-echo $result[0];
-]]>
-                </programlisting>
-            </example>
-
-        </sect3>
-
-        <sect3 id="zend.db.adapter.select.fetchpairs">
-
-            <title>Fetching Key-Value Pairs from a Result Set</title>
-
-            <para>
-                The
-                <code>fetchPairs()</code>
-                method returns data in an array of key-value pairs, as
-                an associative array with a single entry per row. The
-                key of this associative array is taken from the first
-                column returned by the SELECT query. The value is taken
-                from the second column returned by the SELECT query. Any
-                other columns returned by the query are discarded.
-            </para>
-
-            <para>
-                You should design the SELECT query so that the first
-                column returned has unique values. If there are
-                duplicates values in the first column, entries in the
-                associative array will be overwritten.
-            </para>
-
-            <example id="zend.db.adapter.select.fetchpairs.example">
-                <title>Using fetchPairs()</title>
-                <programlisting role="php"><![CDATA[
-$db->setFetchMode(Zend_Db::FETCH_OBJ);
-
-$result = $db->fetchPairs('SELECT bug_id, bug_status FROM bugs');
-
-echo $result[2];
-]]>
-                </programlisting>
-            </example>
-        </sect3>
-
-        <sect3 id="zend.db.adapter.select.fetchrow">
-
-            <title>Fetching a Single Row from a Result Set</title>
-
-            <para>
-                The
-                <code>fetchRow()</code>
-                method returns data using the current fetch mode, but it
-                returns only the first row fetched from the result set.
-            </para>
-
-            <example id="zend.db.adapter.select.fetchrow.example">
-                <title>Using fetchRow()</title>
-                <programlisting role="php"><![CDATA[
-$db->setFetchMode(Zend_Db::FETCH_OBJ);
-
-$result = $db->fetchRow('SELECT * FROM bugs WHERE bug_id = 2');
-
-// note that $result is a single object, not an array of objects
-echo $result->bug_description;
-]]>
-                </programlisting>
-            </example>
-        </sect3>
-
-        <sect3 id="zend.db.adapter.select.fetchone">
-
-            <title>Fetching a Single Scalar from a Result Set</title>
-
-            <para>
-                The
-                <code>fetchOne()</code>
-                method is like a combination of
-                <code>fetchRow()</code>
-                with
-                <code>fetchCol()</code>
-                , in that it returns data only for the first row fetched
-                from the result set, and it returns only the value of
-                the first column in that row. Therefore it returns only
-                a single scalar value, not an array or an object.
-            </para>
-
-            <example id="zend.db.adapter.select.fetchone.example">
-                <title>Using fetchOne()</title>
-                <programlisting role="php"><![CDATA[
-$result = $db->fetchOne('SELECT bug_status FROM bugs WHERE bug_id = 2');
-
-// this is a single string value
-echo $result;
-]]>
-                </programlisting>
-            </example>
-        </sect3>
-
-    </sect2>
-
-    <sect2 id="zend.db.adapter.write">
-
-        <title>Writing Changes to the Database</title>
-
-        <para>
-            You can use the Adapter class to write new data or change
-            existing data in your database. This section describes
-            methods to do these operations.
-        </para>
-
-        <sect3 id="zend.db.adapter.write.insert">
-
-            <title>Inserting Data</title>
-
-            <para>
-                You can add new rows to a table in your database using
-                the
-                <code>insert()</code>
-                method. The first argument is a string that names the
-                table, and the second argument is an associative array,
-                mapping column names to data values.
-            </para>
-
-            <example id="zend.db.adapter.write.insert.example">
-                <title>Inserting to a table</title>
-                <programlisting role="php"><![CDATA[
-$data = array(
-    'created_on'      => '2007-03-22',
-    'bug_description' => 'Something wrong',
-    'bug_status'      => 'NEW'
-);
-
-$db->insert('bugs', $data);
-]]>
-                </programlisting>
-            </example>
-
-            <para>
-                Columns you exclude from the array of data are not
-                specified to the database. Therefore, they follow the
-                same rules that an SQL INSERT statement follows: if the
-                column has a DEFAULT clause, the column takes that value
-                in the row created, otherwise the column is left in a
-                NULL state.
-            </para>
-
-            <para>
-                By default, the values in your data array are inserted
-                using parameters. This reduces risk of some types of
-                security issues. You don't need to apply escaping or
-                quoting to values in the data array.
-            </para>
-
-            <para>
-                You might need values in the data array to be treated as
-                SQL expressions, in which case they should not be
-                quoted. By default, all data values passed as strings
-                are treated as string literals. To specify that the
-                value is an SQL expression and therefore should not be
-                quoted, pass the value in the data array as an object of
-                type Zend_Db_Expr instead of a plain string.
-            </para>
-
-            <example id="zend.db.adapter.write.insert.example2">
-                <title>Inserting expressions to a table</title>
-                <programlisting role="php"><![CDATA[
-$data = array(
-    'created_on'      => new Zend_Db_Expr('CURDATE()'),
-    'bug_description' => 'Something wrong',
-    'bug_status'      => 'NEW'
-);
-
-$db->insert('bugs', $data);
-]]>
-                </programlisting>
-            </example>
-
-        </sect3>
-
-        <sect3 id="zend.db.adapter.write.lastinsertid">
-
-            <title>Retrieving a Generated Value</title>
-
-            <para>
-                Some RDBMS brands support auto-incrementing primary
-                keys. A table defined this way generates a primary key
-                value automatically during an INSERT of a new row. The
-                return value of the
-                <code>insert()</code>
-                method is
-                <emphasis>not</emphasis>
-                the last inserted ID, because the table might not have
-                an auto-incremented column. Instead, the return value is
-                the number of rows affected (usually 1).
-            </para>
-
-            <para>
-                If your table is defined with an auto-incrementing
-                primary key, you can call the
-                <code>lastInsertId()</code>
-                method after the insert. This method returns the last
-                value generated in the scope of the current database
-                connection.
-            </para>
-
-            <example id="zend.db.adapter.write.lastinsertid.example-1">
-                <title>
-                    Using lastInsertId() for an auto-increment key
-                </title>
-                <programlisting role="php"><![CDATA[
-$db->insert('bugs', $data);
-
-// return the last value generated by an auto-increment column
-$id = $db->lastInsertId();
-]]>
-                </programlisting>
-            </example>
-
-            <para>
-                Some RDBMS brands support a sequence object, which
-                generates unique values to serve as primary key values.
-                To support sequences, the
-                <code>lastInsertId()</code>
-                method accepts two optional string arguments. These
-                arguments name the table and the column, assuming you
-                have followed the convention that a sequence is named
-                using the table and column names for which the sequence
-                generates values, and a suffix "_seq". This is based on
-                the convention used by PostgreSQL when naming sequences
-                for SERIAL columns. For example, a table "bugs" with
-                primary key column "bug_id" would use a sequence named
-                "bugs_bug_id_seq".
-            </para>
-
-            <example id="zend.db.adapter.write.lastinsertid.example-2">
-                <title>Using lastInsertId() for a sequence</title>
-                <programlisting role="php"><![CDATA[
-$db->insert('bugs', $data);
-
-// return the last value generated by sequence 'bugs_bug_id_seq'.
-$id = $db->lastInsertId('bugs', 'bug_id');
-
-// alternatively, return the last value generated by sequence 'bugs_seq'.
-$id = $db->lastInsertId('bugs');
-]]>
-                </programlisting>
-            </example>
-
-            <para>
-                If the name of your sequence object does not follow this
-                naming convention, use the
-                <code>lastSequenceId()</code>
-                method instead. This method takes a single string
-                argument, naming the sequence literally.
-            </para>
-
-            <example id="zend.db.adapter.write.lastinsertid.example-3">
-                <title>Using lastSequenceId()</title>
-                <programlisting role="php"><![CDATA[
-$db->insert('bugs', $data);
-
-// return the last value generated by sequence 'bugs_id_gen'.
-$id = $db->lastSequenceId('bugs_id_gen');
-]]>
-                </programlisting>
-            </example>
-
-            <para>
-                For RDBMS brands that don't support sequences, including
-                MySQL, Microsoft SQL Server, and SQLite, the arguments
-                to the lastInsertId() method are ignored, and the value
-                returned is the most recent value generated for any
-                table by INSERT operations during the current
-                connection. For these RDBMS brands, the lastSequenceId()
-                method always returns
-                <code>null</code>
-                .
-            </para>
-
-            <note>
-                <title>Why not use "SELECT MAX(id) FROM table"?</title>
-                <para>
-                    Sometimes this query returns the most recent primary
-                    key value inserted into the table. However, this
-                    technique is not safe to use in an environment where
-                    multiple clients are inserting records to the
-                    database. It is possible, and therefore is bound to
-                    happen eventually, that another client inserts
-                    another row in the instant between the insert
-                    performed by your client application and your query
-                    for the MAX(id) value. Thus the value returned does
-                    not identify the row you inserted, it identifies the
-                    row inserted by some other client. There is no way
-                    to know when this has happened.
-                </para>
-                <para>
-                    Using a strong transaction isolation mode such as
-                    "repeatable read" can mitigate this risk, but some
-                    RDBMS brands don't support the transaction isolation
-                    required for this, or else your application may use
-                    a lower transaction isolation mode by design.
-                </para>
-                <para>
-                    Furthermore, using an expression like "MAX(id)+1" to
-                    generate a new value for a primary key is not safe,
-                    because two clients could do this query
-                    simultaneously, and then both use the same
-                    calculated value for their next INSERT operation.
-                </para>
-                <para>
-                    All RDBMS brands provide mechanisms to generate
-                    unique values, and to return the last value
-                    generated. These mechanisms necessarily work outside
-                    of the scope of transaction isolation, so there is
-                    no chance of two clients generating the same value,
-                    and there is no chance that the value generated by
-                    another client could be reported to your client's
-                    connection as the last value generated.
-                </para>
-            </note>
-
-        </sect3>
-
-        <sect3 id="zend.db.adapter.write.update">
-            <title>Updating Data</title>
-
-            <para>
-                You can update rows in a database table using the
-                <code>update()</code>
-                method of an Adapter. This method takes three arguments:
-                the first is the name of the table; the second is an
-                associative array mapping columns to change to new
-                values to assign to these columns.
-            </para>
-
-            <para>
-                The values in the data array are treated as string
-                literals. See
-                <xref linkend="zend.db.adapter.write.insert"></xref>
-                for information on using SQL expressions in the data
-                array.
-            </para>
-
-            <para>
-                The third argument is a string containing an SQL
-                expression that is used as criteria for the rows to
-                change. The values and identifiers in this argument are
-                not quoted or escaped. You are responsible for ensuring
-                that any dynamic content is interpolated into this
-                string safely. See
-                <xref linkend="zend.db.adapter.quoting"></xref>
-                for methods to help you do this.
-            </para>
-
-            <para>
-                The return value is the number of rows affected by the
-                update operation.
-            </para>
-
-            <example id="zend.db.adapter.write.update.example">
-                <title>Updating rows</title>
-                <programlisting role="php"><![CDATA[
-$data = array(
-    'updated_on'      => '2007-03-23',
-    'bug_status'      => 'FIXED'
-);
-
-$n = $db->update('bugs', $data, 'bug_id = 2');
-]]>
-                </programlisting>
-            </example>
-
-            <para>
-                If you omit the third argument, then all rows in the
-                database table are updated with the values specified in
-                the data array.
-            </para>
-
-            <para>
-                If you provide an array of strings as the third
-                argument, these strings are joined together as terms in
-                an expression separated by
-                <code>AND</code>
-                operators.
-            </para>
-
-            <example id="zend.db.adapter.write.update.example-array">
-                <title>
-                    Updating rows using an array of expressions
-                </title>
-                <programlisting role="php"><![CDATA[
-$data = array(
-    'updated_on'      => '2007-03-23',
-    'bug_status'      => 'FIXED'
-);
-
-$where[] = "reported_by = 'goofy'";
-$where[] = "bug_status = 'OPEN'";
-
-$n = $db->update('bugs', $data, $where);
-
-// Resulting SQL is:
-//  UPDATE "bugs" SET "update_on" = '2007-03-23', "bug_status" = 'FIXED'
-//  WHERE ("reported_by" = 'goofy') AND ("bug_status" = 'OPEN')
-]]>
-                </programlisting>
-            </example>
-
-        </sect3>
-
-        <sect3 id="zend.db.adapter.write.delete">
-            <title>Deleting Data</title>
-            <para>
-                You can delete rows from a database table using the
-                <code>delete()</code>
-                method. This method takes two arguments: the first is a
-                string naming the table.
-            </para>
-
-            <para>
-                The second argument is a string containing an SQL
-                expression that is used as criteria for the rows to
-                delete. The values and identifiers in this argument are
-                not quoted or escaped. You are responsible for ensuring
-                that any dynamic content is interpolated into this
-                string safely. See
-                <xref linkend="zend.db.adapter.quoting"></xref>
-                for methods to help you do this.
-            </para>
-
-            <para>
-                The return value is the number of rows affected by the
-                delete operation.
-            </para>
-
-            <example id="zend.db.adapter.write.delete.example">
-                <title>Deleting rows</title>
-                <programlisting role="php"><![CDATA[
-$n = $db->delete('bugs', 'bug_id = 3');
-]]>
-                </programlisting>
-            </example>
-
-            <para>
-                If you omit the second argument, the result is that all
-                rows in the database table are deleted.
-            </para>
-
-            <para>
-                If you provide an array of strings as the second
-                argument, these strings are joined together as terms in
-                an expression separated by
-                <code>AND</code>
-                operators.
-            </para>
-
-        </sect3>
-
-    </sect2>
-
-    <sect2 id="zend.db.adapter.quoting">
-
-        <title>Quoting Values and Identifiers</title>
-
-        <para>
-            When you form SQL queries, often it is the case that you
-            need to include the values of PHP variables in SQL
-            expressions. This is risky, because if the value in a PHP
-            string contains certain symbols, such as the quote symbol,
-            it could result in invalid SQL. For example, notice the
-            imbalanced quote characters in the following query:
-            <programlisting role="php"><![CDATA[
-$name = "O'Reilly";
-$sql = "SELECT * FROM bugs WHERE reported_by = '$name'";
-
-echo $sql;
-// SELECT * FROM bugs WHERE reported_by = 'O'Reilly'
-]]>
-            </programlisting>
-        </para>
-
-        <para>
-            Even worse is the risk that such code mistakes might be
-            exploited deliberately by a person who is trying to
-            manipulate the function of your web application. If they can
-            specify the value of a PHP variable through the use of an
-            HTTP parameter or other mechanism, they might be able to
-            make your SQL queries do things that you didn't intend them
-            to do, such as return data to which the person should not
-            have privilege to read. This is a serious and widespread
-            technique for violating application security, known as "SQL
-            Injection" (see
-            <ulink url="http://en.wikipedia.org/wiki/SQL_Injection">
-                http://en.wikipedia.org/wiki/SQL_Injection
-            </ulink>
-            ).
-        </para>
-
-        <para>
-            The Zend_Db Adapter class provides convenient functions to
-            help you reduce vulnerabilities to SQL Injection attacks in
-            your PHP code. The solution is to escape special characters
-            such as quotes in PHP values before they are interpolated
-            into your SQL strings. This protects against both accidental
-            and deliberate manipulation of SQL strings by PHP variables
-            that contain special characters.
-        </para>
-
-        <sect3 id="zend.db.adapter.quoting.quote">
-
-            <title>
-                Using
-                <code>quote()</code>
-            </title>
-
-            <para>
-                The
-                <code>quote()</code>
-                method accepts a single argument, a scalar string value.
-                It returns the value with special characters escaped in
-                a manner appropriate for the RDBMS you are using, and
-                surrounded by string value delimiters. The standard SQL
-                string value delimiter is the single-quote (
-                <code>'</code>
-                ).
-            </para>
-
-            <example id="zend.db.adapter.quoting.quote.example">
-                <title>Using quote()</title>
-                <programlisting role="php"><![CDATA[
-$name = $db->quote("O'Reilly");
-echo $name;
-// 'O\'Reilly'
-
-$sql = "SELECT * FROM bugs WHERE reported_by = $name";
-
-echo $sql;
-// SELECT * FROM bugs WHERE reported_by = 'O\'Reilly'
-]]>
-                </programlisting>
-            </example>
-
-            <para>
-                Note that the return value of
-                <code>quote()</code>
-                includes the quote delimiters around the string. This is
-                different from some functions that escape special
-                characters but do not add the quote delimiters, for
-                example
-                <ulink url="http://www.php.net/mysqli_real_escape_string">
-                    mysql_real_escape_string()
-                </ulink>
-                .
-            </para>
-
-            <para>
-                Values may need to be quoted or not quoted according to
-                the SQL datatype context in which they are used. For
-                instance, in some RDBMS brands, an integer value must
-                not be quoted as a string if it is compared to an
-                integer-type column or expression. In other words, the
-                following is an error in some SQL implementations,
-                assuming
-                <code>intColumn</code>
-                has a SQL datatype of
-                <code>INTEGER</code>
-
-                <programlisting role="php"><![CDATA[
-SELECT * FROM atable WHERE intColumn = '123'
-]]>
-                </programlisting>
-            </para>
-
-            <para>
-                You can use the optional second argument to the
-                <code>quote()</code>
-                method to apply quoting selectively for the SQL datatype
-                you specify.
-            </para>
-
-            <example id="zend.db.adapter.quoting.quote.example-2">
-                <title>Using quote() with a SQL type</title>
-                <programlisting role="php"><![CDATA[
-$value = '1234';
-$sql = 'SELECT * FROM atable WHERE intColumn = '
-     . $db->quote($value, 'INTEGER');
-]]>
-                </programlisting>
-            </example>
-
-            <para>
-                Each Zend_Db_Adapter class has encoded the names of
-                numeric SQL datatypes for the respective brand of RDBMS.
-                You can also use the constants
-                <code>Zend_Db::INT_TYPE</code>
-                ,
-                <code>Zend_Db::BIGINT_TYPE</code>
-                , and
-                <code>Zend_Db::FLOAT_TYPE</code>
-                to write code in a more RDBMS-independent way.
-            </para>
-
-            <para>
-                Zend_Db_Table specifies SQL types to
-                <code>quote()</code>
-                automatically when generating SQL queries that reference
-                a table's key columns.
-            </para>
-
-        </sect3>
-
-        <sect3 id="zend.db.adapter.quoting.quote-into">
-
-            <title>
-                Using
-                <code>quoteInto()</code>
-            </title>
-
-            <para>
-                The most typical usage of quoting is to interpolate a
-                PHP variable into a SQL expression or statement. You can
-                use the
-                <code>quoteInto()</code>
-                method to do this in one step. This method takes two
-                arguments: the first argument is a string containing a
-                placeholder symbol (
-                <code>?</code>
-                ), and the second argument is a value or PHP variable
-                that should be substituted for that placeholder.
-            </para>
-
-            <para>
-                The placeholder symbol is the same symbol used by many
-                RDBMS brands for positional parameters, but the
-                <code>quoteInto()</code>
-                method only emulates query parameters. The method simply
-                interpolates the value into the string, escapes special
-                characters, and applies quotes around it. True query
-                parameters maintain the separation between the SQL
-                string and the parameters as the statement is parsed in
-                the RDBMS server.
-            </para>
-
-            <example id="zend.db.adapter.quoting.quote-into.example">
-                <title>Using quoteInto()</title>
-                <programlisting role="php"><![CDATA[
-$sql = $db->quoteInto("SELECT * FROM bugs WHERE reported_by = ?", "O'Reilly");
-
-echo $sql;
-// SELECT * FROM bugs WHERE reported_by = 'O\'Reilly'
-]]>
-                </programlisting>
-            </example>
-
-            <para>
-                You can use the optional third parameter of
-                <code>quoteInto()</code>
-                to specify the SQL datatype. Numeric datatypes are not
-                quoted, and other types are quoted.
-            </para>
-
-            <example id="zend.db.adapter.quoting.quote-into.example-2">
-                <title>Using quoteInto() with a SQL type</title>
-                <programlisting role="php"><![CDATA[
-$sql = $db
-    ->quoteInto("SELECT * FROM bugs WHERE bug_id = ?", '1234', 'INTEGER');
-
-echo $sql;
-// SELECT * FROM bugs WHERE reported_by = 1234
-]]>
-                </programlisting>
-            </example>
-
-        </sect3>
-        <sect3 id="zend.db.adapter.quoting.quote-identifier">
-
-            <title>
-                Using
-                <code>quoteIdentifier()</code>
-            </title>
-
-            <para>
-                Values are not the only part of SQL syntax that might
-                need to be variable. If you use PHP variables to name
-                tables, columns, or other identifiers in your SQL
-                statements, you might need to quote these strings too.
-                By default, SQL identifiers have syntax rules like PHP
-                and most other programming languages. For example,
-                identifiers should not contain spaces, certain
-                punctuation or special characters, or international
-                characters. Also certain words are reserved for SQL
-                syntax, and should not be used as identifiers.
-            </para>
-
-            <para>
-                However, SQL has a feature called
-                <emphasis>delimited identifiers</emphasis>
-                , which allows broader choices for the spelling of
-                identifiers. If you enclose a SQL identifier in the
-                proper types of quotes, you can use identifiers with
-                spellings that would be invalid without the quotes.
-                Delimited identifiers can contain spaces, punctuation,
-                or international characters. You can also use SQL
-                reserved words if you enclose them in identifier
-                delimiters.
-            </para>
-
-            <para>
-                The
-                <code>quoteIdentifier()</code>
-                method works like
-                <code>quote()</code>
-                , but it applies the identifier delimiter characters to
-                the string according to the type of Adapter you use. For
-                example, standard SQL uses double-quotes (
-                <code>"</code>
-                ) for identifier delimiters, and most RDBMS brands use
-                that symbol. MySQL uses back-quotes (
-                <code>`</code>
-                ) by default. The
-                <code>quoteIdentifier()</code>
-                method also escapes special characters within the string
-                argument.
-            </para>
-
-            <example id="zend.db.adapter.quoting.quote-identifier.example">
-                <title>Using quoteIdentifier()</title>
-                <programlisting role="php"><![CDATA[
-// we might have a table name that is an SQL reserved word
-$tableName = $db->quoteIdentifier("order");
-
-$sql = "SELECT * FROM $tableName";
-
-echo $sql
-// SELECT * FROM "order"
-]]>
-                </programlisting>
-            </example>
-
-            <para>
-                SQL delimited identifiers are case-sensitive, unlike
-                unquoted identifiers. Therefore, if you use delimited
-                identifiers, you must use the spelling of the identifier
-                exactly as it is stored in your schema, including the
-                case of the letters.
-            </para>
-
-            <para>
-                In most cases where SQL is generated within Zend_Db
-                classes, the default is that all identifiers are
-                delimited automatically. You can change this behavior
-                with the option
-                <code>Zend_Db::AUTO_QUOTE_IDENTIFIERS</code>
-                . Specify this when instantiating the Adapter. See
-                <xref linkend="zend.db.adapter.connecting.parameters.example2"></xref>
-                .
-            </para>
-
-        </sect3>
-
-    </sect2>
-
-    <sect2 id="zend.db.adapter.transactions">
-
-        <title>Controlling Database Transactions</title>
-
-        <para>
-            Databases define transactions as logical units of work that
-            can be committed or rolled back as a single change, even if
-            they operate on multiple tables. All queries to a database
-            are executed within the context of a transaction, even if
-            the database driver manages them implicitly. This is called
-            <emphasis>auto-commit</emphasis>
-            mode, in which the database driver creates a transaction for
-            every statement you execute, and commits that transaction
-            after your SQL statement has been executed. By default, all
-            Zend_Db Adapter classes operate in auto-commit mode.
-        </para>
-
-        <para>
-            Alternatively, you can specify the beginning and resolution
-            of a transaction, and thus control how many SQL queries are
-            included in a single group that is committed (or rolled
-            back) as a single operation. Use the
-            <code>beginTransaction()</code>
-            method to initiate a transaction. Subsequent SQL statements
-            are executed in the context of the same transaction until
-            you resolve it explicitly.
-        </para>
-
-        <para>
-            To resolve the transaction, use either the
-            <code>commit()</code>
-            or
-            <code>rollBack()</code>
-            methods. The
-            <code>commit()</code>
-            method marks changes made during your transaction as
-            committed, which means the effects of these changes are
-            shown in queries run in other transactions.
-        </para>
-
-        <para>
-            The
-            <code>rollBack()</code>
-            method does the opposite: it discards the changes made
-            during your transaction. The changes are effectively undone,
-            and the state of the data returns to how it was before you
-            began your transaction. However, rolling back your
-            transaction has no effect on changes made by other
-            transactions running concurrently.
-        </para>
-
-        <para>
-            After you resolve this transaction,
-            <code>Zend_Db_Adapter</code>
-            returns to auto-commit mode until you call
-            <code>beginTransaction()</code>
-            again.
-        </para>
-
-        <example id="zend.db.adapter.transactions.example">
-            <title>Managing a transaction to ensure consistency</title>
-            <programlisting role="php"><![CDATA[
-// Start a transaction explicitly.
-$db->beginTransaction();
-
-try {
-    // Attempt to execute one or more queries:
-    $db->query(...);
-    $db->query(...);
-    $db->query(...);
-
-    // If all succeed, commit the transaction and all changes
-    // are committed at once.
-    $db->commit();
-
-} catch (Exception $e) {
-    // If any of the queries failed and threw an exception,
-    // we want to roll back the whole transaction, reversing
-    // changes made in the transaction, even those that succeeded.
-    // Thus all changes are committed together, or none are.
-    $db->rollBack();
-    echo $e->getMessage();
-}
-]]>
-            </programlisting>
-        </example>
-
-    </sect2>
-
-    <sect2 id="zend.db.adapter.list-describe">
-
-        <title>Listing and Describing Tables</title>
-
-        <para>
-            The
-            <code>listTables()</code>
-            method returns an array of strings, naming all tables in the
-            current database.
-        </para>
-
-        <para>
-            The
-            <code>describeTable()</code>
-            method returns an associative array of metadata about a
-            table. Specify the name of the table as a string in the
-            first argument to this method. The second argument is
-            optional, and names the schema in which the table exists.
-        </para>
-
-        <para>
-            The keys of the associative array returned are the column
-            names of the table. The value corresponding to each column
-            is also an associative array, with the following keys and
-            values:
-        </para>
-
-        <table frame="all" cellpadding="5" id="zend.db.adapter.list-describe.metadata">
-            <title>Metadata fields returned by describeTable()</title>
-            <tgroup cols="3" align="left" colsep="1" rowsep="1">
-                <thead>
-                    <row>
-                        <entry>Key</entry>
-                        <entry>Type</entry>
-                        <entry>Description</entry>
-                    </row>
-                </thead>
-                <tbody>
-                    <row>
-                        <entry>SCHEMA_NAME</entry>
-                        <entry>(string)</entry>
-                        <entry>
-                            Name of the database schema in which this
-                            table exists.
-                        </entry>
-                    </row>
-                    <row>
-                        <entry>TABLE_NAME</entry>
-                        <entry>(string)</entry>
-                        <entry>
-                            Name of the table to which this column
-                            belongs.
-                        </entry>
-                    </row>
-                    <row>
-                        <entry>COLUMN_NAME</entry>
-                        <entry>(string)</entry>
-                        <entry>Name of the column.</entry>
-                    </row>
-                    <row>
-                        <entry>COLUMN_POSITION</entry>
-                        <entry>(integer)</entry>
-                        <entry>
-                            Ordinal position of the column in the table.
-                        </entry>
-                    </row>
-                    <row>
-                        <entry>DATA_TYPE</entry>
-                        <entry>(string)</entry>
-                        <entry>
-                            RDBMS name of the datatype of the column.
-                        </entry>
-                    </row>
-                    <row>
-                        <entry>DEFAULT</entry>
-                        <entry>(string)</entry>
-                        <entry>
-                            Default value for the column, if any.
-                        </entry>
-                    </row>
-                    <row>
-                        <entry>NULLABLE</entry>
-                        <entry>(boolean)</entry>
-                        <entry>
-                            True if the column accepts SQL NULLs, false
-                            if the column has a NOT NULL constraint.
-                        </entry>
-                    </row>
-                    <row>
-                        <entry>LENGTH</entry>
-                        <entry>(integer)</entry>
-                        <entry>
-                            Length or size of the column as reported by
-                            the RDBMS.
-                        </entry>
-                    </row>
-                    <row>
-                        <entry>SCALE</entry>
-                        <entry>(integer)</entry>
-                        <entry>
-                            Scale of SQL NUMERIC or DECIMAL type.
-                        </entry>
-                    </row>
-                    <row>
-                        <entry>PRECISION</entry>
-                        <entry>(integer)</entry>
-                        <entry>
-                            Precision of SQL NUMERIC or DECIMAL type.
-                        </entry>
-                    </row>
-                    <row>
-                        <entry>UNSIGNED</entry>
-                        <entry>(boolean)</entry>
-                        <entry>
-                            True if an integer-based type is reported as
-                            UNSIGNED.
-                        </entry>
-                    </row>
-                    <row>
-                        <entry>PRIMARY</entry>
-                        <entry>(boolean)</entry>
-                        <entry>
-                            True if the column is part of the primary
-                            key of this table.
-                        </entry>
-                    </row>
-                    <row>
-                        <entry>PRIMARY_POSITION</entry>
-                        <entry>(integer)</entry>
-                        <entry>
-                            Ordinal position (1-based) of the column in
-                            the primary key.
-                        </entry>
-                    </row>
-                    <row>
-                        <entry>IDENTITY</entry>
-                        <entry>(boolean)</entry>
-                        <entry>
-                            True if the column uses an auto-generated
-                            value.
-                        </entry>
-                    </row>
-                </tbody>
-            </tgroup>
-        </table>
-
-        <note>
-            <title>
-                How the IDENTITY metadata field relates to specific
-                RDBMS
-            </title>
-            <para>
-                The IDENTITY metadata field was chosen as an 'idiomatic'
-                term to represent a relation to surrogate keys. This
-                field can be commonly known by the following values:-
-            </para>
-            <itemizedlist>
-                <listitem>
-                    <para>
-                        <code>IDENTITY</code>
-                        - DB2, MSSQL
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        <code>AUTO_INCREMENT</code>
-                        - MySQL
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        <code>SERIAL</code>
-                        - PostgreSQL
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        <code>SEQUENCE</code>
-                        - Oracle
-                    </para>
-                </listitem>
-            </itemizedlist>
-        </note>
-
-        <para>
-            If no table exists matching the table name and optional
-            schema name specified, then
-            <code>describeTable()</code>
-            returns an empty array.
-        </para>
-
-    </sect2>
-
-    <sect2 id="zend.db.adapter.closing">
-
-        <title>Closing a Connection</title>
-
-        <para>
-            Normally it is not necessary to close a database connection.
-            PHP automatically cleans up all resources and the end of a
-            request. Database extensions are designed to close the
-            connection as the reference to the resource object is
-            cleaned up.
-        </para>
-
-        <para>
-            However, if you have a long-duration PHP script that
-            initiates many database connections, you might need to close
-            the connection, to avoid exhausting the capacity of your
-            RDBMS server. You can use the Adapter's
-            <code>closeConnection()</code>
-            method to explicitly close the underlying database
-            connection.
-        </para>
-
-        <example id="zend.db.adapter.closing.example">
-            <title>Closing a database connection</title>
-            <programlisting role="php"><![CDATA[
-$db->closeConnection();
-]]>
-            </programlisting>
-        </example>
-
-        <note>
-            <title>Does Zend_Db support persistent connections?</title>
-            <para>
-                The usage of persistent connections is not supported or
-                encouraged in Zend_Db.
-            </para>
-            <para>
-                Using persistent connections can cause an excess of idle
-                connections on the RDBMS server, which causes more
-                problems than any performance gain you might achieve by
-                reducing the overhead of making connections.
-            </para>
-            <para>
-                Database connections have state. That is, some objects
-                in the RDBMS server exist in session scope. Examples are
-                locks, user variables, temporary tables, and information
-                about the most recently executed query, such as rows
-                affected, and last generated id value. If you use
-                persistent connections, your application could access
-                invalid or privileged data that were created in a
-                previous PHP request.
-            </para>
-        </note>
-
-    </sect2>
-
-    <sect2 id="zend.db.adapter.other-statements">
-
-        <title>Running Other Database Statements</title>
-
-        <para>
-            There might be cases in which you need to access the
-            connection object directly, as provided by the PHP database
-            extension. Some of these extensions may offer features that
-            are not surfaced by methods of Zend_Db_Adapter_Abstract.
-        </para>
-
-        <para>
-            For example, all SQL statements run by Zend_Db are prepared,
-            then executed. However, some database features are
-            incompatible with prepared statements. DDL statements like
-            CREATE and ALTER cannot be prepared in MySQL. Also, SQL
-            statements don't benefit from the
-            <ulink url="http://dev.mysql.com/doc/refman/5.1/en/query-cache-how.html">
-                MySQL Query Cache
-            </ulink>
-            , prior to MySQL 5.1.17.
-        </para>
-
-        <para>
-            Most PHP database extensions provide a method to execute SQL
-            statements without preparing them. For example, in PDO, this
-            method is
-            <code>exec()</code>
-            . You can access the connection object in the PHP extension
-            directly using getConnection().
-        </para>
-
-        <example id="zend.db.adapter.other-statements.example">
-            <title>
-                Running a non-prepared statement in a PDO adapter
-            </title>
-            <programlisting role="php"><![CDATA[
-$result = $db->getConnection()->exec('DROP TABLE bugs');
-]]>
-            </programlisting>
-        </example>
-
-        <para>
-            Similarly, you can access other methods or properties that
-            are specific to PHP database extensions. Be aware, though,
-            that by doing this you might constrain your application to
-            the interface provided by the extension for a specific brand
-            of RDBMS.
-        </para>
-
-        <para>
-            In future versions of Zend_Db, there will be opportunities
-            to add method entry points for functionality that is common
-            to the supported PHP database extensions. This will not
-            affect backward compatibility.
-        </para>
-
-    </sect2>
-
-    <sect2 id="zend.db.adapter.adapter-notes">
-
-        <title>Notes on Specific Adapters</title>
-
-        <para>
-            This section lists differences between the Adapter classes
-            of which you should be aware.
-        </para>
-
-        <sect3 id="zend.db.adapter.adapter-notes.ibm-db2">
-            <title>IBM DB2</title>
-            <itemizedlist>
-                <listitem>
-                    <para>
-                        Specify this Adapter to the factory() method
-                        with the name 'Db2'.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        This Adapter uses the PHP extension ibm_db2.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        IBM DB2 supports both sequences and
-                        auto-incrementing keys. Therefore the arguments
-                        to
-                        <code>lastInsertId()</code>
-                        are optional. If you give no arguments, the
-                        Adapter returns the last value generated for an
-                        auto-increment key. If you give arguments, the
-                        Adapter returns the last value generated by the
-                        sequence named according to the convention '
-                        <emphasis>table</emphasis>
-                        _
-                        <emphasis>column</emphasis>
-                        _seq'.
-                    </para>
-                </listitem>
-            </itemizedlist>
-        </sect3>
-
-        <sect3 id="zend.db.adapter.adapter-notes.mysqli">
-            <title>MySQLi</title>
-            <itemizedlist>
-                <listitem>
-                    <para>
-                        Specify this Adapter to the
-                        <code>factory()</code>
-                        method with the name 'Mysqli'.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        This Adapter utilizes the PHP extension mysqli.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        MySQL does not support sequences, so
-                        <code>lastInsertId()</code>
-                        ignores its arguments and always returns the
-                        last value generated for an auto-increment key.
-                        The
-                        <code>lastSequenceId()</code>
-                        method returns
-                        <code>null</code>
-                        .
-                    </para>
-                </listitem>
-            </itemizedlist>
-        </sect3>
-
-        <sect3 id="zend.db.adapter.adapter-notes.oracle">
-            <title>Oracle</title>
-            <itemizedlist>
-                <listitem>
-                    <para>
-                        Specify this Adapter to the
-                        <code>factory()</code>
-                        method with the name 'Oracle'.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        This Adapter uses the PHP extension oci8.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        Oracle does not support auto-incrementing keys,
-                        so you should specify the name of a sequence to
-                        <code>lastInsertId()</code>
-                        or
-                        <code>lastSequenceId()</code>
-                        .
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        The Oracle extension does not support positional
-                        parameters. You must use named parameters.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        Currently the
-                        <code>Zend_Db::CASE_FOLDING</code>
-                        option is not supported by the Oracle adapter.
-                        To use this option with Oracle, you must use the
-                        PDO OCI adapter.
-                    </para>
-                </listitem>
-            </itemizedlist>
-        </sect3>
-
-        <sect3 id="zend.db.adapter.adapter-notes.pdo-ibm">
-            <title>
-                PDO for IBM DB2 and Informix Dynamic Server (IDS)
-            </title>
-            <itemizedlist>
-                <listitem>
-                    <para>
-                        Specify this Adapter to the
-                        <code>factory()</code>
-                        method with the name 'Pdo_Ibm'.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        This Adapter uses the PHP extensions pdo and
-                        pdo_ibm.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        You must use at least PDO_IBM extension version
-                        1.2.2. If you have an earlier version of this
-                        extension, you must upgrade the PDO_IBM
-                        extension from PECL.
-                    </para>
-                </listitem>
-            </itemizedlist>
-        </sect3>
-
-        <sect3 id="zend.db.adapter.adapter-notes.pdo-mssql">
-            <title>PDO Microsoft SQL Server</title>
-            <itemizedlist>
-                <listitem>
-                    <para>
-                        Specify this Adapter to the
-                        <code>factory()</code>
-                        method with the name 'Pdo_Mssql'.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        This Adapter uses the PHP extensions pdo and
-                        pdo_mssql.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        Microsoft SQL Server does not support sequences,
-                        so
-                        <code>lastInsertId()</code>
-                        ignores its arguments and always returns the
-                        last value generated for an auto-increment key.
-                        The
-                        <code>lastSequenceId()</code>
-                        method returns
-                        <code>null</code>
-                        .
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        If you are working with unicode strings in an
-                        encoding other than UCS-2 (such as UTF-8), you
-                        may have to perform a conversion in your
-                        application code or store the data in a binary
-                        column. Please refer to
-                        <ulink url="http://support.microsoft.com/kb/232580">
-                            Microsoft's Knowledge Base
-                        </ulink>
-                        for more information.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        Zend_Db_Adapter_Pdo_Mssql sets
-                        <code>QUOTED_IDENTIFIER ON</code>
-                        immediately after connecting to a SQL Server
-                        database. This makes the driver use the standard
-                        SQL identifier delimiter symbol (
-                        <code>"</code>
-                        ) instead of the proprietary square-brackets
-                        syntax SQL Server uses for delimiting
-                        identifiers.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        You can specify
-                        <code>pdoType</code>
-                        as a key in the options array. The value can be
-                        "mssql" (the default), "dblib", "freetds", or
-                        "sybase". This option affects the DSN prefix the
-                        adapter uses when constructing the DSN string.
-                        Both "freetds" and "sybase" imply a prefix of
-                        "sybase:", which is used for the
-                        <ulink url="http://www.freetds.org/">
-                            FreeTDS
-                        </ulink>
-                        set of libraries. See also
-                        <ulink url="http://www.php.net/manual/en/ref.pdo-dblib.connection.php">
-                            http://www.php.net/manual/en/ref.pdo-dblib.connection.php
-                        </ulink>
-                        for more information on the DSN prefixes used in
-                        this driver.
-                    </para>
-                </listitem>
-            </itemizedlist>
-        </sect3>
-
-        <sect3 id="zend.db.adapter.adapter-notes.pdo-mysql">
-            <title>PDO MySQL</title>
-            <itemizedlist>
-                <listitem>
-                    <para>
-                        Specify this Adapter to the
-                        <code>factory()</code>
-                        method with the name 'Pdo_Mysql'.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        This Adapter uses the PHP extensions pdo and
-                        pdo_mysql.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        MySQL does not support sequences, so
-                        <code>lastInsertId()</code>
-                        ignores its arguments and always returns the
-                        last value generated for an auto-increment key.
-                        The
-                        <code>lastSequenceId()</code>
-                        method returns
-                        <code>null</code>
-                        .
-                    </para>
-                </listitem>
-            </itemizedlist>
-        </sect3>
-
-        <sect3 id="zend.db.adapter.adapter-notes.pdo-oci">
-            <title>PDO Oracle</title>
-            <itemizedlist>
-                <listitem>
-                    <para>
-                        Specify this Adapter to the
-                        <code>factory()</code>
-                        method with the name 'Pdo_Oci'.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        This Adapter uses the PHP extensions pdo and
-                        pdo_oci.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        Oracle does not support auto-incrementing keys,
-                        so you should specify the name of a sequence to
-                        <code>lastInsertId()</code>
-                        or
-                        <code>lastSequenceId()</code>
-                        .
-                    </para>
-                </listitem>
-            </itemizedlist>
-        </sect3>
-
-        <sect3 id="zend.db.adapter.adapter-notes.pdo-pgsql">
-            <title>PDO PostgreSQL</title>
-            <itemizedlist>
-                <listitem>
-                    <para>
-                        Specify this Adapter to the
-                        <code>factory()</code>
-                        method with the name 'Pdo_Pgsql'.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        This Adapter uses the PHP extensions pdo and
-                        pdo_pgsql.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        PostgreSQL supports both sequences and
-                        auto-incrementing keys. Therefore the arguments
-                        to
-                        <code>lastInsertId()</code>
-                        are optional. If you give no arguments, the
-                        Adapter returns the last value generated for an
-                        auto-increment key. If you give arguments, the
-                        Adapter returns the last value generated by the
-                        sequence named according to the convention '
-                        <emphasis>table</emphasis>
-                        _
-                        <emphasis>column</emphasis>
-                        _seq'.
-                    </para>
-                </listitem>
-            </itemizedlist>
-        </sect3>
-
-        <sect3 id="zend.db.adapter.adapter-notes.pdo-sqlite">
-            <title>PDO SQLite</title>
-            <itemizedlist>
-                <listitem>
-                    <para>
-                        Specify this Adapter to the
-                        <code>factory()</code>
-                        method with the name 'Pdo_Sqlite'.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        This Adapter uses the PHP extensions pdo and
-                        pdo_sqlite.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        SQLite does not support sequences, so
-                        <code>lastInsertId()</code>
-                        ignores its arguments and always returns the
-                        last value generated for an auto-increment key.
-                        The
-                        <code>lastSequenceId()</code>
-                        method returns
-                        <code>null</code>
-                        .
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        To connect to an SQLite2 database, specify
-                        <code>'sqlite2'=&gt;true</code>
-                        in the array of parameters when creating an
-                        instance of the Pdo_Sqlite Adapter.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        To connect to an in-memory SQLite database,
-                        specify
-                        <code>'dbname'=&gt;':memory:'</code>
-                        in the array of parameters when creating an
-                        instance of the Pdo_Sqlite Adapter.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        Older versions of the SQLite driver for PHP do
-                        not seem to support the PRAGMA commands
-                        necessary to ensure that short column names are
-                        used in result sets. If you have problems that
-                        your result sets are returned with keys of the
-                        form "tablename.columnname" when you do a join
-                        query, then you should upgrade to the current
-                        version of PHP.
-                    </para>
-                </listitem>
-            </itemizedlist>
-        </sect3>
-
-        <sect3 id="zend.db.adapter.adapter-notes.firebird">
-            <title>Firebird/Interbase</title>
-            <itemizedlist>
-                <listitem>
-                    <para>
-                        This Adapter uses the PHP extension
-                        php_interbase.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        Firebird/interbase does not support
-                        auto-incrementing keys, so you should specify
-                        the name of a sequence to
-                        <code>lastInsertId()</code>
-                        or
-                        <code>lastSequenceId()</code>
-                        .
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        Currently the
-                        <code>Zend_Db::CASE_FOLDING</code>
-                        option is not supported by the
-                        Firebird/interbase adapter. Unquoted identifiers
-                        are automatically returned in upper case.
-                    </para>
-                </listitem>
-            </itemizedlist>
-        </sect3>
-
-
-    </sect2>
-
-</sect1>
-<!--
-    vim:se ts=4 sw=4 et:
--->
+<sect1 id="zend.db.adapter">
+
+    <title>Zend_Db_Adapter</title>
+
+    <para>
+        Zend_Db y sus clases relacionadas proporcionan una interfaz
+        simple de base de datos SQL para Zend Framework. El
+        Zend_Db_Adapter es la clase base que se utiliza para conectar su
+        aplicación PHP A una base de datos (RDBMS). Existen diferentes
+        clases Adapters(Adaptador) para cada tipo de base de datos
+        (RDBMS).
+    </para>
+
+    <para>
+        Las clases
+        <code>Adapters</code>
+        de Zend_Db crean un puente entre las extensiones de base de
+        datos de PHP hacia una interfaz común, para ayudarle a escribir
+        aplicaciones PHP una sola vez y poder desplegar múltiples
+        tipos de base de datos (RDBMS) con muy poco esfuerzo.
+    </para>
+
+    <para>
+        La Interfaz de la clase adaptador (adapter) es similar a la
+        intefaz de la extensión
+        <ulink url="http://www.php.net/pdo">PHP Data Objects</ulink>
+        . Zend_Db proporciona clases Adaptadoras para los drivers PDO de
+        los siguientes tipos de RDBMS:
+    </para>
+
+    <itemizedlist>
+        <listitem>
+            <para>
+                IBM DB2 e Informix Dynamic Server (IDS), usando la
+                extensión PHP
+                <ulink url="http://www.php.net/pdo-ibm">pdo_ibm</ulink>
+            </para>
+        </listitem>
+        <listitem>
+            <para>
+                MySQL, usando la extensión PHP
+                <ulink url="http://www.php.net/pdo-mysql">
+                    pdo_mysql
+                </ulink>
+            </para>
+        </listitem>
+        <listitem>
+            <para>
+                Microsoft SQL Server, usando la extensión PHP
+                <ulink url="http://www.php.net/pdo-mssql">
+                    pdo_mssql
+                </ulink>
+            </para>
+        </listitem>
+        <listitem>
+            <para>
+                Oracle, usando la extensión PHP
+                <ulink url="http://www.php.net/pdo-oci">pdo_oci</ulink>
+            </para>
+        </listitem>
+        <listitem>
+            <para>
+                PostgreSQL, usando la extensión PHP
+                <ulink url="http://www.php.net/pdo-pgsql">
+                    pdo_pgsql
+                </ulink>
+            </para>
+        </listitem>
+        <listitem>
+            <para>
+                SQLite, usando la extensión PHP
+                <ulink url="http://www.php.net/pdo-sqlite">
+                    pdo_sqlite
+                </ulink>
+            </para>
+        </listitem>
+
+    </itemizedlist>
+
+    <para>
+        Ademas, Zend_Db proporciona clases Adaptadoras que utilizan las
+        extensiones de base de datos de PHP de los siguientes tipos:
+    </para>
+
+    <itemizedlist>
+        <listitem>
+            <para>
+                MySQL, usando la extensión PHP
+                <ulink url="http://www.php.net/mysqli">mysqli</ulink>
+            </para>
+        </listitem>
+        <listitem>
+            <para>
+                Oracle, usando la extensión PHP
+                <ulink url="http://www.php.net/oci8">oci8</ulink>
+            </para>
+        </listitem>
+        <listitem>
+            <para>
+                IBM DB2, usando la extensión PHP
+                <ulink url="http://www.php.net/ibm_db2">ibm_db2</ulink>
+            </para>
+        </listitem>
+        <listitem>
+            <para>
+                Firebird/Interbase, usando la extensión PHP
+                <ulink url="http://www.php.net/ibase">
+                    php_interbase
+                </ulink>
+            </para>
+        </listitem>
+    </itemizedlist>
+
+    <note>
+        <para>
+            Cada Zend_Db_Adaptador utiliza una extensión PHP. Se debe de
+            tener habilitada la respectiva extensión en su entorno PHP
+            para utilizar un Zend_Db_Adapter. Por ejemplo, si se utiliza
+            una clase Zend_Db_Adapter basada en PDO, tiene que
+            habilitar tanto la extensión PDO como el driver PDO del tipo
+            de base de datos que se utiliza.
+
+        </para>
+    </note>
+
+    <sect2 id="zend.db.adapter.connecting">
+
+        <title>
+            Conexión a una Base de Datos utilizando un Adaptador
+        </title>
+
+        <para>
+            Esta sección describe cómo crear una instancia de un
+            Adaptador de base de datos. Esto corresponde a establecer
+            una conexión a un servidor de Base de Datos (RDBMS) desde su
+            aplicación PHP.
+        </para>
+
+        <sect3 id="zend.db.adapter.connecting.constructor">
+
+            <title>Usando un Constructor de Zend_Db Adapter</title>
+
+            <para>
+                Se puede crear una instancia de un Adaptador utilizando
+                su constructor. Un constructor de adaptador toma un
+                argumento, que es un conjunto de parámetros utilizados
+                para declarar la conexión.
+            </para>
+
+
+            <example id="zend.db.adapter.connecting.constructor.example">
+                <title>Usando el Constructor de un Adaptador</title>
+                <programlisting role="php"><![CDATA[
+$db = new Zend_Db_Adapter_Pdo_Mysql(array(
+    'host'     => '127.0.0.1',
+    'username' => 'webuser',
+    'password' => 'xxxxxxxx',
+    'dbname'   => 'test'
+));
+]]>
+                </programlisting>
+            </example>
+
+        </sect3>
+
+        <sect3 id="zend.db.adapter.connecting.factory">
+
+            <title>Usando el Factory de Zend_Db</title>
+
+            <para>
+                Como alternativa a la utilización directa del
+                constructor de un adaptador, se puede crear una
+                instancia del adaptador que use el método estático
+                <code>Zend_Db::factory()</code>
+                . Este método carga dinámicamente el archivo de clase
+                Adaptador bajo demanda, usando
+                <link linkend="zend.loader.load.class">
+                    Zend_Loader::loadClass()
+                </link>
+                .
+            </para>
+
+            <para>
+                El primer argumento es una cadena que nombra al nombre base
+                de la clase Adaptador. Por ejemplo, la cadena
+                'Pdo_Mysql' corresponde a la clase
+                Zend_Db_Adapter_Pdo_Mysql. El segundo argumento es el
+                mismo array de parámetros que hubiera enviado al
+                constructor del adaptador.
+            </para>
+
+
+
+
+
+            <example id="zend.db.adapter.connecting.factory.example">
+                <title>Usando el Adaptador del método factory</title>
+                <programlisting role="php"><![CDATA[
+// No necesitamos la siguiente declaración, porque 
+// el archivo Zend_Db_Adapter_Pdo_Mysql será cargado para nosotros por el método  
+// factory de Zend_Db.
+
+// require_once 'Zend/Db/Adapter/Pdo/Mysql.php';
+
+// carga automaticamente la clase Zend_Db_Adapter_Pdo_Mysql
+// y crea una instancia de la misma 
+$db = Zend_Db::factory('Pdo_Mysql', array(
+    'host'     => '127.0.0.1',
+    'username' => 'webuser',
+    'password' => 'xxxxxxxx',
+    'dbname'   => 'test'
+));
+]]>
+                </programlisting>
+            </example>
+
+            <para>
+            Si crea su propia clase que extiende a
+            Zend_Db_Adapter_Abstract, pero no nombra su clase con el prefijo
+            de paquete "Zend_Db_Adapter", se puede utilizar el método
+            <code>factory()</code>
+            para cargar su adaptador si se especifica la parte principal
+            de la clase del adaptador con la clave "adapterNamespace" en
+            el conjunto de parámetros
+            </para>
+        
+            <example id="zend.db.adapter.connecting.factory.example2">
+                <title>
+                    Usando el método factory para una clase Adaptador
+                    personalizada
+                </title>
+                <programlisting role="php"><![CDATA[
+// No tenemos que cargar el archivo de clase Adaptador 
+// porque será cargado para nosotros por el método factory de Zend_Db.
+
+// Automáticamente carga la clase MyProject_Db_Adapter_Pdo_Mysql
+// y crea una instancia de ella.
+
+$db = Zend_Db::factory('Pdo_Mysql', array(
+    'host'             => '127.0.0.1',
+    'username'         => 'webuser',
+    'password'         => 'xxxxxxxx',
+    'dbname'           => 'test',
+    'adapterNamespace' => 'MyProject_Db_Adapter'
+));
+]]>
+                </programlisting>
+            </example>
+
+        </sect3>
+
+        <sect3 id="zend.db.adapter.connecting.factory-config">
+
+            <title>Uso de Zend_Config con Zend_Db Factory</title>
+
+            <para>
+                Opcionalmente, se puede especificar cualquier
+                argumento del método
+                <code>factory()</code>
+                como un objeto de tipo
+                <link linkend="zend.config">Zend_Config</link>
+                .
+            </para>
+
+            <para>
+                Si el primer argumento es un objeto de configuración, se
+                espera que contenga una propiedad llamada
+                <code>adapter</code>
+                , conteniendo la cadena que da nombre al nombre base de la
+                clase de adaptador. Opcionalmente, el objeto puede
+                contener una propiedad llamada
+                <code>params</code>
+                , con subpropiedades correspondientes a nombres de parámetros
+                del adaptador. Esto es usado sólo si el segundo
+                argumento del método <code>factory()</code> se ha omitido.
+            </para>
+
+            <example id="zend.db.adapter.connecting.factory.example1">
+                <title>
+                    Uso del método factory del Adaptador con un objeto Zend_Config            
+                </title>
+                <para>
+                    En el siguiente ejemplo, un objeto Zend_Config es
+                    creado usando un array. También puedes cargar los datos de
+                    un archivo externo, por ejemplo con
+                    <link linkend="zend.config.adapters.ini">
+                        Zend_Config_Ini
+                    </link>
+                    o
+                    <link linkend="zend.config.adapters.xml">
+                        Zend_Config_Xml
+                    </link>
+                    .
+                </para>
+                <programlisting role="php"><![CDATA[
+$config = new Zend_Config(
+    array(
+        'database' => array(
+            'adapter' => 'Mysqli',
+            'params' => array(
+                'dbname' => 'test',
+                'username' => 'webuser',
+                'password' => 'secret',
+            )
+        )
+    )
+);
+
+$db = Zend_Db::factory($config->database);
+]]>
+                </programlisting>
+            </example>
+
+            <para>
+                El segundo argumento del método
+                <code>factory()</code>
+                puede ser un array asociativo con entradas
+                correspondientes a los parámetros del adaptador. Este argumento es
+                opcional. Si el primer argumento es de tipo Zend_Config,
+                se asume que tiene todos los parametros, y el segundo
+                argumento es ignorado.
+            </para>
+
+        </sect3>
+
+        <sect3 id="zend.db.adapter.connecting.parameters">
+
+            <title>Parámetros del Adaptador</title>
+
+            <para>
+                El siguiente listado explica parámetros comunes reconocidos por 
+                Adaptador de clases Zend_Db.
+            </para>
+
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        <emphasis role="strong">host</emphasis>
+                        : una string conteniendo un nombre de host o dirección IP
+                        del servidor de base de datos. Si la base de datos está corriendo
+            sobre el mismo host que la aplicación PHP,
+                        usted puede utilizar 'localhost' o '127.0.0.1'.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <emphasis role="strong">username</emphasis>
+                        : identificador de cuenta para autenticar una conexión al 
+            servidor RDBMS.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <emphasis role="strong">password</emphasis>
+                        : la contraseña de la cuenta para la autenticación de credenciales
+            de conexión con el servidor RDBMS
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <emphasis role="strong">dbname</emphasis>
+                        : nombre de la base de datos en el servidor RDBMS.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <emphasis role="strong">port</emphasis>
+                        : algunos servidores RDBMS pueden aceptar conexiones de red
+                        sobre un número de puerto específico.
+            El parámetro del puerto le permite especificar el puerto al 
+            que su aplicación PHP se conecta, para que concuerde el puerto            
+            configurado en el servidor RDBMS.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <emphasis role="strong">options</emphasis>
+                        : este parámetro es un array asociativo de
+                        opciones que son genéricas a todas las clases Zend_Db_Adapter.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <emphasis role="strong">
+                            driver_options
+                        </emphasis>
+                        : este parámetro es un array asociativo de opciones adicionales
+                        para una extensión de base de datos dada.
+            un uso típico de este parámetro es establecer atributos 
+            de un driver PDO.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <emphasis role="strong">
+                            adapterNamespace
+                        </emphasis>
+                        : nombre de la parte inicial del nombre de las clase para el
+            adaptador, en lugar de 'Zend_Db_Adapter'. Utilice 
+                        esto si usted necesita usar el método 
+                        <code>factory()</code>
+                        para cargar un adaptador de clase de base de datos que no sea 
+            de Zend.
+                    </para>
+                </listitem>
+            </itemizedlist>
+
+            <example id="zend.db.adapter.connecting.parameters.example1">
+                <title>
+                    Passing the case-folding option to the factory
+                </title>
+                <para>
+                    Usted puede pasar esta opción específica por la constante
+                    <code>Zend_Db::CASE_FOLDING</code>
+                    . Este corresponde al atributo
+                    <code>ATTR_CASE</code>
+                    en los drivers de base de datos PDO e IBM DB2,
+                    ajustando la sensibilidad de las claves tipo cadena en los resultados
+          de consultas. La opción toma los valores
+                    <code>Zend_Db::CASE_NATURAL</code>
+                    (el predeterminado),
+                    <code>Zend_Db::CASE_UPPER</code>
+                    , y
+                    <code>Zend_Db::CASE_LOWER</code>
+                    .
+                </para>
+                <programlisting role="php"><![CDATA[
+$options = array(
+    Zend_Db::CASE_FOLDING => Zend_Db::CASE_UPPER
+);
+
+$params = array(
+    'host'           => '127.0.0.1',
+    'username'       => 'webuser',
+    'password'       => 'xxxxxxxx',
+    'dbname'         => 'test',
+    'options'        => $options
+);
+
+$db = Zend_Db::factory('Db2', $params);
+]]>
+                </programlisting>
+            </example>
+
+            <example id="zend.db.adapter.connecting.parameters.example2">
+                <title>
+                    Passing the auto-quoting option to the factory
+                </title>
+                <para>
+                    Usted puede especificar esta opción por la constante
+                    <code>Zend_Db::AUTO_QUOTE_IDENTIFIERS</code>
+                    . Si el valor es 
+                    <code>true</code>
+                    (el predeterminado), los identificadores como nombres de tabla,
+          nombres de columna, e incluso los alias son delimitados en la
+          sintaxis SQL generada por el Adatador del objeto.
+          Esto hace que sea sencillo utilizar identificadores que contengan 
+          palabras reservadas de SQL, o caracteres especiales. Si el valor es 
+                    <code>false</code>
+                    , los identificadores no son delimitados automáticamente. Si 
+                    usted necesita delimitar identificadores, debe hacer usted mismo 
+          utilizando el método
+                    <code>quoteIdentifier()</code>
+                    .
+                </para>
+                <programlisting role="php"><![CDATA[
+$options = array(
+    Zend_Db::AUTO_QUOTE_IDENTIFIERS => false
+);
+
+$params = array(
+    'host'           => '127.0.0.1',
+    'username'       => 'webuser',
+    'password'       => 'xxxxxxxx',
+    'dbname'         => 'test',
+    'options'        => $options
+);
+
+$db = Zend_Db::factory('Pdo_Mysql', $params);
+]]>
+                </programlisting>
+            </example>
+
+            <example id="zend.db.adapter.connecting.parameters.example3">
+                <title>Passing PDO driver options to the factory</title>
+                <programlisting role="php"><![CDATA[
+$pdoParams = array(
+    PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true
+);
+
+$params = array(
+    'host'           => '127.0.0.1',
+    'username'       => 'webuser',
+    'password'       => 'xxxxxxxx',
+    'dbname'         => 'test',
+    'driver_options' => $pdoParams
+);
+
+$db = Zend_Db::factory('Pdo_Mysql', $params);
+
+echo $db->getConnection()
+        ->getAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY);
+]]>
+                </programlisting>
+            </example>
+
+        </sect3>
+
+        <sect3 id="zend.db.adapter.connecting.getconnection">
+            <title>Managing Lazy Connections</title>
+
+            <para>
+                Creating an instance of an Adapter class does not
+                immediately connect to the RDBMS server. The Adapter
+                saves the connection parameters, and makes the actual
+                connection on demand, the first time you need to execute
+                a query. This ensures that creating an Adapter object is
+                quick and inexpensive. You can create an instance of an
+                Adapter even if you are not certain that you need to run
+                any database queries during the current request your
+                application is serving.
+            </para>
+
+            <para>
+                If you need to force the Adapter to connect to the
+                RDBMS, use the
+                <code>getConnection()</code>
+                method. This method returns an object for the connection
+                as represented by the respective PHP database extension.
+                For example, if you use any of the Adapter classes for
+                PDO drivers, then
+                <code>getConnection()</code>
+                returns the PDO object, after initiating it as a live
+                connection to the specific database.
+            </para>
+
+            <para>
+                It can be useful to force the connection if you want to
+                catch any exceptions it throws as a result of invalid
+                account credentials, or other failure to connect to the
+                RDBMS server. These exceptions are not thrown until the
+                connection is made, so it can help simplify your
+                application code if you handle the exceptions in one
+                place, instead of at the time of the first query against
+                the database.
+            </para>
+
+            <example id="zend.db.adapter.connecting.getconnection.example">
+                <title>Handling connection exceptions</title>
+                <programlisting role="php"><![CDATA[
+try {
+    $db = Zend_Db::factory('Pdo_Mysql', $parameters);
+    $db->getConnection();
+} catch (Zend_Db_Adapter_Exception $e) {
+    // perhaps a failed login credential, or perhaps the RDBMS is not running
+} catch (Zend_Exception $e) {
+    // perhaps factory() failed to load the specified Adapter class
+}
+]]>
+                </programlisting>
+            </example>
+
+        </sect3>
+
+    </sect2>
+
+    <sect2 id="zend.db.adapter.example-database">
+
+        <title>La base de datos de ejemplo</title>
+
+        <para>
+            En la documentación de las clases Zend_Db, usamos un
+            conjunto sencillo de tablas para ilustrar el uso de las
+            clases y métodos. Estas tablas de ejemplo permiten almacenar
+            información para localizar bugs en un proyecto de desarrollo
+            de software. La base de datos contiene cuatro tablas:
+        </para>
+
+        <itemizedlist>
+            <listitem>
+                <para>
+                    <emphasis role="strong">accounts</emphasis>
+                    almacena información sobre cada usuario que hace el
+                    seguimiento de bugs.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <emphasis role="strong">products</emphasis>
+                    almacena información sobre cada producto para el que
+                    pueden registrarse bugs.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <emphasis role="strong">bugs</emphasis>
+                    almacena información sobre bugs, incluyendo el
+                    estado actual del bug, la persona que informó sobre
+                    el bug, la persona que está asignada para corregir
+                    el bug, y la persona que está asignada para
+                    verificar la corrección.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <emphasis role="strong">bugs_products</emphasis>
+                    stores a relationship between bugs and products.
+                    This implements a many-to-many relationship, because
+                    a given bug may be relevant to multiple products,
+                    and of course a given product can have multiple
+                    bugs.
+                </para>
+            </listitem>
+        </itemizedlist>
+
+        <para>
+            La siguiente definición de datos SQL en lenguaje
+            pseudocódigo describe las tablas de esta base de datos de
+            ejemplo. Estas tablas de ejemplo son usadas ampliamente por
+            los tests unitarios automatizados de Zend_Db.
+        </para>
+
+        <programlisting role="sql"><![CDATA[
+CREATE TABLE accounts (
+  account_name      VARCHAR(100) NOT NULL PRIMARY KEY
+);
+
+CREATE TABLE products (
+  product_id        INTEGER NOT NULL PRIMARY KEY,
+  product_name      VARCHAR(100)
+);
+
+CREATE TABLE bugs (
+  bug_id            INTEGER NOT NULL PRIMARY KEY,
+  bug_description   VARCHAR(100),
+  bug_status        VARCHAR(20),
+  reported_by       VARCHAR(100) REFERENCES accounts(account_name),
+  assigned_to       VARCHAR(100) REFERENCES accounts(account_name),
+  verified_by       VARCHAR(100) REFERENCES accounts(account_name)
+);
+
+CREATE TABLE bugs_products (
+  bug_id            INTEGER NOT NULL REFERENCES bugs,
+  product_id        INTEGER NOT NULL REFERENCES products,
+  PRIMARY KEY       (bug_id, product_id)
+);
+]]>
+        </programlisting>
+
+        <para>
+            Also notice that the
+            <code>bugs</code>
+            table contains multiple foreign key references to the
+            <code>accounts</code>
+            table. Each of these foreign keys may reference a different
+            row in the
+            <code>accounts</code>
+            table for a given bug.
+        </para>
+
+        <para>
+            The diagram below illustrates the physical data model of the
+            example database.
+        </para>
+
+        <para>
+            <inlinegraphic width="387" scale="100" align="center" valign="middle" fileref="figures/zend.db.adapter.example-database.png" format="PNG"></inlinegraphic>
+        </para>
+
+    </sect2>
+
+    <sect2 id="zend.db.adapter.select">
+
+        <title>Reading Query Results</title>
+
+        <para>
+            This section describes methods of the Adapter class with
+            which you can run SELECT queries and retrieve the query
+            results.
+        </para>
+
+        <sect3 id="zend.db.adapter.select.fetchall">
+
+            <title>Fetching a Complete Result Set</title>
+
+            <para>
+                You can run a SQL SELECT query and retrieve its results
+                in one step using the
+                <code>fetchAll()</code>
+                method.
+            </para>
+
+            <para>
+                The first argument to this method is a string containing
+                a SELECT statement. Alternatively, the first argument
+                can be an object of class
+                <link linkend="zend.db.select">Zend_Db_Select</link>
+                . The Adapter automatically converts this object to a
+                string representation of the SELECT statement.
+            </para>
+
+            <para>
+                The second argument to
+                <code>fetchAll()</code>
+                is an array of values to substitute for parameter
+                placeholders in the SQL statement.
+            </para>
+
+            <example id="zend.db.adapter.select.fetchall.example">
+                <title>Using fetchAll()</title>
+                <programlisting role="php"><![CDATA[
+$sql = 'SELECT * FROM bugs WHERE bug_id = ?';
+
+$result = $db->fetchAll($sql, 2);
+]]>
+                </programlisting>
+            </example>
+
+        </sect3>
+
+        <sect3 id="zend.db.adapter.select.fetch-mode">
+
+            <title>Changing the Fetch Mode</title>
+
+            <para>
+                By default,
+                <code>fetchAll()</code>
+                returns an array of rows, each of which is an
+                associative array. The keys of the associative array are
+                the columns or column aliases named in the select query.
+            </para>
+
+            <para>
+                You can specify a different style of fetching results
+                using the
+                <code>setFetchMode()</code>
+                method. The modes supported are identified by constants:
+            </para>
+
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        <emphasis role="strong">
+                            Zend_Db::FETCH_ASSOC
+                        </emphasis>
+                        : return data in an array of associative arrays.
+                        The array keys are column names, as strings.
+                        This is the default fetch mode for
+                        Zend_Db_Adapter classes.
+                    </para>
+                    <para>
+                        Note that if your select-list contains more than
+                        one column with the same name, for example if
+                        they are from two different tables in a JOIN,
+                        there can be only one entry in the associative
+                        array for a given name. If you use the
+                        FETCH_ASSOC mode, you should specify column
+                        aliases in your SELECT query to ensure that the
+                        names result in unique array keys.
+                    </para>
+                    <para>
+                        By default, these strings are returned as they
+                        are returned by the database driver. This is
+                        typically the spelling of the column in the
+                        RDBMS server. You can specify the case for these
+                        strings, using the
+                        <code>Zend_Db::CASE_FOLDING</code>
+                        option. Specify this when instantiating the
+                        Adapter. See
+                        <xref linkend="zend.db.adapter.connecting.parameters.example1"></xref>
+                        .
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <emphasis role="strong">
+                            Zend_Db::FETCH_NUM
+                        </emphasis>
+                        : return data in an array of arrays. The arrays
+                        are indexed by integers, corresponding to the
+                        position of the respective field in the
+                        select-list of the query.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <emphasis role="strong">
+                            Zend_Db::FETCH_BOTH
+                        </emphasis>
+                        : return data in an array of arrays. The array
+                        keys are both strings as used in the FETCH_ASSOC
+                        mode, and integers as used in the FETCH_NUM
+                        mode. Note that the number of elements in the
+                        array is double that which would be in the array
+                        if you used either FETCH_ASSOC or FETCH_NUM.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <emphasis role="strong">
+                            Zend_Db::FETCH_COLUMN
+                        </emphasis>
+                        : return data in an array of values. The value
+                        in each array is the value returned by one
+                        column of the result set. By default, this is
+                        the first column, indexed by 0.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <emphasis role="strong">
+                            Zend_Db::FETCH_OBJ
+                        </emphasis>
+                        : return data in an array of objects. The
+                        default class is the PHP built-in class
+                        stdClass. Columns of the result set are
+                        available as public properties of the object.
+                    </para>
+                </listitem>
+            </itemizedlist>
+
+            <example id="zend.db.adapter.select.fetch-mode.example">
+                <title>Using setFetchMode()</title>
+                <programlisting role="php"><![CDATA[
+$db->setFetchMode(Zend_Db::FETCH_OBJ);
+
+$result = $db->fetchAll('SELECT * FROM bugs WHERE bug_id = ?', 2);
+
+// $result is an array of objects
+echo $result[0]->bug_description;
+]]>
+                </programlisting>
+            </example>
+
+        </sect3>
+
+        <sect3 id="zend.db.adapter.select.fetchassoc">
+
+            <title>Fetching a Result Set as an Associative Array</title>
+
+            <para>
+                The
+                <code>fetchAssoc()</code>
+                method returns data in an array of associative arrays,
+                regardless of what value you have set for the fetch
+                mode.
+            </para>
+
+            <example id="zend.db.adapter.select.fetchassoc.example">
+                <title>Using fetchAssoc()</title>
+                <programlisting role="php"><![CDATA[
+$db->setFetchMode(Zend_Db::FETCH_OBJ);
+
+$result = $db->fetchAssoc('SELECT * FROM bugs WHERE bug_id = ?', 2);
+
+// $result is an array of associative arrays, in spite of the fetch mode
+echo $result[0]['bug_description'];
+]]>
+                </programlisting>
+            </example>
+
+        </sect3>
+
+        <sect3 id="zend.db.adapter.select.fetchcol">
+
+            <title>Fetching a Single Column from a Result Set</title>
+
+            <para>
+                The
+                <code>fetchCol()</code>
+                method returns data in an array of values, regardless of
+                the value you have set for the fetch mode. This only
+                returns the first column returned by the query. Any
+                other columns returned by the query are discarded. If
+                you need to return a column other than the first, see
+                <xref linkend="zend.db.statement.fetching.fetchcolumn"></xref>
+                .
+            </para>
+
+            <example id="zend.db.adapter.select.fetchcol.example">
+                <title>Using fetchCol()</title>
+                <programlisting role="php"><![CDATA[
+$db->setFetchMode(Zend_Db::FETCH_OBJ);
+
+$result = $db->fetchCol(
+    'SELECT bug_description, bug_id FROM bugs WHERE bug_id = ?', 2);
+
+// contains bug_description; bug_id is not returned
+echo $result[0];
+]]>
+                </programlisting>
+            </example>
+
+        </sect3>
+
+        <sect3 id="zend.db.adapter.select.fetchpairs">
+
+            <title>Fetching Key-Value Pairs from a Result Set</title>
+
+            <para>
+                The
+                <code>fetchPairs()</code>
+                method returns data in an array of key-value pairs, as
+                an associative array with a single entry per row. The
+                key of this associative array is taken from the first
+                column returned by the SELECT query. The value is taken
+                from the second column returned by the SELECT query. Any
+                other columns returned by the query are discarded.
+            </para>
+
+            <para>
+                You should design the SELECT query so that the first
+                column returned has unique values. If there are
+                duplicates values in the first column, entries in the
+                associative array will be overwritten.
+            </para>
+
+            <example id="zend.db.adapter.select.fetchpairs.example">
+                <title>Using fetchPairs()</title>
+                <programlisting role="php"><![CDATA[
+$db->setFetchMode(Zend_Db::FETCH_OBJ);
+
+$result = $db->fetchPairs('SELECT bug_id, bug_status FROM bugs');
+
+echo $result[2];
+]]>
+                </programlisting>
+            </example>
+        </sect3>
+
+        <sect3 id="zend.db.adapter.select.fetchrow">
+
+            <title>Fetching a Single Row from a Result Set</title>
+
+            <para>
+                The
+                <code>fetchRow()</code>
+                method returns data using the current fetch mode, but it
+                returns only the first row fetched from the result set.
+            </para>
+
+            <example id="zend.db.adapter.select.fetchrow.example">
+                <title>Using fetchRow()</title>
+                <programlisting role="php"><![CDATA[
+$db->setFetchMode(Zend_Db::FETCH_OBJ);
+
+$result = $db->fetchRow('SELECT * FROM bugs WHERE bug_id = 2');
+
+// note that $result is a single object, not an array of objects
+echo $result->bug_description;
+]]>
+                </programlisting>
+            </example>
+        </sect3>
+
+        <sect3 id="zend.db.adapter.select.fetchone">
+
+            <title>Fetching a Single Scalar from a Result Set</title>
+
+            <para>
+                The
+                <code>fetchOne()</code>
+                method is like a combination of
+                <code>fetchRow()</code>
+                with
+                <code>fetchCol()</code>
+                , in that it returns data only for the first row fetched
+                from the result set, and it returns only the value of
+                the first column in that row. Therefore it returns only
+                a single scalar value, not an array or an object.
+            </para>
+
+            <example id="zend.db.adapter.select.fetchone.example">
+                <title>Using fetchOne()</title>
+                <programlisting role="php"><![CDATA[
+$result = $db->fetchOne('SELECT bug_status FROM bugs WHERE bug_id = 2');
+
+// this is a single string value
+echo $result;
+]]>
+                </programlisting>
+            </example>
+        </sect3>
+
+    </sect2>
+
+    <sect2 id="zend.db.adapter.write">
+
+        <title>Writing Changes to the Database</title>
+
+        <para>
+            You can use the Adapter class to write new data or change
+            existing data in your database. This section describes
+            methods to do these operations.
+        </para>
+
+        <sect3 id="zend.db.adapter.write.insert">
+
+            <title>Inserting Data</title>
+
+            <para>
+                You can add new rows to a table in your database using
+                the
+                <code>insert()</code>
+                method. The first argument is a string that names the
+                table, and the second argument is an associative array,
+                mapping column names to data values.
+            </para>
+
+            <example id="zend.db.adapter.write.insert.example">
+                <title>Inserting to a table</title>
+                <programlisting role="php"><![CDATA[
+$data = array(
+    'created_on'      => '2007-03-22',
+    'bug_description' => 'Something wrong',
+    'bug_status'      => 'NEW'
+);
+
+$db->insert('bugs', $data);
+]]>
+                </programlisting>
+            </example>
+
+            <para>
+                Columns you exclude from the array of data are not
+                specified to the database. Therefore, they follow the
+                same rules that an SQL INSERT statement follows: if the
+                column has a DEFAULT clause, the column takes that value
+                in the row created, otherwise the column is left in a
+                NULL state.
+            </para>
+
+            <para>
+                By default, the values in your data array are inserted
+                using parameters. This reduces risk of some types of
+                security issues. You don't need to apply escaping or
+                quoting to values in the data array.
+            </para>
+
+            <para>
+                You might need values in the data array to be treated as
+                SQL expressions, in which case they should not be
+                quoted. By default, all data values passed as strings
+                are treated as string literals. To specify that the
+                value is an SQL expression and therefore should not be
+                quoted, pass the value in the data array as an object of
+                type Zend_Db_Expr instead of a plain string.
+            </para>
+
+            <example id="zend.db.adapter.write.insert.example2">
+                <title>Inserting expressions to a table</title>
+                <programlisting role="php"><![CDATA[
+$data = array(
+    'created_on'      => new Zend_Db_Expr('CURDATE()'),
+    'bug_description' => 'Something wrong',
+    'bug_status'      => 'NEW'
+);
+
+$db->insert('bugs', $data);
+]]>
+                </programlisting>
+            </example>
+
+        </sect3>
+
+        <sect3 id="zend.db.adapter.write.lastinsertid">
+
+            <title>Retrieving a Generated Value</title>
+
+            <para>
+                Some RDBMS brands support auto-incrementing primary
+                keys. A table defined this way generates a primary key
+                value automatically during an INSERT of a new row. The
+                return value of the
+                <code>insert()</code>
+                method is
+                <emphasis>not</emphasis>
+                the last inserted ID, because the table might not have
+                an auto-incremented column. Instead, the return value is
+                the number of rows affected (usually 1).
+            </para>
+
+            <para>
+                If your table is defined with an auto-incrementing
+                primary key, you can call the
+                <code>lastInsertId()</code>
+                method after the insert. This method returns the last
+                value generated in the scope of the current database
+                connection.
+            </para>
+
+            <example id="zend.db.adapter.write.lastinsertid.example-1">
+                <title>
+                    Using lastInsertId() for an auto-increment key
+                </title>
+                <programlisting role="php"><![CDATA[
+$db->insert('bugs', $data);
+
+// return the last value generated by an auto-increment column
+$id = $db->lastInsertId();
+]]>
+                </programlisting>
+            </example>
+
+            <para>
+                Some RDBMS brands support a sequence object, which
+                generates unique values to serve as primary key values.
+                To support sequences, the
+                <code>lastInsertId()</code>
+                method accepts two optional string arguments. These
+                arguments name the table and the column, assuming you
+                have followed the convention that a sequence is named
+                using the table and column names for which the sequence
+                generates values, and a suffix "_seq". This is based on
+                the convention used by PostgreSQL when naming sequences
+                for SERIAL columns. For example, a table "bugs" with
+                primary key column "bug_id" would use a sequence named
+                "bugs_bug_id_seq".
+            </para>
+
+            <example id="zend.db.adapter.write.lastinsertid.example-2">
+                <title>Using lastInsertId() for a sequence</title>
+                <programlisting role="php"><![CDATA[
+$db->insert('bugs', $data);
+
+// return the last value generated by sequence 'bugs_bug_id_seq'.
+$id = $db->lastInsertId('bugs', 'bug_id');
+
+// alternatively, return the last value generated by sequence 'bugs_seq'.
+$id = $db->lastInsertId('bugs');
+]]>
+                </programlisting>
+            </example>
+
+            <para>
+                If the name of your sequence object does not follow this
+                naming convention, use the
+                <code>lastSequenceId()</code>
+                method instead. This method takes a single string
+                argument, naming the sequence literally.
+            </para>
+
+            <example id="zend.db.adapter.write.lastinsertid.example-3">
+                <title>Using lastSequenceId()</title>
+                <programlisting role="php"><![CDATA[
+$db->insert('bugs', $data);
+
+// return the last value generated by sequence 'bugs_id_gen'.
+$id = $db->lastSequenceId('bugs_id_gen');
+]]>
+                </programlisting>
+            </example>
+
+            <para>
+                For RDBMS brands that don't support sequences, including
+                MySQL, Microsoft SQL Server, and SQLite, the arguments
+                to the lastInsertId() method are ignored, and the value
+                returned is the most recent value generated for any
+                table by INSERT operations during the current
+                connection. For these RDBMS brands, the lastSequenceId()
+                method always returns
+                <code>null</code>
+                .
+            </para>
+
+            <note>
+                <title>Why not use "SELECT MAX(id) FROM table"?</title>
+                <para>
+                    Sometimes this query returns the most recent primary
+                    key value inserted into the table. However, this
+                    technique is not safe to use in an environment where
+                    multiple clients are inserting records to the
+                    database. It is possible, and therefore is bound to
+                    happen eventually, that another client inserts
+                    another row in the instant between the insert
+                    performed by your client application and your query
+                    for the MAX(id) value. Thus the value returned does
+                    not identify the row you inserted, it identifies the
+                    row inserted by some other client. There is no way
+                    to know when this has happened.
+                </para>
+                <para>
+                    Using a strong transaction isolation mode such as
+                    "repeatable read" can mitigate this risk, but some
+                    RDBMS brands don't support the transaction isolation
+                    required for this, or else your application may use
+                    a lower transaction isolation mode by design.
+                </para>
+                <para>
+                    Furthermore, using an expression like "MAX(id)+1" to
+                    generate a new value for a primary key is not safe,
+                    because two clients could do this query
+                    simultaneously, and then both use the same
+                    calculated value for their next INSERT operation.
+                </para>
+                <para>
+                    All RDBMS brands provide mechanisms to generate
+                    unique values, and to return the last value
+                    generated. These mechanisms necessarily work outside
+                    of the scope of transaction isolation, so there is
+                    no chance of two clients generating the same value,
+                    and there is no chance that the value generated by
+                    another client could be reported to your client's
+                    connection as the last value generated.
+                </para>
+            </note>
+
+        </sect3>
+
+        <sect3 id="zend.db.adapter.write.update">
+            <title>Updating Data</title>
+
+            <para>
+                You can update rows in a database table using the
+                <code>update()</code>
+                method of an Adapter. This method takes three arguments:
+                the first is the name of the table; the second is an
+                associative array mapping columns to change to new
+                values to assign to these columns.
+            </para>
+
+            <para>
+                The values in the data array are treated as string
+                literals. See
+                <xref linkend="zend.db.adapter.write.insert"></xref>
+                for information on using SQL expressions in the data
+                array.
+            </para>
+
+            <para>
+                The third argument is a string containing an SQL
+                expression that is used as criteria for the rows to
+                change. The values and identifiers in this argument are
+                not quoted or escaped. You are responsible for ensuring
+                that any dynamic content is interpolated into this
+                string safely. See
+                <xref linkend="zend.db.adapter.quoting"></xref>
+                for methods to help you do this.
+            </para>
+
+            <para>
+                The return value is the number of rows affected by the
+                update operation.
+            </para>
+
+            <example id="zend.db.adapter.write.update.example">
+                <title>Updating rows</title>
+                <programlisting role="php"><![CDATA[
+$data = array(
+    'updated_on'      => '2007-03-23',
+    'bug_status'      => 'FIXED'
+);
+
+$n = $db->update('bugs', $data, 'bug_id = 2');
+]]>
+                </programlisting>
+            </example>
+
+            <para>
+                If you omit the third argument, then all rows in the
+                database table are updated with the values specified in
+                the data array.
+            </para>
+
+            <para>
+                If you provide an array of strings as the third
+                argument, these strings are joined together as terms in
+                an expression separated by
+                <code>AND</code>
+                operators.
+            </para>
+
+            <example id="zend.db.adapter.write.update.example-array">
+                <title>
+                    Updating rows using an array of expressions
+                </title>
+                <programlisting role="php"><![CDATA[
+$data = array(
+    'updated_on'      => '2007-03-23',
+    'bug_status'      => 'FIXED'
+);
+
+$where[] = "reported_by = 'goofy'";
+$where[] = "bug_status = 'OPEN'";
+
+$n = $db->update('bugs', $data, $where);
+
+// Resulting SQL is:
+//  UPDATE "bugs" SET "update_on" = '2007-03-23', "bug_status" = 'FIXED'
+//  WHERE ("reported_by" = 'goofy') AND ("bug_status" = 'OPEN')
+]]>
+                </programlisting>
+            </example>
+
+        </sect3>
+
+        <sect3 id="zend.db.adapter.write.delete">
+            <title>Deleting Data</title>
+            <para>
+                You can delete rows from a database table using the
+                <code>delete()</code>
+                method. This method takes two arguments: the first is a
+                string naming the table.
+            </para>
+
+            <para>
+                The second argument is a string containing an SQL
+                expression that is used as criteria for the rows to
+                delete. The values and identifiers in this argument are
+                not quoted or escaped. You are responsible for ensuring
+                that any dynamic content is interpolated into this
+                string safely. See
+                <xref linkend="zend.db.adapter.quoting"></xref>
+                for methods to help you do this.
+            </para>
+
+            <para>
+                The return value is the number of rows affected by the
+                delete operation.
+            </para>
+
+            <example id="zend.db.adapter.write.delete.example">
+                <title>Deleting rows</title>
+                <programlisting role="php"><![CDATA[
+$n = $db->delete('bugs', 'bug_id = 3');
+]]>
+                </programlisting>
+            </example>
+
+            <para>
+                If you omit the second argument, the result is that all
+                rows in the database table are deleted.
+            </para>
+
+            <para>
+                If you provide an array of strings as the second
+                argument, these strings are joined together as terms in
+                an expression separated by
+                <code>AND</code>
+                operators.
+            </para>
+
+        </sect3>
+
+    </sect2>
+
+    <sect2 id="zend.db.adapter.quoting">
+
+        <title>Quoting Values and Identifiers</title>
+
+        <para>
+            When you form SQL queries, often it is the case that you
+            need to include the values of PHP variables in SQL
+            expressions. This is risky, because if the value in a PHP
+            string contains certain symbols, such as the quote symbol,
+            it could result in invalid SQL. For example, notice the
+            imbalanced quote characters in the following query:
+            <programlisting role="php"><![CDATA[
+$name = "O'Reilly";
+$sql = "SELECT * FROM bugs WHERE reported_by = '$name'";
+
+echo $sql;
+// SELECT * FROM bugs WHERE reported_by = 'O'Reilly'
+]]>
+            </programlisting>
+        </para>
+
+        <para>
+            Even worse is the risk that such code mistakes might be
+            exploited deliberately by a person who is trying to
+            manipulate the function of your web application. If they can
+            specify the value of a PHP variable through the use of an
+            HTTP parameter or other mechanism, they might be able to
+            make your SQL queries do things that you didn't intend them
+            to do, such as return data to which the person should not
+            have privilege to read. This is a serious and widespread
+            technique for violating application security, known as "SQL
+            Injection" (see
+            <ulink url="http://en.wikipedia.org/wiki/SQL_Injection">
+                http://en.wikipedia.org/wiki/SQL_Injection
+            </ulink>
+            ).
+        </para>
+
+        <para>
+            The Zend_Db Adapter class provides convenient functions to
+            help you reduce vulnerabilities to SQL Injection attacks in
+            your PHP code. The solution is to escape special characters
+            such as quotes in PHP values before they are interpolated
+            into your SQL strings. This protects against both accidental
+            and deliberate manipulation of SQL strings by PHP variables
+            that contain special characters.
+        </para>
+
+        <sect3 id="zend.db.adapter.quoting.quote">
+
+            <title>
+                Using
+                <code>quote()</code>
+            </title>
+
+            <para>
+                The
+                <code>quote()</code>
+                method accepts a single argument, a scalar string value.
+                It returns the value with special characters escaped in
+                a manner appropriate for the RDBMS you are using, and
+                surrounded by string value delimiters. The standard SQL
+                string value delimiter is the single-quote (
+                <code>'</code>
+                ).
+            </para>
+
+            <example id="zend.db.adapter.quoting.quote.example">
+                <title>Using quote()</title>
+                <programlisting role="php"><![CDATA[
+$name = $db->quote("O'Reilly");
+echo $name;
+// 'O\'Reilly'
+
+$sql = "SELECT * FROM bugs WHERE reported_by = $name";
+
+echo $sql;
+// SELECT * FROM bugs WHERE reported_by = 'O\'Reilly'
+]]>
+                </programlisting>
+            </example>
+
+            <para>
+                Note that the return value of
+                <code>quote()</code>
+                includes the quote delimiters around the string. This is
+                different from some functions that escape special
+                characters but do not add the quote delimiters, for
+                example
+                <ulink url="http://www.php.net/mysqli_real_escape_string">
+                    mysql_real_escape_string()
+                </ulink>
+                .
+            </para>
+
+            <para>
+                Values may need to be quoted or not quoted according to
+                the SQL datatype context in which they are used. For
+                instance, in some RDBMS brands, an integer value must
+                not be quoted as a string if it is compared to an
+                integer-type column or expression. In other words, the
+                following is an error in some SQL implementations,
+                assuming
+                <code>intColumn</code>
+                has a SQL datatype of
+                <code>INTEGER</code>
+
+                <programlisting role="php"><![CDATA[
+SELECT * FROM atable WHERE intColumn = '123'
+]]>
+                </programlisting>
+            </para>
+
+            <para>
+                You can use the optional second argument to the
+                <code>quote()</code>
+                method to apply quoting selectively for the SQL datatype
+                you specify.
+            </para>
+
+            <example id="zend.db.adapter.quoting.quote.example-2">
+                <title>Using quote() with a SQL type</title>
+                <programlisting role="php"><![CDATA[
+$value = '1234';
+$sql = 'SELECT * FROM atable WHERE intColumn = '
+     . $db->quote($value, 'INTEGER');
+]]>
+                </programlisting>
+            </example>
+
+            <para>
+                Each Zend_Db_Adapter class has encoded the names of
+                numeric SQL datatypes for the respective brand of RDBMS.
+                You can also use the constants
+                <code>Zend_Db::INT_TYPE</code>
+                ,
+                <code>Zend_Db::BIGINT_TYPE</code>
+                , and
+                <code>Zend_Db::FLOAT_TYPE</code>
+                to write code in a more RDBMS-independent way.
+            </para>
+
+            <para>
+                Zend_Db_Table specifies SQL types to
+                <code>quote()</code>
+                automatically when generating SQL queries that reference
+                a table's key columns.
+            </para>
+
+        </sect3>
+
+        <sect3 id="zend.db.adapter.quoting.quote-into">
+
+            <title>
+                Using
+                <code>quoteInto()</code>
+            </title>
+
+            <para>
+                The most typical usage of quoting is to interpolate a
+                PHP variable into a SQL expression or statement. You can
+                use the
+                <code>quoteInto()</code>
+                method to do this in one step. This method takes two
+                arguments: the first argument is a string containing a
+                placeholder symbol (
+                <code>?</code>
+                ), and the second argument is a value or PHP variable
+                that should be substituted for that placeholder.
+            </para>
+
+            <para>
+                The placeholder symbol is the same symbol used by many
+                RDBMS brands for positional parameters, but the
+                <code>quoteInto()</code>
+                method only emulates query parameters. The method simply
+                interpolates the value into the string, escapes special
+                characters, and applies quotes around it. True query
+                parameters maintain the separation between the SQL
+                string and the parameters as the statement is parsed in
+                the RDBMS server.
+            </para>
+
+            <example id="zend.db.adapter.quoting.quote-into.example">
+                <title>Using quoteInto()</title>
+                <programlisting role="php"><![CDATA[
+$sql = $db->quoteInto("SELECT * FROM bugs WHERE reported_by = ?", "O'Reilly");
+
+echo $sql;
+// SELECT * FROM bugs WHERE reported_by = 'O\'Reilly'
+]]>
+                </programlisting>
+            </example>
+
+            <para>
+                You can use the optional third parameter of
+                <code>quoteInto()</code>
+                to specify the SQL datatype. Numeric datatypes are not
+                quoted, and other types are quoted.
+            </para>
+
+            <example id="zend.db.adapter.quoting.quote-into.example-2">
+                <title>Using quoteInto() with a SQL type</title>
+                <programlisting role="php"><![CDATA[
+$sql = $db
+    ->quoteInto("SELECT * FROM bugs WHERE bug_id = ?", '1234', 'INTEGER');
+
+echo $sql;
+// SELECT * FROM bugs WHERE reported_by = 1234
+]]>
+                </programlisting>
+            </example>
+
+        </sect3>
+        <sect3 id="zend.db.adapter.quoting.quote-identifier">
+
+            <title>
+                Using
+                <code>quoteIdentifier()</code>
+            </title>
+
+            <para>
+                Values are not the only part of SQL syntax that might
+                need to be variable. If you use PHP variables to name
+                tables, columns, or other identifiers in your SQL
+                statements, you might need to quote these strings too.
+                By default, SQL identifiers have syntax rules like PHP
+                and most other programming languages. For example,
+                identifiers should not contain spaces, certain
+                punctuation or special characters, or international
+                characters. Also certain words are reserved for SQL
+                syntax, and should not be used as identifiers.
+            </para>
+
+            <para>
+                However, SQL has a feature called
+                <emphasis>delimited identifiers</emphasis>
+                , which allows broader choices for the spelling of
+                identifiers. If you enclose a SQL identifier in the
+                proper types of quotes, you can use identifiers with
+                spellings that would be invalid without the quotes.
+                Delimited identifiers can contain spaces, punctuation,
+                or international characters. You can also use SQL
+                reserved words if you enclose them in identifier
+                delimiters.
+            </para>
+
+            <para>
+                The
+                <code>quoteIdentifier()</code>
+                method works like
+                <code>quote()</code>
+                , but it applies the identifier delimiter characters to
+                the string according to the type of Adapter you use. For
+                example, standard SQL uses double-quotes (
+                <code>"</code>
+                ) for identifier delimiters, and most RDBMS brands use
+                that symbol. MySQL uses back-quotes (
+                <code>`</code>
+                ) by default. The
+                <code>quoteIdentifier()</code>
+                method also escapes special characters within the string
+                argument.
+            </para>
+
+            <example id="zend.db.adapter.quoting.quote-identifier.example">
+                <title>Using quoteIdentifier()</title>
+                <programlisting role="php"><![CDATA[
+// we might have a table name that is an SQL reserved word
+$tableName = $db->quoteIdentifier("order");
+
+$sql = "SELECT * FROM $tableName";
+
+echo $sql
+// SELECT * FROM "order"
+]]>
+                </programlisting>
+            </example>
+
+            <para>
+                SQL delimited identifiers are case-sensitive, unlike
+                unquoted identifiers. Therefore, if you use delimited
+                identifiers, you must use the spelling of the identifier
+                exactly as it is stored in your schema, including the
+                case of the letters.
+            </para>
+
+            <para>
+                In most cases where SQL is generated within Zend_Db
+                classes, the default is that all identifiers are
+                delimited automatically. You can change this behavior
+                with the option
+                <code>Zend_Db::AUTO_QUOTE_IDENTIFIERS</code>
+                . Specify this when instantiating the Adapter. See
+                <xref linkend="zend.db.adapter.connecting.parameters.example2"></xref>
+                .
+            </para>
+
+        </sect3>
+
+    </sect2>
+
+    <sect2 id="zend.db.adapter.transactions">
+
+        <title>Controlling Database Transactions</title>
+
+        <para>
+            Databases define transactions as logical units of work that
+            can be committed or rolled back as a single change, even if
+            they operate on multiple tables. All queries to a database
+            are executed within the context of a transaction, even if
+            the database driver manages them implicitly. This is called
+            <emphasis>auto-commit</emphasis>
+            mode, in which the database driver creates a transaction for
+            every statement you execute, and commits that transaction
+            after your SQL statement has been executed. By default, all
+            Zend_Db Adapter classes operate in auto-commit mode.
+        </para>
+
+        <para>
+            Alternatively, you can specify the beginning and resolution
+            of a transaction, and thus control how many SQL queries are
+            included in a single group that is committed (or rolled
+            back) as a single operation. Use the
+            <code>beginTransaction()</code>
+            method to initiate a transaction. Subsequent SQL statements
+            are executed in the context of the same transaction until
+            you resolve it explicitly.
+        </para>
+
+        <para>
+            To resolve the transaction, use either the
+            <code>commit()</code>
+            or
+            <code>rollBack()</code>
+            methods. The
+            <code>commit()</code>
+            method marks changes made during your transaction as
+            committed, which means the effects of these changes are
+            shown in queries run in other transactions.
+        </para>
+
+        <para>
+            The
+            <code>rollBack()</code>
+            method does the opposite: it discards the changes made
+            during your transaction. The changes are effectively undone,
+            and the state of the data returns to how it was before you
+            began your transaction. However, rolling back your
+            transaction has no effect on changes made by other
+            transactions running concurrently.
+        </para>
+
+        <para>
+            After you resolve this transaction,
+            <code>Zend_Db_Adapter</code>
+            returns to auto-commit mode until you call
+            <code>beginTransaction()</code>
+            again.
+        </para>
+
+        <example id="zend.db.adapter.transactions.example">
+            <title>Managing a transaction to ensure consistency</title>
+            <programlisting role="php"><![CDATA[
+// Start a transaction explicitly.
+$db->beginTransaction();
+
+try {
+    // Attempt to execute one or more queries:
+    $db->query(...);
+    $db->query(...);
+    $db->query(...);
+
+    // If all succeed, commit the transaction and all changes
+    // are committed at once.
+    $db->commit();
+
+} catch (Exception $e) {
+    // If any of the queries failed and threw an exception,
+    // we want to roll back the whole transaction, reversing
+    // changes made in the transaction, even those that succeeded.
+    // Thus all changes are committed together, or none are.
+    $db->rollBack();
+    echo $e->getMessage();
+}
+]]>
+            </programlisting>
+        </example>
+
+    </sect2>
+
+    <sect2 id="zend.db.adapter.list-describe">
+
+        <title>Listing and Describing Tables</title>
+
+        <para>
+            The
+            <code>listTables()</code>
+            method returns an array of strings, naming all tables in the
+            current database.
+        </para>
+
+        <para>
+            The
+            <code>describeTable()</code>
+            method returns an associative array of metadata about a
+            table. Specify the name of the table as a string in the
+            first argument to this method. The second argument is
+            optional, and names the schema in which the table exists.
+        </para>
+
+        <para>
+            The keys of the associative array returned are the column
+            names of the table. The value corresponding to each column
+            is also an associative array, with the following keys and
+            values:
+        </para>
+
+        <table frame="all" cellpadding="5" id="zend.db.adapter.list-describe.metadata">
+            <title>Metadata fields returned by describeTable()</title>
+            <tgroup cols="3" align="left" colsep="1" rowsep="1">
+                <thead>
+                    <row>
+                        <entry>Key</entry>
+                        <entry>Type</entry>
+                        <entry>Description</entry>
+                    </row>
+                </thead>
+                <tbody>
+                    <row>
+                        <entry>SCHEMA_NAME</entry>
+                        <entry>(string)</entry>
+                        <entry>
+                            Name of the database schema in which this
+                            table exists.
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>TABLE_NAME</entry>
+                        <entry>(string)</entry>
+                        <entry>
+                            Name of the table to which this column
+                            belongs.
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>COLUMN_NAME</entry>
+                        <entry>(string)</entry>
+                        <entry>Name of the column.</entry>
+                    </row>
+                    <row>
+                        <entry>COLUMN_POSITION</entry>
+                        <entry>(integer)</entry>
+                        <entry>
+                            Ordinal position of the column in the table.
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>DATA_TYPE</entry>
+                        <entry>(string)</entry>
+                        <entry>
+                            RDBMS name of the datatype of the column.
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>DEFAULT</entry>
+                        <entry>(string)</entry>
+                        <entry>
+                            Default value for the column, if any.
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>NULLABLE</entry>
+                        <entry>(boolean)</entry>
+                        <entry>
+                            True if the column accepts SQL NULLs, false
+                            if the column has a NOT NULL constraint.
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>LENGTH</entry>
+                        <entry>(integer)</entry>
+                        <entry>
+                            Length or size of the column as reported by
+                            the RDBMS.
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>SCALE</entry>
+                        <entry>(integer)</entry>
+                        <entry>
+                            Scale of SQL NUMERIC or DECIMAL type.
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>PRECISION</entry>
+                        <entry>(integer)</entry>
+                        <entry>
+                            Precision of SQL NUMERIC or DECIMAL type.
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>UNSIGNED</entry>
+                        <entry>(boolean)</entry>
+                        <entry>
+                            True if an integer-based type is reported as
+                            UNSIGNED.
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>PRIMARY</entry>
+                        <entry>(boolean)</entry>
+                        <entry>
+                            True if the column is part of the primary
+                            key of this table.
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>PRIMARY_POSITION</entry>
+                        <entry>(integer)</entry>
+                        <entry>
+                            Ordinal position (1-based) of the column in
+                            the primary key.
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>IDENTITY</entry>
+                        <entry>(boolean)</entry>
+                        <entry>
+                            True if the column uses an auto-generated
+                            value.
+                        </entry>
+                    </row>
+                </tbody>
+            </tgroup>
+        </table>
+
+        <note>
+            <title>
+                How the IDENTITY metadata field relates to specific
+                RDBMS
+            </title>
+            <para>
+                The IDENTITY metadata field was chosen as an 'idiomatic'
+                term to represent a relation to surrogate keys. This
+                field can be commonly known by the following values:-
+            </para>
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        <code>IDENTITY</code>
+                        - DB2, MSSQL
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <code>AUTO_INCREMENT</code>
+                        - MySQL
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <code>SERIAL</code>
+                        - PostgreSQL
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <code>SEQUENCE</code>
+                        - Oracle
+                    </para>
+                </listitem>
+            </itemizedlist>
+        </note>
+
+        <para>
+            If no table exists matching the table name and optional
+            schema name specified, then
+            <code>describeTable()</code>
+            returns an empty array.
+        </para>
+
+    </sect2>
+
+    <sect2 id="zend.db.adapter.closing">
+
+        <title>Closing a Connection</title>
+
+        <para>
+            Normally it is not necessary to close a database connection.
+            PHP automatically cleans up all resources and the end of a
+            request. Database extensions are designed to close the
+            connection as the reference to the resource object is
+            cleaned up.
+        </para>
+
+        <para>
+            However, if you have a long-duration PHP script that
+            initiates many database connections, you might need to close
+            the connection, to avoid exhausting the capacity of your
+            RDBMS server. You can use the Adapter's
+            <code>closeConnection()</code>
+            method to explicitly close the underlying database
+            connection.
+        </para>
+
+        <example id="zend.db.adapter.closing.example">
+            <title>Closing a database connection</title>
+            <programlisting role="php"><![CDATA[
+$db->closeConnection();
+]]>
+            </programlisting>
+        </example>
+
+        <note>
+            <title>Does Zend_Db support persistent connections?</title>
+            <para>
+                The usage of persistent connections is not supported or
+                encouraged in Zend_Db.
+            </para>
+            <para>
+                Using persistent connections can cause an excess of idle
+                connections on the RDBMS server, which causes more
+                problems than any performance gain you might achieve by
+                reducing the overhead of making connections.
+            </para>
+            <para>
+                Database connections have state. That is, some objects
+                in the RDBMS server exist in session scope. Examples are
+                locks, user variables, temporary tables, and information
+                about the most recently executed query, such as rows
+                affected, and last generated id value. If you use
+                persistent connections, your application could access
+                invalid or privileged data that were created in a
+                previous PHP request.
+            </para>
+        </note>
+
+    </sect2>
+
+    <sect2 id="zend.db.adapter.other-statements">
+
+        <title>Running Other Database Statements</title>
+
+        <para>
+            There might be cases in which you need to access the
+            connection object directly, as provided by the PHP database
+            extension. Some of these extensions may offer features that
+            are not surfaced by methods of Zend_Db_Adapter_Abstract.
+        </para>
+
+        <para>
+            For example, all SQL statements run by Zend_Db are prepared,
+            then executed. However, some database features are
+            incompatible with prepared statements. DDL statements like
+            CREATE and ALTER cannot be prepared in MySQL. Also, SQL
+            statements don't benefit from the
+            <ulink url="http://dev.mysql.com/doc/refman/5.1/en/query-cache-how.html">
+                MySQL Query Cache
+            </ulink>
+            , prior to MySQL 5.1.17.
+        </para>
+
+        <para>
+            Most PHP database extensions provide a method to execute SQL
+            statements without preparing them. For example, in PDO, this
+            method is
+            <code>exec()</code>
+            . You can access the connection object in the PHP extension
+            directly using getConnection().
+        </para>
+
+        <example id="zend.db.adapter.other-statements.example">
+            <title>
+                Running a non-prepared statement in a PDO adapter
+            </title>
+            <programlisting role="php"><![CDATA[
+$result = $db->getConnection()->exec('DROP TABLE bugs');
+]]>
+            </programlisting>
+        </example>
+
+        <para>
+            Similarly, you can access other methods or properties that
+            are specific to PHP database extensions. Be aware, though,
+            that by doing this you might constrain your application to
+            the interface provided by the extension for a specific brand
+            of RDBMS.
+        </para>
+
+        <para>
+            In future versions of Zend_Db, there will be opportunities
+            to add method entry points for functionality that is common
+            to the supported PHP database extensions. This will not
+            affect backward compatibility.
+        </para>
+
+    </sect2>
+
+    <sect2 id="zend.db.adapter.adapter-notes">
+
+        <title>Notes on Specific Adapters</title>
+
+        <para>
+            This section lists differences between the Adapter classes
+            of which you should be aware.
+        </para>
+
+        <sect3 id="zend.db.adapter.adapter-notes.ibm-db2">
+            <title>IBM DB2</title>
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        Specify this Adapter to the factory() method
+                        with the name 'Db2'.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        This Adapter uses the PHP extension ibm_db2.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        IBM DB2 supports both sequences and
+                        auto-incrementing keys. Therefore the arguments
+                        to
+                        <code>lastInsertId()</code>
+                        are optional. If you give no arguments, the
+                        Adapter returns the last value generated for an
+                        auto-increment key. If you give arguments, the
+                        Adapter returns the last value generated by the
+                        sequence named according to the convention '
+                        <emphasis>table</emphasis>
+                        _
+                        <emphasis>column</emphasis>
+                        _seq'.
+                    </para>
+                </listitem>
+            </itemizedlist>
+        </sect3>
+
+        <sect3 id="zend.db.adapter.adapter-notes.mysqli">
+            <title>MySQLi</title>
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        Specify this Adapter to the
+                        <code>factory()</code>
+                        method with the name 'Mysqli'.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        This Adapter utilizes the PHP extension mysqli.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        MySQL does not support sequences, so
+                        <code>lastInsertId()</code>
+                        ignores its arguments and always returns the
+                        last value generated for an auto-increment key.
+                        The
+                        <code>lastSequenceId()</code>
+                        method returns
+                        <code>null</code>
+                        .
+                    </para>
+                </listitem>
+            </itemizedlist>
+        </sect3>
+
+        <sect3 id="zend.db.adapter.adapter-notes.oracle">
+            <title>Oracle</title>
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        Specify this Adapter to the
+                        <code>factory()</code>
+                        method with the name 'Oracle'.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        This Adapter uses the PHP extension oci8.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        Oracle does not support auto-incrementing keys,
+                        so you should specify the name of a sequence to
+                        <code>lastInsertId()</code>
+                        or
+                        <code>lastSequenceId()</code>
+                        .
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        The Oracle extension does not support positional
+                        parameters. You must use named parameters.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        Currently the
+                        <code>Zend_Db::CASE_FOLDING</code>
+                        option is not supported by the Oracle adapter.
+                        To use this option with Oracle, you must use the
+                        PDO OCI adapter.
+                    </para>
+                </listitem>
+            </itemizedlist>
+        </sect3>
+
+        <sect3 id="zend.db.adapter.adapter-notes.pdo-ibm">
+            <title>
+                PDO for IBM DB2 and Informix Dynamic Server (IDS)
+            </title>
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        Specify this Adapter to the
+                        <code>factory()</code>
+                        method with the name 'Pdo_Ibm'.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        This Adapter uses the PHP extensions pdo and
+                        pdo_ibm.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        You must use at least PDO_IBM extension version
+                        1.2.2. If you have an earlier version of this
+                        extension, you must upgrade the PDO_IBM
+                        extension from PECL.
+                    </para>
+                </listitem>
+            </itemizedlist>
+        </sect3>
+
+        <sect3 id="zend.db.adapter.adapter-notes.pdo-mssql">
+            <title>PDO Microsoft SQL Server</title>
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        Specify this Adapter to the
+                        <code>factory()</code>
+                        method with the name 'Pdo_Mssql'.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        This Adapter uses the PHP extensions pdo and
+                        pdo_mssql.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        Microsoft SQL Server does not support sequences,
+                        so
+                        <code>lastInsertId()</code>
+                        ignores its arguments and always returns the
+                        last value generated for an auto-increment key.
+                        The
+                        <code>lastSequenceId()</code>
+                        method returns
+                        <code>null</code>
+                        .
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        If you are working with unicode strings in an
+                        encoding other than UCS-2 (such as UTF-8), you
+                        may have to perform a conversion in your
+                        application code or store the data in a binary
+                        column. Please refer to
+                        <ulink url="http://support.microsoft.com/kb/232580">
+                            Microsoft's Knowledge Base
+                        </ulink>
+                        for more information.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        Zend_Db_Adapter_Pdo_Mssql sets
+                        <code>QUOTED_IDENTIFIER ON</code>
+                        immediately after connecting to a SQL Server
+                        database. This makes the driver use the standard
+                        SQL identifier delimiter symbol (
+                        <code>"</code>
+                        ) instead of the proprietary square-brackets
+                        syntax SQL Server uses for delimiting
+                        identifiers.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        You can specify
+                        <code>pdoType</code>
+                        as a key in the options array. The value can be
+                        "mssql" (the default), "dblib", "freetds", or
+                        "sybase". This option affects the DSN prefix the
+                        adapter uses when constructing the DSN string.
+                        Both "freetds" and "sybase" imply a prefix of
+                        "sybase:", which is used for the
+                        <ulink url="http://www.freetds.org/">
+                            FreeTDS
+                        </ulink>
+                        set of libraries. See also
+                        <ulink url="http://www.php.net/manual/en/ref.pdo-dblib.connection.php">
+                            http://www.php.net/manual/en/ref.pdo-dblib.connection.php
+                        </ulink>
+                        for more information on the DSN prefixes used in
+                        this driver.
+                    </para>
+                </listitem>
+            </itemizedlist>
+        </sect3>
+
+        <sect3 id="zend.db.adapter.adapter-notes.pdo-mysql">
+            <title>PDO MySQL</title>
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        Specify this Adapter to the
+                        <code>factory()</code>
+                        method with the name 'Pdo_Mysql'.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        This Adapter uses the PHP extensions pdo and
+                        pdo_mysql.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        MySQL does not support sequences, so
+                        <code>lastInsertId()</code>
+                        ignores its arguments and always returns the
+                        last value generated for an auto-increment key.
+                        The
+                        <code>lastSequenceId()</code>
+                        method returns
+                        <code>null</code>
+                        .
+                    </para>
+                </listitem>
+            </itemizedlist>
+        </sect3>
+
+        <sect3 id="zend.db.adapter.adapter-notes.pdo-oci">
+            <title>PDO Oracle</title>
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        Specify this Adapter to the
+                        <code>factory()</code>
+                        method with the name 'Pdo_Oci'.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        This Adapter uses the PHP extensions pdo and
+                        pdo_oci.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        Oracle does not support auto-incrementing keys,
+                        so you should specify the name of a sequence to
+                        <code>lastInsertId()</code>
+                        or
+                        <code>lastSequenceId()</code>
+                        .
+                    </para>
+                </listitem>
+            </itemizedlist>
+        </sect3>
+
+        <sect3 id="zend.db.adapter.adapter-notes.pdo-pgsql">
+            <title>PDO PostgreSQL</title>
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        Specify this Adapter to the
+                        <code>factory()</code>
+                        method with the name 'Pdo_Pgsql'.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        This Adapter uses the PHP extensions pdo and
+                        pdo_pgsql.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        PostgreSQL supports both sequences and
+                        auto-incrementing keys. Therefore the arguments
+                        to
+                        <code>lastInsertId()</code>
+                        are optional. If you give no arguments, the
+                        Adapter returns the last value generated for an
+                        auto-increment key. If you give arguments, the
+                        Adapter returns the last value generated by the
+                        sequence named according to the convention '
+                        <emphasis>table</emphasis>
+                        _
+                        <emphasis>column</emphasis>
+                        _seq'.
+                    </para>
+                </listitem>
+            </itemizedlist>
+        </sect3>
+
+        <sect3 id="zend.db.adapter.adapter-notes.pdo-sqlite">
+            <title>PDO SQLite</title>
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        Specify this Adapter to the
+                        <code>factory()</code>
+                        method with the name 'Pdo_Sqlite'.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        This Adapter uses the PHP extensions pdo and
+                        pdo_sqlite.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        SQLite does not support sequences, so
+                        <code>lastInsertId()</code>
+                        ignores its arguments and always returns the
+                        last value generated for an auto-increment key.
+                        The
+                        <code>lastSequenceId()</code>
+                        method returns
+                        <code>null</code>
+                        .
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        To connect to an SQLite2 database, specify
+                        <code>'sqlite2'=&gt;true</code>
+                        in the array of parameters when creating an
+                        instance of the Pdo_Sqlite Adapter.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        To connect to an in-memory SQLite database,
+                        specify
+                        <code>'dbname'=&gt;':memory:'</code>
+                        in the array of parameters when creating an
+                        instance of the Pdo_Sqlite Adapter.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        Older versions of the SQLite driver for PHP do
+                        not seem to support the PRAGMA commands
+                        necessary to ensure that short column names are
+                        used in result sets. If you have problems that
+                        your result sets are returned with keys of the
+                        form "tablename.columnname" when you do a join
+                        query, then you should upgrade to the current
+                        version of PHP.
+                    </para>
+                </listitem>
+            </itemizedlist>
+        </sect3>
+
+        <sect3 id="zend.db.adapter.adapter-notes.firebird">
+            <title>Firebird/Interbase</title>
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        This Adapter uses the PHP extension
+                        php_interbase.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        Firebird/interbase does not support
+                        auto-incrementing keys, so you should specify
+                        the name of a sequence to
+                        <code>lastInsertId()</code>
+                        or
+                        <code>lastSequenceId()</code>
+                        .
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        Currently the
+                        <code>Zend_Db::CASE_FOLDING</code>
+                        option is not supported by the
+                        Firebird/interbase adapter. Unquoted identifiers
+                        are automatically returned in upper case.
+                    </para>
+                </listitem>
+            </itemizedlist>
+        </sect3>
+
+
+    </sect2>
+
+</sect1>
+<!--
+    vim:se ts=4 sw=4 et:
+-->

+ 6 - 6
documentation/manual/es/module_specs/Zend_Db_Select.xml

@@ -105,7 +105,7 @@ $select = new Zend_Db_Select($db);
 
         <title>Construyendo consultas Select</title>
 
-        <para>Cuando se construye una consulta, puede agregar clausulas a esta, una por una.
+        <para>Cuando se construye una consulta, puede agregar clausulas a esta, una por una.
             Hay un método separado para agregar cada al objeto Zend_Db_Select.</para>
 
         <example id="zend.db.select.building.example">
@@ -129,8 +129,8 @@ $select->order( ...specify sorting criteria... );
 
         </example>
 
-        <para>También puede utilizar la mayoría de los métodos del objeto Zend_Db_Select con una 
-            interfaz fluida. Una interfaz fluida significa que cada método retorna una referencia
+        <para>También puede utilizar la mayoría de los métodos del objeto Zend_Db_Select con una 
+            interfaz fluida. Una interfaz fluida significa que cada método retorna una referencia
             al objeto que se ha llamado, así puedes llamar inmediatamente a otro método.</para>
 
         <example id="zend.db.select.building.example-fluent">
@@ -147,9 +147,9 @@ $select = $db->select()
 
         </example>
 
-        <para>Los ejemplos en esta sección muestran el uso de la interfaz fluída, pero también
-            puedes usar la interfaz no-fluída en todos los casos. A menudo es necesario
-            utilizar la interfaz no-fluída, por ejemplo, si su aplicación necesita realizar
+        <para>Los ejemplos en esta sección muestran el uso de la interfaz fluída, pero también
+            puedes usar la interfaz no-fluída en todos los casos. A menudo es necesario
+            utilizar la interfaz no-fluída, por ejemplo, si su aplicación necesita realizar
             cierta lógica antes de añadir una cláusula a la consulta.</para>
 
         <sect3 id="zend.db.select.building.from">

+ 15 - 15
documentation/manual/es/module_specs/Zend_Exception.xml

@@ -1,15 +1,15 @@
-<sect1 id="zend.exception.using">
-
-    <title>Usando Excepciones</title>
-
-    <para>
-        Todas las excepciones lanzadas por las clases de Zend Framework
-        deberian arrojar una excepción que deriva de la clase base
-        Zend_Exception.
-    </para>
-
-    <example id="zend.exception.using.example">
-        <title>Ejemplo de catching de una excepción</title>
+<sect1 id="zend.exception.using">
+
+    <title>Usando Excepciones</title>
+
+    <para>
+        Todas las excepciones lanzadas por las clases de Zend Framework
+        deberian arrojar una excepción que deriva de la clase base
+        Zend_Exception.
+    </para>
+
+    <example id="zend.exception.using.example">
+        <title>Ejemplo de catching de una excepción</title>
         <programlisting role="php"><![CDATA[
 try {
     Zend_Loader::loadClass('clasenoexistente');
@@ -30,6 +30,6 @@ try {
     </para>
 
 </sect1>
-<!--
-    vim:se ts=4 sw=4 et:
--->
+<!--
+    vim:se ts=4 sw=4 et:
+-->

+ 1502 - 1502
documentation/manual/es/module_specs/Zend_Form-Elements.xml

@@ -1,1502 +1,1502 @@
-<sect1 id="zend.form.elements">
-    <title>Creando elementos de formulario usando Zend_Form_Element</title>
-
-    <para>
-        Un formulario esta compuesto de elementos, que normalmente corresponden 
-        al  elemento HTML input. <code>Zend_Form_Element</code> encapsula
-        elementos de formulario individualmente, con las siguientes áreas de 
-        responsabilidad:
-    </para>
-
-    <itemizedlist>
-        <listitem>
-            <para>
-                validación (¿los datos enviados son válidos?)
-            </para>
-
-            <itemizedlist>
-                <listitem><para>captura de códigos y mensajes de error</para></listitem>
-            </itemizedlist>
-        </listitem>
-
-        <listitem><para>
-            filtrado (¿cómo es escapado y normalizado el elemento para su 
-            validación y/o salida?
-        </para></listitem>
-
-        <listitem><para>
-            generación (¿cómo es mostrado el elemento?)
-        </para></listitem>
-
-        <listitem><para>
-            metadatos y atributos (¿qué información amplía la definición del
-            elemento?)
-        </para></listitem>
-    </itemizedlist>
-
-    <para>
-        La clase base, <code>Zend_Form_Element</code>, funciona por defecto para
-        varios casos, pero es mejor extender la clase para elementos con fines 
-        especiales de uso común. Adicionalmente, Zend Framework contiene un 
-        número de elementos XHTML estándar; puede leer de ellos <link linkend="zend.form.standardElements">en el capítulo Elementos
-        Estándares</link>
-    </para>
-
-    <sect2 id="zend.form.elements.loaders">
-        <title>Cargadores de Plugin</title>
-
-        <para>
-            <code>Zend_Form_Element</code> hace uso de <link linkend="zend.loader.pluginloader">Zend_Loader_PluginLoader</link>
-            para permitir a los desarrolladores especificar ubicaciones de
-            validadores, filtros y decoradores alternos. Cada uno tiene su 
-            propio cargador de plugin asociado a él y métodos de acceso 
-            generales usados para su recuperación y modificación.
-        </para>
-
-        <para>
-            Los siguientes tipos de cargadores son usados con los varios métodos
-            del cargador de plugin: 'validate', 'filter', y 'decorator'. Los
-            nombres son sensibles a mayúsculas y minúsculas.
-        </para>
-
-        <para>
-            Los métodos usados para interactuar con los cargadores de plugin son 
-            los siguientes:
-        </para>
-
-        <itemizedlist>
-            <listitem><para>
-                <code>setPluginLoader($loader, $type)</code>:
-                <code>$loader</code> es el propio objeto cargador, mientras
-                <code>$type</code> es uno de los tipos arriba mencionados. Esto
-                establece el cargador de plugin para el tipo dado en el objeto
-                cargador recién especificado.
-            </para></listitem>
-
-            <listitem><para>
-                <code>getPluginLoader($type)</code>: obtiene el cargador de
-                plugin asociado con <code>$type</code>.
-            </para></listitem>
-
-            <listitem><para>
-                <code>addPrefixPath($prefix, $path, $type = null)</code>: agrega
-                una asociación prefijo/ruta para el cargador especificado por
-                <code>$type</code>. Si <code>$type</code> es null, se intentará
-                agregar la ruta a todos los cargadores, añadiendo el prefijo a
-                cada "_Validate", "_Filter" y "_Decorator"; y agregandole
-                "Validate/", "Filter/" y "Decorator/" a la ruta. Si tiene todas 
-                sus clases extras para elementos de formulario dentro de
-                una jerarquía común, este método es conveniente para establecer
-                el prefijo para todas ellas.
-            </para></listitem>
-
-            <listitem><para>
-                <code>addPrefixPaths(array $spec)</code>: le permite añadir
-                varias rutas de una sola vez a uno o más cargadores de plugin.
-                Se espera cada elemento de la matriz sea un array con claves
-                'path', 'prefix', y 'type'.
-            </para></listitem>
-        </itemizedlist>
-
-        <para>
-            Validadores, filtros y decoradores personalizados son una manera
-            simple de compartir funcionalidad entre formularios y encapsular
-            funcionalidad personalizada.
-        </para>
-
-        <example id="zend.form.elements.loaders.customLabel">
-            <title>Etiqueta personalizada</title>
-
-            <para>
-                Un uso común de los plugins es proveer reemplazos para las
-                clases estándares. Por ejemplo, si desea proveer una implementación diferente
-                 del decorador 'Label' -- por ejemplo, para
-                añadir siempre dos puntos -- puede crear su  propio decorador 
-                'Label' con su propio prefijo de clase, y entonces añadirlo a su 
-                prefijo de ruta.
-            </para>
-
-            <para>
-                Comencemos con un decorador de etiqueta personalizado. Le 
-                daremos el prefijo "My_Decorator", y la clase estará en el 
-                archivo "My/Decorator/Label.php".
-            </para>
-
-            <programlisting role="php"><![CDATA[
-class My_Decorator_Label extends Zend_Form_Decorator_Abstract
-{
-    protected $_placement = 'PREPEND';
-
-    public function render($content)
-    {
-        if (null === ($element = $this->getElement())) {
-            return $content;
-        }
-        if (!method_exists($element, 'getLabel')) {
-            return $content;
-        }
-
-        $label = $element->getLabel() . ':';
-
-        if (null === ($view = $element->getView())) {
-            return $this->renderLabel($content, $label);
-        }
-
-        $label = $view->formLabel($element->getName(), $label);
-
-        return $this->renderLabel($content, $label);
-    }
-
-    public function renderLabel($content, $label)
-    {
-        $placement = $this->getPlacement();
-        $separator = $this->getSeparator();
-
-        switch ($placement) {
-            case 'APPEND':
-                return $content . $separator . $label;
-            case 'PREPEND':
-            default:
-                return $label . $separator . $content;
-        }
-    }
-}
-]]>
-            </programlisting>
-
-            <para>
-                Ahora diremos al elemento que use esta ruta cuando busque por
-                decoradores:
-            </para>
-
-            <programlisting role="php"><![CDATA[
-$element->addPrefixPath('My_Decorator', 'My/Decorator/', 'decorator');
-]]>
-            </programlisting>
-
-            <para>
-                Alternativamente, podemos hacerlo en el formulario para asegurar
-                que todos los decoradores usen esta ruta:
-            </para>
-
-            <programlisting role="php"><![CDATA[
-$form->addElementPrefixPath('My_Decorator', 'My/Decorator/', 'decorator');
-]]>
-            </programlisting>
-
-            <para>
-                Con esta ruta añadida, cuando agregue un decorador, la ruta
-                'My/Decorator' será consultada primero en búsqueda de la 
-                existencia del decorador en este lugar. Como resultado, 
-                'My_Decorator_Label' ahora será utilizado cuando el decorador
-                'Label' sea requerido.
-            </para>
-        </example>
-    </sect2>
-
-    <sect2 id="zend.form.elements.filters">
-        <title>Filters</title>
-
-        <para>
-            A menudo es útil y/o necesario realizar alguna normalización en la
-            entrada antes de la validación – por ejemplo, puede querer eliminar
-            todo el HTML, pero realizar las validaciones sobre lo restante para
-            asegurarse que el envío es válido. O puede eliminar los espacios en
-            blanco al inicio o fin de la entrada para asegurarse de que un validador
-            StringLenth (longitud de la cadena) no regrese un positivo falso. Estas
-            operaciones pueden realizarse usando <code>Zend_Filter</code>, y
-            <code>Zend_Form_Element</code> que soportan cadenas de filtros,
-            permitiéndole especificar múltiples filtros secuenciales a utilizar.
-            El filtrado sucede tanto en la validación como cuando recupera el
-            valor del elemento vía <code>getValue()</code>:
-        </para>
-
-        <programlisting role="php"><![CDATA[
-$filtered = $element->getValue();
-
-]]>
-        </programlisting>
-
-        <para>
-            Los filtros pueden ser agregados a la pila de dos maneras:
-        </para>
-
-        <itemizedlist>
-            <listitem><para>
-                pasándolo en una instancia de filtro específica
-            </para></listitem>
-
-            <listitem><para>
-                proveyendo un nombre de filtro – el correspondiente nombre 
-                corto o completo de la clase
-            </para></listitem>
-        </itemizedlist>
-
-        <para>
-            Veamos algunos ejemplos:
-        </para>
-
-        <programlisting role="php"><![CDATA[
-// Instancia específica del filtro
-$element->addFilter(new Zend_Filter_Alnum());
-
-// El correspondiente nombre completo de la clase:
-$element->addFilter('Zend_Filter_Alnum');
-
-// Nombre corto del filtro:
-$element->addFilter('Alnum');
-$element->addFilter('alnum');
-]]>
-        </programlisting>
-
-        <para>
-            Los nombres cortos son típicamente el nombre del filtro sin el
-            prefijo. En el caso predeterminado, esto se refiere a sin el prefijo
-            'Zend_Filter_'. Además, la primera letra no necesita estar en 
-            mayúscula.
-        </para>
-
-        <note>
-            <title>Usando clases de filtros personalizados</title>
-
-            <para>
-                Si tiene su propio conjunto de clases de filtro, puede 
-                informarle de ellas a <code>Zend_Form_Element</code> usando 
-                <code>addPrefixPath()</code>. Por ejemplo, si tiene filtros
-                con el prefijo 'My_Filter', puede indicárselo a
-                <code>Zend_Form_Element</code> de la siguiente manera:
-            </para>
-
-            <programlisting role="php"><![CDATA[
-$element->addPrefixPath('My_Filter', 'My/Filter/', 'filter');
-]]>
-            </programlisting>
-
-            <para>
-                (Recuerde que el tercer argumento indica el cargador de plugin
-                sobre el cual ha de ejecutarse la acción.)
-            </para>
-        </note>
-
-        <para>
-            Si en algún momento necesita un valor no filtrado, use el método
-            <code>getUnfilteredValue()</code>:
-        </para>
-
-        <programlisting role="php"><![CDATA[
-$unfiltered = $element->getUnfilteredValue();
-]]>
-        </programlisting>
-
-        <para>
-            Para mayor información sobre filtros, vea la <link linkend="zend.filter.introduction">documentación de 
-                Zend_Filter</link>.
-        </para>
-
-        <para>
-            Métodos asociados con filtros incluyen:
-        </para>
-
-        <itemizedlist>
-            <listitem><para>
-                <code>addFilter($nameOfFilter, array $options = null)</code>
-            </para></listitem>
-
-            <listitem><para>
-                <code>addFilters(array $filters)</code>
-            </para></listitem>
-
-            <listitem><para>
-                <code>setFilters(array $filters)</code> (sobreescribe todos los
-                filtros)
-            </para></listitem>
-
-            <listitem><para>
-                <code>getFilter($name)</code> (recupera un objeto filtro por su
-                nombre)
-            </para></listitem>
-
-            <listitem><para>
-                <code>getFilters()</code> (recupera todos los filtros)
-            </para></listitem>
-
-            <listitem><para>
-                <code>removeFilter($name)</code> (elimina un filtro por su
-                nombre)
-            </para></listitem>
-
-            <listitem><para>
-                <code>clearFilters()</code> (elimina todos los filtros)
-            </para></listitem>
-        </itemizedlist>
-    </sect2>
-
-    <sect2 id="zend.form.elements.validators">
-        <title>Validadores</title>
-
-        <para>
-            Si sigue el mantra de seguridad "filtrar la entrada, escapar la
-            salida" querrá validar ("filtrar la entrada") los datos de los
-            formularios. En <code>Zend_Form</code> cada elemento contiene su
-            propia cadena de validadores, consistente en validadores
-            <code>Zend_Validate_*</code>.
-        </para>
-
-        <para>
-            Los validadores pueden ser agregados de dos maneras:
-        </para>
-
-        <itemizedlist>
-            <listitem><para>
-                pasándolo en una instancia de validador específica
-            </para></listitem>
-
-            <listitem><para>
-                proveyendo un nombre de validador – el correspondiente nombre 
-                corto o completo de clase
-            </para></listitem>
-        </itemizedlist>
-
-        <para>
-            Veamos algunos ejemplos:
-        </para>
-
-        <programlisting role="php"><![CDATA[
-// Instancia específica del validador:
-$element->addValidator(new Zend_Validate_Alnum());
-
-// El correspondiente nombre completo de la clase:
-$element->addValidator('Zend_Validate_Alnum');
-
-// Nombre corto del validador:
-$element->addValidator('Alnum');
-$element->addValidator('alnum');
-]]>
-        </programlisting>
-
-        <para>
-            Los nombres cortos son típicamente el nombre del validador sin el
-            prefijo. En el caso predeterminado, esto se refiere a sin el prefijo
-            'Zend_Validate_'. Además, la primera letra no necesita estar en
-            mayúscula.
-        </para>
-
-        <note>
-            <title>Usando clases de validación personalizadas</title>
-
-            <para>
-                Si tiene su propio conjunto de clases de validación, puede 
-                informarle de ellas a <code>Zend_Form_Element</code> usando 
-                <code>addPrefixPath()</code>. Por ejemplo, si tiene validadores
-                con el prefijo 'My_Validator', puede indicárselo a
-                <code>Zend_Form_Element</code> de la siguiente manera:
-            </para>
-
-            <programlisting role="php"><![CDATA[
-$element->addPrefixPath('My_Validator', 'My/Validator/', 'validate');
-]]>
-            </programlisting>
-
-            <para>
-                (Recuerde que el tercer argumento indica el cargador de plugin
-                sobre el cual ha de ejecutarse la acción.)
-            </para>
-        </note>
-
-        <para>
-            Si el fallo de un validador debe evitar validaciones posteriores,
-            pase el boleano <code>true</code> como segundo parámetro:
-        </para>
-
-        <programlisting role="php"><![CDATA[
-$element->addValidator('alnum', true);
-]]>
-        </programlisting>
-
-        <para>
-            Si está usando la cadena nombre para añadir el validador, y la clase 
-            del validador acepta argumentos para su constructor, puede pasarlos
-            a el tercer parámetro de <code>addValidator()</code> como un 
-            array:
-        </para>
-
-        <programlisting role="php"><![CDATA[
-$element->addValidator('StringLength', false, array(6, 20));
-]]>
-        </programlisting>
-
-        <para>
-            Los argumentos pasados de esta manera deben estar en el orden en el
-            cual son definidos en el constructor. El ejemplo de arriba 
-            instanciará la clase <code>Zend_Validate_StringLenth</code> con los
-            parámetros <code>$min</code> y <code>$max</code>:
-        </para>
-
-        <programlisting role="php"><![CDATA[
-$validator = new Zend_Validate_StringLength(6, 20);
-]]>
-        </programlisting>
-
-        <note>
-            <title>Estipulando mensajes de error de validación personalizados</title>
-
-            <para>
-                Algunos desarrolladores querrán estipular mensajes de error
-                personalizados para un validador. El argumento 
-                <code>$options</code> de 
-                <code>Zend_Form_Element::addValidator()</code> le permite 
-                hacerlo proporcionando la clave 'messages' y estableciendolos en 
-                un array de pares clave/valor para especificar las plantillas 
-                de mensaje. Necesitará conocer los códigos de error de los 
-                diferentes tipos de error de un validador en particular.
-            </para>
-
-            <para>
-                Una opción mejor es usar <code>Zend_Translate_Adapter</code>
-                con su formulario. Los códigos de error son automáticamente 
-                pasados al adaptador por el decorador Errors por defecto; puede 
-                especificar su propias cadenas de mensaje de error mediante la 
-                creación de traducciones para los varios códigos de error de 
-                sus validadores.
-            </para>
-        </note>
-
-        <para>
-            Puede también establecer varios validadores a la vez, usando
-            <code>addValidators()</code>. Su uso básico es pasar una matriz de
-            arrays, donde cada array contenga de 1 a 3 valores, 
-            correspondientes al constructor de <code>addValidator()</code>:
-        </para>
-
-        <programlisting role="php"><![CDATA[
-$element->addValidators(array(
-    array('NotEmpty', true),
-    array('alnum'),
-    array('stringLength', false, array(6, 20)),
-));
-]]>
-        </programlisting>
-
-        <para>
-            Si quiere ser más detallado o explícito, puede utilizar las claves 
-            'validator', 'breakChainOnFailure', y 'options' en el array:
-        </para>
-
-        <programlisting role="php"><![CDATA[
-$element->addValidators(array(
-    array(
-        'validator'           => 'NotEmpty',
-        'breakChainOnFailure' => true),
-    array('validator' => 'alnum'),
-    array(
-        'validator' => 'stringLength',
-        'options'   => array(6, 20)),
-));
-]]>
-        </programlisting>
-
-        <para>
-            Este uso es bueno para ilustrar cómo puede configurar validadores
-            en un archivo de configuración:
-        </para>
-
-        <programlisting role="ini"><![CDATA[
-element.validators.notempty.validator = "NotEmpty"
-element.validators.notempty.breakChainOnFailure = true
-element.validators.alnum.validator = "Alnum"
-element.validators.strlen.validator = "StringLength"
-element.validators.strlen.options.min = 6
-element.validators.strlen.options.max = 20
-]]>
-</programlisting>
-
-        <para>
-            Note que cada elemento tiene una clave, la necesite o no; esta es 
-            una limitación del uso de archivos de configuración -- pero también 
-            ayuda a hacer más explicito el para qué son usados los argumentos. 
-            Sólo recuerde que cualesquiera opciones del validador deben ser 
-            especificadas en orden.
-        </para>
-
-        <para>
-            Para validar un elemento, pase el valor a
-            <code>isValid()</code>:
-        </para>
-
-        <programlisting role="php"><![CDATA[
-if ($element->isValid($value)) {
-    // válido
-} else {
-    // no válido
-}
-]]>
-        </programlisting>
-
-        <note>
-            <title>Validación operando en valores filtrados</title>
-
-            <para>
-                <code>Zend_Form_Element::isValid()</code> siempre filtra los 
-                valores antes de la validación a través de la cadena de filtros.
-                Vea <link linkend="zend.form.elements.filters">la sección de 
-                filtros</link> para más información.
-            </para>
-        </note>
-
-        <note>
-            <title>Contexto de validación</title>
-
-            <para>
-                <code>Zend_Form_Element::isValid()</code> soporta un argumento
-                adicional, <code>$context</code>.
-                <code>Zend_Form::isValid()</code> pasa todo el conjunto de datos 
-                procesados a <code>$context</code> cuando valida un formulario, 
-                y <code>Zend_Form_Element::isValid()</code>, a su vez, lo pasa a 
-                cada validador. Esto significa que puede escribir validadores 
-                que son conscientes de los datos pasados a otros elementos del 
-                formulario. Como ejemplo, considere un formulario de registro
-                estándar que tiene campos para la contraseña y la confirmación 
-                de la contraseña; una validación sería que los dos campos 
-                coincidan. Este validador puede tener un aspecto como el 
-                siguiente:
-            </para>
-
-            <programlisting role="php"><![CDATA[
-class My_Validate_PasswordConfirmation extends Zend_Validate_Abstract
-{
-    const NOT_MATCH = 'notMatch';
-
-    protected $_messageTemplates = array(
-        self::NOT_MATCH => 'Password confirmation does not match'
-    );
-
-    public function isValid($value, $context = null)
-    {
-        $value = (string) $value;
-        $this->_setValue($value);
-
-        if (is_array($context)) {
-            if (isset($context['password_confirm'])
-                && ($value == $context['password_confirm']))
-            {
-                return true;
-            }
-        } elseif (is_string($context) && ($value == $context)) {
-            return true;
-        }
-
-        $this->_error(self::NOT_MATCH);
-        return false;
-    }
-}
-]]>
-            </programlisting>
-        </note>
-
-        <para>
-            Los validadores son procesados en orden. Cada validador es 
-            procesado, a menos que un validador creado con un valor true para
-            <code>breakChainOnFailure</code> falle su validación. Asegúrese de 
-            especificar sus validadores en un orden razonable.
-        </para>
-
-        <para>
-            Después de una validación fallida, puede recuperar los códigos y 
-            mensajes de error de la cadena del validador:
-        </para>
-
-        <programlisting role="php"><![CDATA[
-$errors   = $element->getErrors();
-$messages = $element->getMessages();
-]]>
-        </programlisting>
-
-        <para>
-            (Nota: los mensajes de error retornados son un array asociativo de
-            pares código / mensaje de error.) 
-        </para>
-
-        <para>
-            En adición a los validadores, puede especificar que un elemento es
-            necesario, usando <code>setRequired(true)</code>. Por defecto, esta
-            bandera es false, lo que significa que pasará su cadena de  
-            validadores si ningún valor es pasado a <code>isValid()</code>. 
-            Puede modificar este comportamiento en un número de maneras:
-        </para>
-
-        <itemizedlist>
-            <listitem>
-                <para>
-                    Por defecto, cuando un elemento es requerido, una bandera,
-                    'allowEmpty', también es true. Esto quiere decir que si un 
-                    valor empty es evaluado pasándolo a <code>isValid()</code>, 
-                    los validadores serán saltados. Puede intercalar esta
-                    bandera usando el método de acceso 
-                    <code>setAllowEmpty($flag)</code>; cuando la bandera es 
-                    false, si un valor es pasado, los validadores seguirán 
-                    ejecutándose.
-                </para>
-            </listitem>
-
-            <listitem>
-                <para>
-                    Por defecto, si un elemento es requerido, pero no contiene
-                    un validador 'NotEmpty', <code>isValid()</code> añadirá uno
-                    en la cima de la pila, con la bandera 
-                    <code>breakChainOnFailure</code> establecido. Esto hace que 
-                    la bandera requerida tenga un significado semántico: si 
-                    ningún valor es pasado, inmediatamente invalidamos el envío 
-                    y se le notifica al usuario, e impedimos que otros 
-                    validadores se ejecuten en lo que ya sabemos son datos 
-                    inválidos.
-                </para>
-
-                <para>
-                    Si no quiere este comportamiento, puede desactivarlo pasando
-                    un valor false a 
-                    <code>setAutoInsertNotEmptyValidator($flag)</code>; esto
-                    prevendrá a <code>isValid()</code> de colocar un validador 
-                    'NotEmpty' en la cadena de validaciones.
-                </para>
-            </listitem>
-        </itemizedlist>
-
-        <para>
-            Para mayor información sobre validadores, vea la <link linkend="zend.validate.introduction">documentación de 
-                Zend_Validate</link>.
-        </para>
-
-        <note>
-            <title>Usando Zend_Form_Elements como validador de propósito general</title>
-
-            <para>
-                <code>Zend_Form_Element</code> implementa
-                <code>Zend_Validate_Interface</code>, significando un elemento
-                puede también usarse como un validador en otro, cadenas de 
-                validación no relacionadas al formulario.
-            </para>
-        </note>
-
-        <para>
-            Métodos asociados con validación incluyen:
-        </para>
-
-        <itemizedlist>
-            <listitem><para>
-                    <code>setRequired($flag)</code> y
-                    <code>isRequired()</code> permiten establecer y recuperar el 
-                    estado de la bandera 'required'. Cuando se le asigna un 
-                    booleano <code>true</code>, esta bandera requiere que el
-                    elemento esté presente en la información procesada por 
-                    <code>Zend_Form</code>.
-            </para></listitem>
-
-            <listitem><para>
-                    <code>setAllowEmpty($flag)</code> y
-                    <code>getAllowEmpty()</code> permiten modificar el 
-                    comportamiento de elementos opcionales (p.e., elementos 
-                    donde la bandera required es false). Cuando la bandera  
-                    'allow empty' es true, valores vacíos no pasarán la cadena
-                    de validadores.
-            </para></listitem>
-
-            <listitem><para>
-                    <code>setAutoInsertNotEmptyValidator($flag)</code> permite
-                    especificar si realmente un validador 'NotEmpty' será 
-                    añadido el inicio de la cadena de validaciones cuando un 
-                    elemento es requerido. Por defecto, esta bandera es true.
-            </para></listitem>
-
-            <listitem><para>
-                <code>addValidator($nameOrValidator, $breakChainOnFailure = false, array $options = null)</code>
-            </para></listitem>
-
-            <listitem><para>
-                <code>addValidators(array $validators)</code>
-            </para></listitem>
-
-            <listitem><para>
-                <code>setValidators(array $validators)</code> (sobreescribe todos los validadores)
-            </para></listitem>
-
-            <listitem><para>
-                <code>getValidator($name)</code> (recupera un objeto validador por nombre)
-            </para></listitem>
-
-            <listitem><para>
-                <code>getValidators()</code> (recupera todos los validadores)
-            </para></listitem>
-
-            <listitem><para>
-                <code>removeValidator($name)</code> (elimina un validador por nombre)
-            </para></listitem>
-
-            <listitem><para>
-                <code>clearValidators()</code> (elimina todos los validadores)
-            </para></listitem>
-        </itemizedlist>
-
-        <sect3 id="zend.form.elements.validators.errors">
-            <title>Errores de mensaje personalizados</title>
-
-            <para>
-                Alguna veces, querrá especificar uno o más mensajes de error para
-                usarlos en lugar de los mensajes de error generados por los 
-                validadores adjuntos a los elementos. Adicionalmente, algunas
-                veces usted mismo querrá marcar al elemento como inválido. A 
-                partir de 1.6.0, esta funcionalidad es posible vía los 
-                siguientes métodos. 
-            </para>
-
-            <itemizedlist>
-                <listitem><para>
-                    <code>addErrorMessage($message)</code>: añade un mensaje de 
-                    error para mostrarlos en forma de errores de validación. Puede 
-                    llamarlo más de una vez, y los nuevos mensajes nuevos son 
-                    añadidos a la pila.
-                </para></listitem>
-
-                <listitem><para>
-                    <code>addErrorMessages(array $messages)</code>: añade 
-                    múltiples mensajes de error para mostrarlos en forma de errores de
-                    validación.
-                </para></listitem>
-
-                <listitem><para>
-                    <code>setErrorMessages(array $messages)</code>: añade 
-                    múltiples mensajes de error para mostrarlos en forma de errores de
-                    validación, sobreescribiendo todos los mensajes de error 
-                    previamente establecidos. 
-                </para></listitem>
-
-                <listitem><para>
-                    <code>getErrorMessages()</code>: recupera la lista de 
-                    mensajes de error personalizados que fueron definidos.
-                </para></listitem>
-
-                <listitem><para>
-                    <code>clearErrorMessages()</code>: remueve todos los 
-                    mensajes de error personalizados que hayan sido definidos.
-                </para></listitem>
-
-                <listitem><para>
-                    <code>markAsError()</code>: marca al elemento como que falló 
-                    la validación.
-                </para></listitem>
-
-                <listitem><para>
-                    <code>hasErrors()</code>: determina si el elemento ha 
-                    fallado la validación o ha sido marcado como inválido.
-                </para></listitem>
-
-                <listitem><para>
-                    <code>addError($message)</code>: añade un mensaje a la pila
-                    de mensaje de error personalizados y marca al elemento como 
-                    inválido.
-                </para></listitem>
-
-                <listitem><para>
-                    <code>addErrors(array $messages)</code>: añade varios 
-                    mensajes a la pila de mensajes de error personalizados y 
-                    marca al elemento como inválido.
-                </para></listitem>
-
-                <listitem><para>
-                    <code>setErrors(array $messages)</code>: sobreescribe el 
-                    mensaje de error personalizado en la pila con los mensajes
-                    previstos y marca al elemento como inválido.
-                </para></listitem>
-            </itemizedlist>
-
-            <para>
-                Todos los errores establecidos de este modo pueden ser 
-                traducidos. Adicionalmente, puede insertar el marcador "%value%" 
-                para representar el valor del elemento; este valor actual del 
-                elemento será sustituido cuando el mensaje de error sea 
-                recuperado.
-            </para>
-        </sect3>
-    </sect2>
-
-    <sect2 id="zend.form.elements.decorators">
-        <title>Decoradores</title>
-
-        <para>
-            Una dolencia particular para muchos desarrolladores web es la creación
-            del XHTML para formularios por ellos mismos. Para cada elemento, el
-            desarrollador necesita crear la marcación para el elemento mismo,
-            comúnmente una etiqueta (label), y, si son amables con sus usuarios,
-            la marcación para mostrar mensajes de errores de validación. Cuanto
-            más elementos en una página, menos trivial se convierte esta tarea.
-        </para>
-
-        <para>
-            <code>Zend_Form_Element</code> intenta resolver este problema mediante
-            el uso de "decoradores". Los decoradores son clases simples que tienen
-            métodos de acceso al elemento y métodos para generar el contenido. Para
-            obtener mayor información sobre cómo trabajan los decoradores, consulte
-            por favor  la sección sobre 
-            <link linkend="zend.form.decorators">Zend_Form_Decorator</link>.
-        </para>
-
-        <para>
-            Los decoradores usados por defecto por
-            <code>Zend_Form_Element</code> son:
-        </para>
-
-        <itemizedlist>
-            <listitem><para>
-                <emphasis>ViewHelper</emphasis>: especifica un view helper que
-                usar para general el elemento. El atributo 'helper' del elemento
-                puede usarse para especificar qué auxiliar vista usar. Por
-                defecto, <code>Zend_Form_Element</code> especifica el auxiliar
-                vista 'formText', pero cada subclase especifica diferentes 
-                auxiliares.
-            </para></listitem>
-
-            <listitem><para>
-                <emphasis>Errors</emphasis>: añade mensajes de error al elemento
-                usando <code>Zend_View_Helper_FormErrors</code>. Si no está
-                presente, no se añade nada.
-            </para></listitem>
-
-            <listitem><para>
-                <emphasis>Description</emphasis>: añade la descripción del
-                elemento. Si no está presente, no se añade nada. Por defecto, la
-                descripción es generada dentro de una etiqueta &lt;p&gt; con un
-                class 'description'.
-            </para></listitem>
-
-            <listitem><para>
-                <emphasis>HtmlTag</emphasis>: envuelve el elemento y los errores
-                en una etiqueta HTML &lt;dd&gt;.
-            </para></listitem>
-
-            <listitem><para>
-                <emphasis>Label</emphasis>: añade al comienzo una etiqueta al
-                elemento usando <code>Zend_View_Helper_FormLabel</code>, y
-                envolviéndola en una etiqueta &lt;dt&gt;. Si ninguna etiqueta es
-                provista, solo la etiqueta de la definición es generada.
-            </para></listitem>
-        </itemizedlist>
-
-        <note>
-            <title>Decoradores por defecto no necesitan ser cargados</title>
-
-            <para>
-                Por defecto, los decoradores por defecto son cargados durante la
-                inicialización del objeto. Puede deshabilitar esto pasando la
-                opción 'disableLoadDefaultDecorators' al constructor:
-            </para>
-
-            <programlisting role="php"><![CDATA[
-$element = new Zend_Form_Element('foo',
-                                 array('disableLoadDefaultDecorators' =>
-                                      true)
-                                );
-]]>
-            </programlisting>
-
-            <para>
-                Esta opción puede ser combinada junto con cualquier otra opción que
-                pase, ya sea como un array de opciones o en un objeto
-                <code>Zend_Config</code>.
-            </para>
-        </note>
-
-        <para>
-            Ya que el orden en el cual los decoradores son registrados importa
-            -- el primer decorador registrado es ejecutado primero -- necesitará
-            estar seguro de registrar sus decoradores en el orden apropiado, o
-            asegurarse de que estableció las opciones de colocación en el modo apropiado. Por
-            dar un ejemplo, aquí esta el código que registran los decoradores
-            por defecto:
-        </para>
-
-        <programlisting role="php"><![CDATA[
-$this->addDecorators(array(
-    array('ViewHelper'),
-    array('Errors'),
-    array('Description', array('tag' => 'p', 'class' => 'description')),
-    array('HtmlTag', array('tag' => 'dd')),
-    array('Label', array('tag' => 'dt')),
-));
-]]>
-        </programlisting>
-
-        <para>
-            El contenido inicial es creado por el decorador 'ViewHelper', que
-            crea el propio elemento. En seguida, el decorador 'Errors' consulta
-            los mensajes de error del elemento, y, si hay alguno presente, los
-            pasa al auxiliar vista 'FormErrors' para mostrarlos. Si una
-            descripción está presente, el decorador 'Description' añadirá
-            un párrafo con class 'description' conteniendo el texto descriptivo
-            para el contenido agregado. El siguiente decorador, 'HtmlTag',
-            envuelve al elemento, los errores, y la descripción en una etiqueta 
-            HTML &lt;dd&gt;. Finalmente, el último decorador, 'label', recupera
-            la etiqueta del elemento y la pasa al auxiliar vista 'FormLabel',
-            envolviéndolo en una etiqueta &lt;dt&gt;; por default el valor es 
-            añadido al inicio del contenido. El resultado de la salida
-            básicamente se ve así:
-        </para>
-
-        <programlisting role="html"><![CDATA[
-<dt><label for="foo" class="optional">Foo</label></dt>
-<dd>
-    <input type="text" name="foo" id="foo" value="123" />
-    <ul class="errors">
-        <li>"123" is not an alphanumeric value</li>
-    </ul>
-    <p class="description">
-        This is some descriptive text regarding the element.
-    </p>
-</dd>
-]]>
-</programlisting>
-
-        <para>
-            Para más información sobre decoradores, lea la <link linkend="zend.form.decorators"> sección de Zend_Form_Decorator</link>.
-        </para>
-
-        <note>
-            <title>Usando múltiples decoradores al mismo tiempo</title>
-
-            <para>
-                Internamente, <code>Zend_Form_Element</code> utiliza una clase
-                decorador como mecanismo de búsqueda para la recuperación de
-                decoradores. Como resultado, no puede registrar múltiples 
-                decoradores del mismo tipo; decoradores subsecuentes 
-                simplemente sobreescribirán aquellos que ya existían.
-            </para>
-
-            <para>
-                Para evitar esto, puede usar <emphasis>alias</emphasis>. En
-                lugar de pasar un decorador o nombre de decorador como primer
-                argumento a <code>addDecorator()</code>, pase una matriz con un
-                solo elemento, con el alias apuntando al nombre o objeto
-                decorador:
-            </para>
-
-            <programlisting role="php"><![CDATA[
-// Alias a 'FooBar':
-$element->addDecorator(array('FooBar' => 'HtmlTag'),
-                       array('tag' => 'div'));
-
-// Y recuperandolo posteriormente:
-$decorator = $element->getDecorator('FooBar');
-]]>
-            </programlisting>
-
-            <para>
-                En los métodos <code>addDecorators()</code> y
-                <code>setDecorators()</code>, necesitará pasar la opción
-                'decorator' en la matriz representando el decorador:
-            </para>
-
-            <programlisting role="php"><![CDATA[
-// Y dos decoradores 'HtmlTag', 'FooBar' como alias:
-$element->addDecorators(
-    array('HtmlTag', array('tag' => 'div')),
-    array(
-        'decorator' => array('FooBar' => 'HtmlTag'),
-        'options' => array('tag' => 'dd')
-    ),
-);
-
-// Y recuperándolos posteriormente:
-$htmlTag = $element->getDecorator('HtmlTag');
-$fooBar  = $element->getDecorator('FooBar');
-]]>
-            </programlisting>
-        </note>
-
-        <para>
-            Métodos asociados con decoradores incluyen:
-        </para>
-
-        <itemizedlist>
-            <listitem><para>
-                <code>addDecorator($nameOrDecorator, array $options = null)</code>
-            </para></listitem>
-
-            <listitem><para>
-                <code>addDecorators(array $decorators)</code>
-            </para></listitem>
-
-            <listitem><para>
-                <code>setDecorators(array $decorators)</code> (sobreescribe
-                todos los decoradores)
-            </para></listitem>
-
-            <listitem><para>
-                <code>getDecorator($name)</code> (recupera un objeto decorador
-                por su nombre)
-            </para></listitem>
-
-            <listitem><para>
-                <code>getDecorators()</code> (recupera todos los decoradores)
-            </para></listitem>
-
-            <listitem><para>
-                <code>removeDecorator($name)</code> (elimina un decorador por su
-                nombre)
-            </para></listitem>
-
-            <listitem><para>
-                <code>clearDecorators()</code> (elimina todos los decoradores)
-            </para></listitem>
-        </itemizedlist>
-
-        <para>
-            <code>Zend_Form_Element</code> también utiliza la sobrecarga para
-            permitir generar decoradores específicos. <code>__call()</code>
-            interceptará métodos que comiencen con el texto 'render' y utilizará
-            el resto del nombre del método para buscar un decorador; si se
-            encuentra, entonces será generado <emphasis>sólo ese</emphasis> 
-            decorador. Cualquier argumento pasado al llamado del método será
-            usado como contenido para pasar  al método <code>render()</code> del
-            decorador. Como ejemplo:
-        </para>
-
-        <programlisting role="php"><![CDATA[
-// Genera solo el decorador ViewHelper:
-echo $element->renderViewHelper();
-
-// Genera solo el decorador HtmlTag, pasándole contenido:
-echo $element->renderHtmlTag("This is the html tag content");
-]]></programlisting>
-
-        <para>
-            Si el decorador no existe, una excepción es lanzada.
-        </para>
-    </sect2>
-
-    <sect2 id="zend.form.elements.metadata">
-        <title>Metadatos y atributos</title>
-
-        <para>
-            <code>Zend_Form_Element</code> manipula una variedad de atributos y
-            medatados del elemento. Atributos básicos incluyen:
-        </para>
-
-        <itemizedlist>
-            <listitem><para>
-                <emphasis>name</emphasis>: el nombre del elemento. Emplea los
-                métodos de acceso <code>setName()</code> y <code>getName()</code>.
-            </para></listitem>
-
-            <listitem><para>
-                <emphasis>label</emphasis>: la etiqueta del elemento. Emplea los
-                métodos de acceso <code>setLabel()</code> y <code>getLabel()</code>.
-            </para></listitem>
-
-            <listitem><para>
-                <emphasis>order</emphasis>: el índice en el cual los elementos
-                deben ir mostrándose en el formulario. Emplea los métodos de
-                acceso <code>setOrder()</code> y <code>getOrder()</code>.
-            </para></listitem>
-
-            <listitem><para>
-                <emphasis>value</emphasis>: El valor del elemento actual. Emplea
-                los métodos de acceso <code>setValue()</code> y 
-                <code>getValue()</code>.
-            </para></listitem>
-
-            <listitem><para>
-                <emphasis>description</emphasis>: una descripción del elemento;
-                a menudo utilizada para proveer un tooltip o ayuda contextual
-                con javascript describiendo el propósito del elemento. Emplea
-                los métodos de acceso <code>setDescription()</code> y 
-                <code>getDescription()</code>.
-            </para></listitem>
-
-            <listitem><para>
-                <emphasis>required</emphasis>: bandera que indica si un elemento
-                es requerido o no cuando se efectúa la validación del
-                formulario. Emplea los métodos de acceso 
-                <code>setRequired()</code> y <code>getRequired()</code>. Esta
-                bandera es false por defecto.
-            </para></listitem>
-
-            <listitem><para>
-                <emphasis>allowEmpty</emphasis>: bandera indicando si un
-                elemento no-requerido (opcional) debe intentar validar o no
-                valores vacíos. Cuando es true, y la bandera required es false,
-                valores vacíos no pasarán la cadena de validación, y se supone
-                verdadero. Emplea los métodos de acceso 
-                <code>setAllowEmpty()</code> y <code>getAllowEmpty()</code>.
-                Esta bandera es true por defecto.
-            </para></listitem>
-
-            <listitem><para>
-                <emphasis>autoInsertNotEmptyValidator</emphasis>: bandera 
-                indicando insertar o no un validador 'NotEmpty' cuando un
-                elemento es requerido. Por defecto, esta bandera es true.
-                Establezca la bandera con
-                <code>setAutoInsertNotEmptyValidator($flag)</code> y determine
-                el valor con <code>autoInsertNotEmptyValidator()</code>.
-            </para></listitem>
-        </itemizedlist>
-
-        <para>
-            Los elementos del formulario pueden requerir metainformación
-            adicional. Para elementos XHTML del formuladio, por ejemplo, puede
-            querer especificar atributos como el class o id. Para facilitar esto
-            hay un conjunto de métodos de acceso:
-        </para>
-
-        <itemizedlist>
-            <listitem><para>
-                <emphasis>setAttrib($name, $value)</emphasis>: añade un atributo
-            </para></listitem>
-
-            <listitem><para>
-                <emphasis>setAttribs(array $attribs)</emphasis>: como
-                addAttribs(), pero sobreescribiendo
-            </para></listitem>
-
-            <listitem><para>
-                <emphasis>getAttrib($name)</emphasis>: recupera el valor de solo
-                un atributo
-            </para></listitem>
-
-            <listitem><para>
-                <emphasis>getAttribs()</emphasis>: recupera todos los atributos
-                como pares clave/valor
-            </para></listitem>
-        </itemizedlist>
-
-        <para>
-            La mayoría de las veces, como sea, puede simplemente acceder a ellos
-            como propiedades de objeto, ya que <code>Zend_Form_Element</code>
-            utiliza la sobrecarga para facilitar el acceso a ellos:
-        </para>
-
-        <programlisting role="php"><![CDATA[
-// Equivalente a $element->setAttrib('class', 'text'):
-$element->class = 'text;
-]]>
-        </programlisting>
-
-        <para>
-            Por defecto, todos los atributos son pasados al auxiliar vista usado 
-            por el elemento durante la generación, y generados como atributos de
-            la etiqueta del elemento.
-        </para>
-    </sect2>
-
-    <sect2 id="zend.form.elements.standard">
-        <title>Elementos Estándar</title>
-
-        <para>
-            <code>Zend_Form</code> contiene un buen número de elementos
-            estándar; por favor lea el capítulo <link linkend="zend.form.standardElements">Elementos Estándar</link> para
-            todos los detalles.
-        </para>
-    </sect2>
-
-    <sect2 id="zend.form.elements.methods">
-        <title>Métodos de Zend_Form_Element</title>
-
-        <para>
-            <code>Zend_Form_Element</code> tiene muchos, muchos métodos. Lo que
-            sigue es un sumario de sus funciones, agrupados por tipo:
-        </para>
-
-        <itemizedlist>
-            <listitem><para>Configuración:</para>
-                <itemizedlist>
-                    <listitem><para><code>setOptions(array $options)</code></para></listitem>
-                    <listitem><para><code>setConfig(Zend_Config $config)</code></para></listitem>
-                </itemizedlist>
-            </listitem>
-
-            <listitem><para>I18n:</para>
-                <itemizedlist>
-                    <listitem><para><code>setTranslator(Zend_Translate_Adapter $translator = null)</code></para></listitem>
-                    <listitem><para><code>getTranslator()</code></para></listitem>
-                    <listitem><para><code>setDisableTranslator($flag)</code></para></listitem>
-                    <listitem><para><code>translatorIsDisabled()</code></para></listitem>
-                </itemizedlist>
-            </listitem>
-
-            <listitem><para>Propiedades:</para>
-                <itemizedlist>
-                    <listitem><para><code>setName($name)</code></para></listitem>
-                    <listitem><para><code>getName()</code></para></listitem>
-                    <listitem><para><code>setValue($value)</code></para></listitem>
-                    <listitem><para><code>getValue()</code></para></listitem>
-                    <listitem><para><code>getUnfilteredValue()</code></para></listitem>
-                    <listitem><para><code>setLabel($label)</code></para></listitem>
-                    <listitem><para><code>getLabel()</code></para></listitem>
-                    <listitem><para><code>setDescription($description)</code></para></listitem>
-                    <listitem><para><code>getDescription()</code></para></listitem>
-                    <listitem><para><code>setOrder($order)</code></para></listitem>
-                    <listitem><para><code>getOrder()</code></para></listitem>
-                    <listitem><para><code>setRequired($flag)</code></para></listitem>
-                    <listitem><para><code>getRequired()</code></para></listitem>
-                    <listitem><para><code>setAllowEmpty($flag)</code></para></listitem>
-                    <listitem><para><code>getAllowEmpty()</code></para></listitem>
-                    <listitem><para><code>setAutoInsertNotEmptyValidator($flag)</code></para></listitem>
-                    <listitem><para><code>autoInsertNotEmptyValidator()</code></para></listitem>
-                    <listitem><para><code>setIgnore($flag)</code></para></listitem>
-                    <listitem><para><code>getIgnore()</code></para></listitem>
-                    <listitem><para><code>getType()</code></para></listitem>
-                    <listitem><para><code>setAttrib($name, $value)</code></para></listitem>
-                    <listitem><para><code>setAttribs(array $attribs)</code></para></listitem>
-                    <listitem><para><code>getAttrib($name)</code></para></listitem>
-                    <listitem><para><code>getAttribs()</code></para></listitem>
-                </itemizedlist>
-            </listitem>
-
-            <listitem><para>Cargadores y rutas de plugin:</para>
-                <itemizedlist>
-                    <listitem><para><code>setPluginLoader(Zend_Loader_PluginLoader_Interface $loader, $type)</code></para></listitem>
-                    <listitem><para><code>getPluginLoader($type)</code></para></listitem>
-                    <listitem><para><code>addPrefixPath($prefix, $path, $type = null)</code></para></listitem>
-                    <listitem><para><code>addPrefixPaths(array $spec)</code></para></listitem>
-                </itemizedlist>
-            </listitem>
-
-            <listitem><para>Validación:</para>
-                <itemizedlist>
-                    <listitem><para><code>addValidator($validator, $breakChainOnFailure = false, $options = array())</code></para></listitem>
-                    <listitem><para><code>addValidators(array $validators)</code></para></listitem>
-                    <listitem><para><code>setValidators(array $validators)</code></para></listitem>
-                    <listitem><para><code>getValidator($name)</code></para></listitem>
-                    <listitem><para><code>getValidators()</code></para></listitem>
-                    <listitem><para><code>removeValidator($name)</code></para></listitem>
-                    <listitem><para><code>clearValidators()</code></para></listitem>
-                    <listitem><para><code>isValid($value, $context = null)</code></para></listitem>
-                    <listitem><para><code>getErrors()</code></para></listitem>
-                    <listitem><para><code>getMessages()</code></para></listitem>
-                </itemizedlist>
-            </listitem>
-
-            <listitem><para>Filtros:</para>
-                <itemizedlist>
-                    <listitem><para><code>addFilter($filter, $options = array())</code></para></listitem>
-                    <listitem><para><code>addFilters(array $filters)</code></para></listitem>
-                    <listitem><para><code>setFilters(array $filters)</code></para></listitem>
-                    <listitem><para><code>getFilter($name)</code></para></listitem>
-                    <listitem><para><code>getFilters()</code></para></listitem>
-                    <listitem><para><code>removeFilter($name)</code></para></listitem>
-                    <listitem><para><code>clearFilters()</code></para></listitem>
-                </itemizedlist>
-            </listitem>
-
-            <listitem><para>Generación:</para>
-                <itemizedlist>
-                    <listitem><para><code>setView(Zend_View_Interface $view = null)</code></para></listitem>
-                    <listitem><para><code>getView()</code></para></listitem>
-                    <listitem><para><code>addDecorator($decorator, $options = null)</code></para></listitem>
-                    <listitem><para><code>addDecorators(array $decorators)</code></para></listitem>
-                    <listitem><para><code>setDecorators(array $decorators)</code></para></listitem>
-                    <listitem><para><code>getDecorator($name)</code></para></listitem>
-                    <listitem><para><code>getDecorators()</code></para></listitem>
-                    <listitem><para><code>removeDecorator($name)</code></para></listitem>
-                    <listitem><para><code>clearDecorators()</code></para></listitem>
-                    <listitem><para><code>render(Zend_View_Interface $view = null)</code></para></listitem>
-                </itemizedlist>
-            </listitem>
-        </itemizedlist>
-    </sect2>
-
-    <sect2 id="zend.form.elements.config">
-        <title>Configuración</title>
-
-        <para>
-            El constructor de <code>Zend_Form_Element</code> acepta tanto una
-            matriz de opciones como un objeto <code>Zend_Config</code>
-            conteniendo opciones, y esto puede configurarse usando
-            <code>setOptions()</code> o <code>setConfig()</code>. Hablando de
-            manera general, las claves son nombradas de la siguiente manera:
-        </para>
-
-        <itemizedlist>
-            <listitem><para>
-                Si 'set' + clave se refiere a un método de 
-                <code>Zend_Form_Element</code>, entonces el valor provisto será
-                pasado a el método.
-            </para></listitem>
-
-            <listitem><para>
-                De otra manera, el valor será usado para establecer un atributo.
-            </para></listitem>
-        </itemizedlist>
-
-        <para>
-            Excepciones a la regla incluyen las siguientes:
-        </para>
-
-        <itemizedlist>
-            <listitem><para>
-                <code>prefixPath</code> será pasado a
-                <code>addPrefixPaths()</code>
-            </para></listitem>
-
-            <listitem>
-                <para>
-                    Los siguientes setters no pueden establecerse de esta manera:
-                </para>
-
-                <itemizedlist>
-                    <listitem><para>
-                            <code>setAttrib</code> (aunque
-                            <code>setAttribs</code> <emphasis>funcionará</emphasis>
-                    </para></listitem>
-
-                    <listitem><para><code>setConfig</code></para></listitem>
-
-                    <listitem><para><code>setOptions</code></para></listitem>
-
-                    <listitem><para><code>setPluginLoader</code></para></listitem>
-
-                    <listitem><para><code>setTranslator</code></para></listitem>
-
-                    <listitem><para><code>setView</code></para></listitem>
-                </itemizedlist>
-            </listitem>
-        </itemizedlist>
-
-        <para>
-            Como ejemplo, aquí esta un archivo de configuración pasado para
-            cada tipo de dato configurable:
-        </para>
-
-        <programlisting role="ini"><![CDATA[
-[element]
-name = "foo"
-value = "foobar"
-label = "Foo:"
-order = 10
-required = true
-allowEmpty = false
-autoInsertNotEmptyValidator = true
-description = "Foo elements are for examples"
-ignore = false
-attribs.id = "foo"
-attribs.class = "element"
-; sets 'onclick' attribute
-onclick = "autoComplete(this, '/form/autocomplete/element')"
-prefixPaths.decorator.prefix = "My_Decorator"
-prefixPaths.decorator.path = "My/Decorator/"
-disableTranslator = 0
-validators.required.validator = "NotEmpty"
-validators.required.breakChainOnFailure = true
-validators.alpha.validator = "alpha"
-validators.regex.validator = "regex"
-validators.regex.options.pattern = "/^[A-F].*/$"
-filters.ucase.filter = "StringToUpper"
-decorators.element.decorator = "ViewHelper"
-decorators.element.options.helper = "FormText"
-decorators.label.decorator = "Label"
-]]>
-</programlisting>
-    </sect2>
-
-    <sect2 id="zend.form.elements.custom">
-        <title>Elementos personalizados</title>
-
-        <para>
-            Usted puede crear sus propios elementos personalizados simplemente
-            extendiendo la clase <code>Zend_Form_Element</code>. Las razones
-            comunes para hacer esto incluyen:
-        </para>
-
-        <itemizedlist>
-            <listitem><para>
-                Elementos que comparten validadores y/o filtros comunes 
-            </para></listitem>
-
-            <listitem><para>
-                Elementos que tienen decoradores con funcionalidad personalizada
-            </para></listitem>
-        </itemizedlist>
-
-        <para>
-            Hay dos métodos típicamente usados para extender un elemento:
-            <code>init()</code>, el cual puede usarse para añadir una lógica de
-            inicialización personalizada a su elemento, y
-            <code>loadDefaultDecorators()</code>, el cual puede usarse para
-            establecer una lista de decoradores usados por su elemento de manera
-            predeterminada.
-        </para>
-
-        <para>
-            Como un ejemplo, digamos que todos los elementos de tipo texto en un
-            formulario que está creando, necesitan ser filtrados con
-            <code>StringTrim</code>, validados con una expresión regular, y que
-            quiere usar un decorador personalizado que ha creado para
-            mostrarlos, 'My_Decorator_TextItem'; adicionalmente, tiene un número
-            de atributos estándars, incluyendo 'size', 'maxLength', y 'class'
-            que quisiera especificar. Puede definir un elemento tal como sigue:
-        </para>
-
-        <programlisting role="php"><![CDATA[
-class My_Element_Text extends Zend_Form_Element
-{
-    public function init()
-    {
-        $this->addPrefixPath('My_Decorator', 'My/Decorator/', 'decorator')
-             ->addFilters('StringTrim')
-             ->addValidator('Regex', false, array('/^[a-z0-9]{6,}$/i'))
-             ->addDecorator('TextItem')
-             ->setAttrib('size', 30)
-             ->setAttrib('maxLength', 45)
-             ->setAttrib('class', 'text');
-    }
-}
-]]>
-        </programlisting>
-
-        <para>
-            Entonces puede informar a su objeto formulario acerca del prefijo de
-            ruta para elementos de ese tipo, y comenzar creando elementos:
-        </para>
-
-        <programlisting role="php"><![CDATA[
-$form->addPrefixPath('My_Element', 'My/Element/', 'element')
-     ->addElement('foo', 'text');
-]]>
-        </programlisting>
-
-        <para>
-            El elemento 'foo' será ahora del tipo <code>My_Element_Text</code>,
-            y mostrará el comportamiento que ha especificado.
-        </para>
-
-        <para>
-            Otro método que puede querer sobreescribir cuando extienda
-            <code>Zend_Form_Element</code> es el método
-            <code>loadDefaultDecorators()</code>. Este método carga
-            condicionalmente un grupo de decoradores predefinidos para su
-            elemento; puede querer sustituir su propio decorador en su clase
-            extendida:
-        </para>
-
-        <programlisting role="php"><![CDATA[
-class My_Element_Text extends Zend_Form_Element
-{
-    public function loadDefaultDecorators()
-    {
-        $this->addDecorator('ViewHelper')
-             ->addDecorator('DisplayError')
-             ->addDecorator('Label')
-             ->addDecorator('HtmlTag',
-                            array('tag' => 'div', 'class' => 'element'));
-    }
-}
-]]>
-        </programlisting>
-
-        <para>
-            Hay muchas maneras de personalizar elementos; asegúrese de leer la
-            documentación de la API de <code>Zend_Form_Element</code> para
-            conocer todos los métodos disponibles.
-        </para>
-    </sect2>
-</sect1>
-<!--
-vim:se ts=4 sw=4 tw=80 ai et:
--->
+<sect1 id="zend.form.elements">
+    <title>Creando elementos de formulario usando Zend_Form_Element</title>
+
+    <para>
+        Un formulario esta compuesto de elementos, que normalmente corresponden 
+        al  elemento HTML input. <code>Zend_Form_Element</code> encapsula
+        elementos de formulario individualmente, con las siguientes áreas de 
+        responsabilidad:
+    </para>
+
+    <itemizedlist>
+        <listitem>
+            <para>
+                validación (¿los datos enviados son válidos?)
+            </para>
+
+            <itemizedlist>
+                <listitem><para>captura de códigos y mensajes de error</para></listitem>
+            </itemizedlist>
+        </listitem>
+
+        <listitem><para>
+            filtrado (¿cómo es escapado y normalizado el elemento para su 
+            validación y/o salida?
+        </para></listitem>
+
+        <listitem><para>
+            generación (¿cómo es mostrado el elemento?)
+        </para></listitem>
+
+        <listitem><para>
+            metadatos y atributos (¿qué información amplía la definición del
+            elemento?)
+        </para></listitem>
+    </itemizedlist>
+
+    <para>
+        La clase base, <code>Zend_Form_Element</code>, funciona por defecto para
+        varios casos, pero es mejor extender la clase para elementos con fines 
+        especiales de uso común. Adicionalmente, Zend Framework contiene un 
+        número de elementos XHTML estándar; puede leer de ellos <link linkend="zend.form.standardElements">en el capítulo Elementos
+        Estándares</link>
+    </para>
+
+    <sect2 id="zend.form.elements.loaders">
+        <title>Cargadores de Plugin</title>
+
+        <para>
+            <code>Zend_Form_Element</code> hace uso de <link linkend="zend.loader.pluginloader">Zend_Loader_PluginLoader</link>
+            para permitir a los desarrolladores especificar ubicaciones de
+            validadores, filtros y decoradores alternos. Cada uno tiene su 
+            propio cargador de plugin asociado a él y métodos de acceso 
+            generales usados para su recuperación y modificación.
+        </para>
+
+        <para>
+            Los siguientes tipos de cargadores son usados con los varios métodos
+            del cargador de plugin: 'validate', 'filter', y 'decorator'. Los
+            nombres son sensibles a mayúsculas y minúsculas.
+        </para>
+
+        <para>
+            Los métodos usados para interactuar con los cargadores de plugin son 
+            los siguientes:
+        </para>
+
+        <itemizedlist>
+            <listitem><para>
+                <code>setPluginLoader($loader, $type)</code>:
+                <code>$loader</code> es el propio objeto cargador, mientras
+                <code>$type</code> es uno de los tipos arriba mencionados. Esto
+                establece el cargador de plugin para el tipo dado en el objeto
+                cargador recién especificado.
+            </para></listitem>
+
+            <listitem><para>
+                <code>getPluginLoader($type)</code>: obtiene el cargador de
+                plugin asociado con <code>$type</code>.
+            </para></listitem>
+
+            <listitem><para>
+                <code>addPrefixPath($prefix, $path, $type = null)</code>: agrega
+                una asociación prefijo/ruta para el cargador especificado por
+                <code>$type</code>. Si <code>$type</code> es null, se intentará
+                agregar la ruta a todos los cargadores, añadiendo el prefijo a
+                cada "_Validate", "_Filter" y "_Decorator"; y agregandole
+                "Validate/", "Filter/" y "Decorator/" a la ruta. Si tiene todas 
+                sus clases extras para elementos de formulario dentro de
+                una jerarquía común, este método es conveniente para establecer
+                el prefijo para todas ellas.
+            </para></listitem>
+
+            <listitem><para>
+                <code>addPrefixPaths(array $spec)</code>: le permite añadir
+                varias rutas de una sola vez a uno o más cargadores de plugin.
+                Se espera cada elemento de la matriz sea un array con claves
+                'path', 'prefix', y 'type'.
+            </para></listitem>
+        </itemizedlist>
+
+        <para>
+            Validadores, filtros y decoradores personalizados son una manera
+            simple de compartir funcionalidad entre formularios y encapsular
+            funcionalidad personalizada.
+        </para>
+
+        <example id="zend.form.elements.loaders.customLabel">
+            <title>Etiqueta personalizada</title>
+
+            <para>
+                Un uso común de los plugins es proveer reemplazos para las
+                clases estándares. Por ejemplo, si desea proveer una implementación diferente
+                 del decorador 'Label' -- por ejemplo, para
+                añadir siempre dos puntos -- puede crear su  propio decorador 
+                'Label' con su propio prefijo de clase, y entonces añadirlo a su 
+                prefijo de ruta.
+            </para>
+
+            <para>
+                Comencemos con un decorador de etiqueta personalizado. Le 
+                daremos el prefijo "My_Decorator", y la clase estará en el 
+                archivo "My/Decorator/Label.php".
+            </para>
+
+            <programlisting role="php"><![CDATA[
+class My_Decorator_Label extends Zend_Form_Decorator_Abstract
+{
+    protected $_placement = 'PREPEND';
+
+    public function render($content)
+    {
+        if (null === ($element = $this->getElement())) {
+            return $content;
+        }
+        if (!method_exists($element, 'getLabel')) {
+            return $content;
+        }
+
+        $label = $element->getLabel() . ':';
+
+        if (null === ($view = $element->getView())) {
+            return $this->renderLabel($content, $label);
+        }
+
+        $label = $view->formLabel($element->getName(), $label);
+
+        return $this->renderLabel($content, $label);
+    }
+
+    public function renderLabel($content, $label)
+    {
+        $placement = $this->getPlacement();
+        $separator = $this->getSeparator();
+
+        switch ($placement) {
+            case 'APPEND':
+                return $content . $separator . $label;
+            case 'PREPEND':
+            default:
+                return $label . $separator . $content;
+        }
+    }
+}
+]]>
+            </programlisting>
+
+            <para>
+                Ahora diremos al elemento que use esta ruta cuando busque por
+                decoradores:
+            </para>
+
+            <programlisting role="php"><![CDATA[
+$element->addPrefixPath('My_Decorator', 'My/Decorator/', 'decorator');
+]]>
+            </programlisting>
+
+            <para>
+                Alternativamente, podemos hacerlo en el formulario para asegurar
+                que todos los decoradores usen esta ruta:
+            </para>
+
+            <programlisting role="php"><![CDATA[
+$form->addElementPrefixPath('My_Decorator', 'My/Decorator/', 'decorator');
+]]>
+            </programlisting>
+
+            <para>
+                Con esta ruta añadida, cuando agregue un decorador, la ruta
+                'My/Decorator' será consultada primero en búsqueda de la 
+                existencia del decorador en este lugar. Como resultado, 
+                'My_Decorator_Label' ahora será utilizado cuando el decorador
+                'Label' sea requerido.
+            </para>
+        </example>
+    </sect2>
+
+    <sect2 id="zend.form.elements.filters">
+        <title>Filters</title>
+
+        <para>
+            A menudo es útil y/o necesario realizar alguna normalización en la
+            entrada antes de la validación – por ejemplo, puede querer eliminar
+            todo el HTML, pero realizar las validaciones sobre lo restante para
+            asegurarse que el envío es válido. O puede eliminar los espacios en
+            blanco al inicio o fin de la entrada para asegurarse de que un validador
+            StringLenth (longitud de la cadena) no regrese un positivo falso. Estas
+            operaciones pueden realizarse usando <code>Zend_Filter</code>, y
+            <code>Zend_Form_Element</code> que soportan cadenas de filtros,
+            permitiéndole especificar múltiples filtros secuenciales a utilizar.
+            El filtrado sucede tanto en la validación como cuando recupera el
+            valor del elemento vía <code>getValue()</code>:
+        </para>
+
+        <programlisting role="php"><![CDATA[
+$filtered = $element->getValue();
+
+]]>
+        </programlisting>
+
+        <para>
+            Los filtros pueden ser agregados a la pila de dos maneras:
+        </para>
+
+        <itemizedlist>
+            <listitem><para>
+                pasándolo en una instancia de filtro específica
+            </para></listitem>
+
+            <listitem><para>
+                proveyendo un nombre de filtro – el correspondiente nombre 
+                corto o completo de la clase
+            </para></listitem>
+        </itemizedlist>
+
+        <para>
+            Veamos algunos ejemplos:
+        </para>
+
+        <programlisting role="php"><![CDATA[
+// Instancia específica del filtro
+$element->addFilter(new Zend_Filter_Alnum());
+
+// El correspondiente nombre completo de la clase:
+$element->addFilter('Zend_Filter_Alnum');
+
+// Nombre corto del filtro:
+$element->addFilter('Alnum');
+$element->addFilter('alnum');
+]]>
+        </programlisting>
+
+        <para>
+            Los nombres cortos son típicamente el nombre del filtro sin el
+            prefijo. En el caso predeterminado, esto se refiere a sin el prefijo
+            'Zend_Filter_'. Además, la primera letra no necesita estar en 
+            mayúscula.
+        </para>
+
+        <note>
+            <title>Usando clases de filtros personalizados</title>
+
+            <para>
+                Si tiene su propio conjunto de clases de filtro, puede 
+                informarle de ellas a <code>Zend_Form_Element</code> usando 
+                <code>addPrefixPath()</code>. Por ejemplo, si tiene filtros
+                con el prefijo 'My_Filter', puede indicárselo a
+                <code>Zend_Form_Element</code> de la siguiente manera:
+            </para>
+
+            <programlisting role="php"><![CDATA[
+$element->addPrefixPath('My_Filter', 'My/Filter/', 'filter');
+]]>
+            </programlisting>
+
+            <para>
+                (Recuerde que el tercer argumento indica el cargador de plugin
+                sobre el cual ha de ejecutarse la acción.)
+            </para>
+        </note>
+
+        <para>
+            Si en algún momento necesita un valor no filtrado, use el método
+            <code>getUnfilteredValue()</code>:
+        </para>
+
+        <programlisting role="php"><![CDATA[
+$unfiltered = $element->getUnfilteredValue();
+]]>
+        </programlisting>
+
+        <para>
+            Para mayor información sobre filtros, vea la <link linkend="zend.filter.introduction">documentación de 
+                Zend_Filter</link>.
+        </para>
+
+        <para>
+            Métodos asociados con filtros incluyen:
+        </para>
+
+        <itemizedlist>
+            <listitem><para>
+                <code>addFilter($nameOfFilter, array $options = null)</code>
+            </para></listitem>
+
+            <listitem><para>
+                <code>addFilters(array $filters)</code>
+            </para></listitem>
+
+            <listitem><para>
+                <code>setFilters(array $filters)</code> (sobreescribe todos los
+                filtros)
+            </para></listitem>
+
+            <listitem><para>
+                <code>getFilter($name)</code> (recupera un objeto filtro por su
+                nombre)
+            </para></listitem>
+
+            <listitem><para>
+                <code>getFilters()</code> (recupera todos los filtros)
+            </para></listitem>
+
+            <listitem><para>
+                <code>removeFilter($name)</code> (elimina un filtro por su
+                nombre)
+            </para></listitem>
+
+            <listitem><para>
+                <code>clearFilters()</code> (elimina todos los filtros)
+            </para></listitem>
+        </itemizedlist>
+    </sect2>
+
+    <sect2 id="zend.form.elements.validators">
+        <title>Validadores</title>
+
+        <para>
+            Si sigue el mantra de seguridad "filtrar la entrada, escapar la
+            salida" querrá validar ("filtrar la entrada") los datos de los
+            formularios. En <code>Zend_Form</code> cada elemento contiene su
+            propia cadena de validadores, consistente en validadores
+            <code>Zend_Validate_*</code>.
+        </para>
+
+        <para>
+            Los validadores pueden ser agregados de dos maneras:
+        </para>
+
+        <itemizedlist>
+            <listitem><para>
+                pasándolo en una instancia de validador específica
+            </para></listitem>
+
+            <listitem><para>
+                proveyendo un nombre de validador – el correspondiente nombre 
+                corto o completo de clase
+            </para></listitem>
+        </itemizedlist>
+
+        <para>
+            Veamos algunos ejemplos:
+        </para>
+
+        <programlisting role="php"><![CDATA[
+// Instancia específica del validador:
+$element->addValidator(new Zend_Validate_Alnum());
+
+// El correspondiente nombre completo de la clase:
+$element->addValidator('Zend_Validate_Alnum');
+
+// Nombre corto del validador:
+$element->addValidator('Alnum');
+$element->addValidator('alnum');
+]]>
+        </programlisting>
+
+        <para>
+            Los nombres cortos son típicamente el nombre del validador sin el
+            prefijo. En el caso predeterminado, esto se refiere a sin el prefijo
+            'Zend_Validate_'. Además, la primera letra no necesita estar en
+            mayúscula.
+        </para>
+
+        <note>
+            <title>Usando clases de validación personalizadas</title>
+
+            <para>
+                Si tiene su propio conjunto de clases de validación, puede 
+                informarle de ellas a <code>Zend_Form_Element</code> usando 
+                <code>addPrefixPath()</code>. Por ejemplo, si tiene validadores
+                con el prefijo 'My_Validator', puede indicárselo a
+                <code>Zend_Form_Element</code> de la siguiente manera:
+            </para>
+
+            <programlisting role="php"><![CDATA[
+$element->addPrefixPath('My_Validator', 'My/Validator/', 'validate');
+]]>
+            </programlisting>
+
+            <para>
+                (Recuerde que el tercer argumento indica el cargador de plugin
+                sobre el cual ha de ejecutarse la acción.)
+            </para>
+        </note>
+
+        <para>
+            Si el fallo de un validador debe evitar validaciones posteriores,
+            pase el boleano <code>true</code> como segundo parámetro:
+        </para>
+
+        <programlisting role="php"><![CDATA[
+$element->addValidator('alnum', true);
+]]>
+        </programlisting>
+
+        <para>
+            Si está usando la cadena nombre para añadir el validador, y la clase 
+            del validador acepta argumentos para su constructor, puede pasarlos
+            a el tercer parámetro de <code>addValidator()</code> como un 
+            array:
+        </para>
+
+        <programlisting role="php"><![CDATA[
+$element->addValidator('StringLength', false, array(6, 20));
+]]>
+        </programlisting>
+
+        <para>
+            Los argumentos pasados de esta manera deben estar en el orden en el
+            cual son definidos en el constructor. El ejemplo de arriba 
+            instanciará la clase <code>Zend_Validate_StringLenth</code> con los
+            parámetros <code>$min</code> y <code>$max</code>:
+        </para>
+
+        <programlisting role="php"><![CDATA[
+$validator = new Zend_Validate_StringLength(6, 20);
+]]>
+        </programlisting>
+
+        <note>
+            <title>Estipulando mensajes de error de validación personalizados</title>
+
+            <para>
+                Algunos desarrolladores querrán estipular mensajes de error
+                personalizados para un validador. El argumento 
+                <code>$options</code> de 
+                <code>Zend_Form_Element::addValidator()</code> le permite 
+                hacerlo proporcionando la clave 'messages' y estableciendolos en 
+                un array de pares clave/valor para especificar las plantillas 
+                de mensaje. Necesitará conocer los códigos de error de los 
+                diferentes tipos de error de un validador en particular.
+            </para>
+
+            <para>
+                Una opción mejor es usar <code>Zend_Translate_Adapter</code>
+                con su formulario. Los códigos de error son automáticamente 
+                pasados al adaptador por el decorador Errors por defecto; puede 
+                especificar su propias cadenas de mensaje de error mediante la 
+                creación de traducciones para los varios códigos de error de 
+                sus validadores.
+            </para>
+        </note>
+
+        <para>
+            Puede también establecer varios validadores a la vez, usando
+            <code>addValidators()</code>. Su uso básico es pasar una matriz de
+            arrays, donde cada array contenga de 1 a 3 valores, 
+            correspondientes al constructor de <code>addValidator()</code>:
+        </para>
+
+        <programlisting role="php"><![CDATA[
+$element->addValidators(array(
+    array('NotEmpty', true),
+    array('alnum'),
+    array('stringLength', false, array(6, 20)),
+));
+]]>
+        </programlisting>
+
+        <para>
+            Si quiere ser más detallado o explícito, puede utilizar las claves 
+            'validator', 'breakChainOnFailure', y 'options' en el array:
+        </para>
+
+        <programlisting role="php"><![CDATA[
+$element->addValidators(array(
+    array(
+        'validator'           => 'NotEmpty',
+        'breakChainOnFailure' => true),
+    array('validator' => 'alnum'),
+    array(
+        'validator' => 'stringLength',
+        'options'   => array(6, 20)),
+));
+]]>
+        </programlisting>
+
+        <para>
+            Este uso es bueno para ilustrar cómo puede configurar validadores
+            en un archivo de configuración:
+        </para>
+
+        <programlisting role="ini"><![CDATA[
+element.validators.notempty.validator = "NotEmpty"
+element.validators.notempty.breakChainOnFailure = true
+element.validators.alnum.validator = "Alnum"
+element.validators.strlen.validator = "StringLength"
+element.validators.strlen.options.min = 6
+element.validators.strlen.options.max = 20
+]]>
+</programlisting>
+
+        <para>
+            Note que cada elemento tiene una clave, la necesite o no; esta es 
+            una limitación del uso de archivos de configuración -- pero también 
+            ayuda a hacer más explicito el para qué son usados los argumentos. 
+            Sólo recuerde que cualesquiera opciones del validador deben ser 
+            especificadas en orden.
+        </para>
+
+        <para>
+            Para validar un elemento, pase el valor a
+            <code>isValid()</code>:
+        </para>
+
+        <programlisting role="php"><![CDATA[
+if ($element->isValid($value)) {
+    // válido
+} else {
+    // no válido
+}
+]]>
+        </programlisting>
+
+        <note>
+            <title>Validación operando en valores filtrados</title>
+
+            <para>
+                <code>Zend_Form_Element::isValid()</code> siempre filtra los 
+                valores antes de la validación a través de la cadena de filtros.
+                Vea <link linkend="zend.form.elements.filters">la sección de 
+                filtros</link> para más información.
+            </para>
+        </note>
+
+        <note>
+            <title>Contexto de validación</title>
+
+            <para>
+                <code>Zend_Form_Element::isValid()</code> soporta un argumento
+                adicional, <code>$context</code>.
+                <code>Zend_Form::isValid()</code> pasa todo el conjunto de datos 
+                procesados a <code>$context</code> cuando valida un formulario, 
+                y <code>Zend_Form_Element::isValid()</code>, a su vez, lo pasa a 
+                cada validador. Esto significa que puede escribir validadores 
+                que son conscientes de los datos pasados a otros elementos del 
+                formulario. Como ejemplo, considere un formulario de registro
+                estándar que tiene campos para la contraseña y la confirmación 
+                de la contraseña; una validación sería que los dos campos 
+                coincidan. Este validador puede tener un aspecto como el 
+                siguiente:
+            </para>
+
+            <programlisting role="php"><![CDATA[
+class My_Validate_PasswordConfirmation extends Zend_Validate_Abstract
+{
+    const NOT_MATCH = 'notMatch';
+
+    protected $_messageTemplates = array(
+        self::NOT_MATCH => 'Password confirmation does not match'
+    );
+
+    public function isValid($value, $context = null)
+    {
+        $value = (string) $value;
+        $this->_setValue($value);
+
+        if (is_array($context)) {
+            if (isset($context['password_confirm'])
+                && ($value == $context['password_confirm']))
+            {
+                return true;
+            }
+        } elseif (is_string($context) && ($value == $context)) {
+            return true;
+        }
+
+        $this->_error(self::NOT_MATCH);
+        return false;
+    }
+}
+]]>
+            </programlisting>
+        </note>
+
+        <para>
+            Los validadores son procesados en orden. Cada validador es 
+            procesado, a menos que un validador creado con un valor true para
+            <code>breakChainOnFailure</code> falle su validación. Asegúrese de 
+            especificar sus validadores en un orden razonable.
+        </para>
+
+        <para>
+            Después de una validación fallida, puede recuperar los códigos y 
+            mensajes de error de la cadena del validador:
+        </para>
+
+        <programlisting role="php"><![CDATA[
+$errors   = $element->getErrors();
+$messages = $element->getMessages();
+]]>
+        </programlisting>
+
+        <para>
+            (Nota: los mensajes de error retornados son un array asociativo de
+            pares código / mensaje de error.) 
+        </para>
+
+        <para>
+            En adición a los validadores, puede especificar que un elemento es
+            necesario, usando <code>setRequired(true)</code>. Por defecto, esta
+            bandera es false, lo que significa que pasará su cadena de  
+            validadores si ningún valor es pasado a <code>isValid()</code>. 
+            Puede modificar este comportamiento en un número de maneras:
+        </para>
+
+        <itemizedlist>
+            <listitem>
+                <para>
+                    Por defecto, cuando un elemento es requerido, una bandera,
+                    'allowEmpty', también es true. Esto quiere decir que si un 
+                    valor empty es evaluado pasándolo a <code>isValid()</code>, 
+                    los validadores serán saltados. Puede intercalar esta
+                    bandera usando el método de acceso 
+                    <code>setAllowEmpty($flag)</code>; cuando la bandera es 
+                    false, si un valor es pasado, los validadores seguirán 
+                    ejecutándose.
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    Por defecto, si un elemento es requerido, pero no contiene
+                    un validador 'NotEmpty', <code>isValid()</code> añadirá uno
+                    en la cima de la pila, con la bandera 
+                    <code>breakChainOnFailure</code> establecido. Esto hace que 
+                    la bandera requerida tenga un significado semántico: si 
+                    ningún valor es pasado, inmediatamente invalidamos el envío 
+                    y se le notifica al usuario, e impedimos que otros 
+                    validadores se ejecuten en lo que ya sabemos son datos 
+                    inválidos.
+                </para>
+
+                <para>
+                    Si no quiere este comportamiento, puede desactivarlo pasando
+                    un valor false a 
+                    <code>setAutoInsertNotEmptyValidator($flag)</code>; esto
+                    prevendrá a <code>isValid()</code> de colocar un validador 
+                    'NotEmpty' en la cadena de validaciones.
+                </para>
+            </listitem>
+        </itemizedlist>
+
+        <para>
+            Para mayor información sobre validadores, vea la <link linkend="zend.validate.introduction">documentación de 
+                Zend_Validate</link>.
+        </para>
+
+        <note>
+            <title>Usando Zend_Form_Elements como validador de propósito general</title>
+
+            <para>
+                <code>Zend_Form_Element</code> implementa
+                <code>Zend_Validate_Interface</code>, significando un elemento
+                puede también usarse como un validador en otro, cadenas de 
+                validación no relacionadas al formulario.
+            </para>
+        </note>
+
+        <para>
+            Métodos asociados con validación incluyen:
+        </para>
+
+        <itemizedlist>
+            <listitem><para>
+                    <code>setRequired($flag)</code> y
+                    <code>isRequired()</code> permiten establecer y recuperar el 
+                    estado de la bandera 'required'. Cuando se le asigna un 
+                    booleano <code>true</code>, esta bandera requiere que el
+                    elemento esté presente en la información procesada por 
+                    <code>Zend_Form</code>.
+            </para></listitem>
+
+            <listitem><para>
+                    <code>setAllowEmpty($flag)</code> y
+                    <code>getAllowEmpty()</code> permiten modificar el 
+                    comportamiento de elementos opcionales (p.e., elementos 
+                    donde la bandera required es false). Cuando la bandera  
+                    'allow empty' es true, valores vacíos no pasarán la cadena
+                    de validadores.
+            </para></listitem>
+
+            <listitem><para>
+                    <code>setAutoInsertNotEmptyValidator($flag)</code> permite
+                    especificar si realmente un validador 'NotEmpty' será 
+                    añadido el inicio de la cadena de validaciones cuando un 
+                    elemento es requerido. Por defecto, esta bandera es true.
+            </para></listitem>
+
+            <listitem><para>
+                <code>addValidator($nameOrValidator, $breakChainOnFailure = false, array $options = null)</code>
+            </para></listitem>
+
+            <listitem><para>
+                <code>addValidators(array $validators)</code>
+            </para></listitem>
+
+            <listitem><para>
+                <code>setValidators(array $validators)</code> (sobreescribe todos los validadores)
+            </para></listitem>
+
+            <listitem><para>
+                <code>getValidator($name)</code> (recupera un objeto validador por nombre)
+            </para></listitem>
+
+            <listitem><para>
+                <code>getValidators()</code> (recupera todos los validadores)
+            </para></listitem>
+
+            <listitem><para>
+                <code>removeValidator($name)</code> (elimina un validador por nombre)
+            </para></listitem>
+
+            <listitem><para>
+                <code>clearValidators()</code> (elimina todos los validadores)
+            </para></listitem>
+        </itemizedlist>
+
+        <sect3 id="zend.form.elements.validators.errors">
+            <title>Errores de mensaje personalizados</title>
+
+            <para>
+                Alguna veces, querrá especificar uno o más mensajes de error para
+                usarlos en lugar de los mensajes de error generados por los 
+                validadores adjuntos a los elementos. Adicionalmente, algunas
+                veces usted mismo querrá marcar al elemento como inválido. A 
+                partir de 1.6.0, esta funcionalidad es posible vía los 
+                siguientes métodos. 
+            </para>
+
+            <itemizedlist>
+                <listitem><para>
+                    <code>addErrorMessage($message)</code>: añade un mensaje de 
+                    error para mostrarlos en forma de errores de validación. Puede 
+                    llamarlo más de una vez, y los nuevos mensajes nuevos son 
+                    añadidos a la pila.
+                </para></listitem>
+
+                <listitem><para>
+                    <code>addErrorMessages(array $messages)</code>: añade 
+                    múltiples mensajes de error para mostrarlos en forma de errores de
+                    validación.
+                </para></listitem>
+
+                <listitem><para>
+                    <code>setErrorMessages(array $messages)</code>: añade 
+                    múltiples mensajes de error para mostrarlos en forma de errores de
+                    validación, sobreescribiendo todos los mensajes de error 
+                    previamente establecidos. 
+                </para></listitem>
+
+                <listitem><para>
+                    <code>getErrorMessages()</code>: recupera la lista de 
+                    mensajes de error personalizados que fueron definidos.
+                </para></listitem>
+
+                <listitem><para>
+                    <code>clearErrorMessages()</code>: remueve todos los 
+                    mensajes de error personalizados que hayan sido definidos.
+                </para></listitem>
+
+                <listitem><para>
+                    <code>markAsError()</code>: marca al elemento como que falló 
+                    la validación.
+                </para></listitem>
+
+                <listitem><para>
+                    <code>hasErrors()</code>: determina si el elemento ha 
+                    fallado la validación o ha sido marcado como inválido.
+                </para></listitem>
+
+                <listitem><para>
+                    <code>addError($message)</code>: añade un mensaje a la pila
+                    de mensaje de error personalizados y marca al elemento como 
+                    inválido.
+                </para></listitem>
+
+                <listitem><para>
+                    <code>addErrors(array $messages)</code>: añade varios 
+                    mensajes a la pila de mensajes de error personalizados y 
+                    marca al elemento como inválido.
+                </para></listitem>
+
+                <listitem><para>
+                    <code>setErrors(array $messages)</code>: sobreescribe el 
+                    mensaje de error personalizado en la pila con los mensajes
+                    previstos y marca al elemento como inválido.
+                </para></listitem>
+            </itemizedlist>
+
+            <para>
+                Todos los errores establecidos de este modo pueden ser 
+                traducidos. Adicionalmente, puede insertar el marcador "%value%" 
+                para representar el valor del elemento; este valor actual del 
+                elemento será sustituido cuando el mensaje de error sea 
+                recuperado.
+            </para>
+        </sect3>
+    </sect2>
+
+    <sect2 id="zend.form.elements.decorators">
+        <title>Decoradores</title>
+
+        <para>
+            Una dolencia particular para muchos desarrolladores web es la creación
+            del XHTML para formularios por ellos mismos. Para cada elemento, el
+            desarrollador necesita crear la marcación para el elemento mismo,
+            comúnmente una etiqueta (label), y, si son amables con sus usuarios,
+            la marcación para mostrar mensajes de errores de validación. Cuanto
+            más elementos en una página, menos trivial se convierte esta tarea.
+        </para>
+
+        <para>
+            <code>Zend_Form_Element</code> intenta resolver este problema mediante
+            el uso de "decoradores". Los decoradores son clases simples que tienen
+            métodos de acceso al elemento y métodos para generar el contenido. Para
+            obtener mayor información sobre cómo trabajan los decoradores, consulte
+            por favor  la sección sobre 
+            <link linkend="zend.form.decorators">Zend_Form_Decorator</link>.
+        </para>
+
+        <para>
+            Los decoradores usados por defecto por
+            <code>Zend_Form_Element</code> son:
+        </para>
+
+        <itemizedlist>
+            <listitem><para>
+                <emphasis>ViewHelper</emphasis>: especifica un view helper que
+                usar para general el elemento. El atributo 'helper' del elemento
+                puede usarse para especificar qué auxiliar vista usar. Por
+                defecto, <code>Zend_Form_Element</code> especifica el auxiliar
+                vista 'formText', pero cada subclase especifica diferentes 
+                auxiliares.
+            </para></listitem>
+
+            <listitem><para>
+                <emphasis>Errors</emphasis>: añade mensajes de error al elemento
+                usando <code>Zend_View_Helper_FormErrors</code>. Si no está
+                presente, no se añade nada.
+            </para></listitem>
+
+            <listitem><para>
+                <emphasis>Description</emphasis>: añade la descripción del
+                elemento. Si no está presente, no se añade nada. Por defecto, la
+                descripción es generada dentro de una etiqueta &lt;p&gt; con un
+                class 'description'.
+            </para></listitem>
+
+            <listitem><para>
+                <emphasis>HtmlTag</emphasis>: envuelve el elemento y los errores
+                en una etiqueta HTML &lt;dd&gt;.
+            </para></listitem>
+
+            <listitem><para>
+                <emphasis>Label</emphasis>: añade al comienzo una etiqueta al
+                elemento usando <code>Zend_View_Helper_FormLabel</code>, y
+                envolviéndola en una etiqueta &lt;dt&gt;. Si ninguna etiqueta es
+                provista, solo la etiqueta de la definición es generada.
+            </para></listitem>
+        </itemizedlist>
+
+        <note>
+            <title>Decoradores por defecto no necesitan ser cargados</title>
+
+            <para>
+                Por defecto, los decoradores por defecto son cargados durante la
+                inicialización del objeto. Puede deshabilitar esto pasando la
+                opción 'disableLoadDefaultDecorators' al constructor:
+            </para>
+
+            <programlisting role="php"><![CDATA[
+$element = new Zend_Form_Element('foo',
+                                 array('disableLoadDefaultDecorators' =>
+                                      true)
+                                );
+]]>
+            </programlisting>
+
+            <para>
+                Esta opción puede ser combinada junto con cualquier otra opción que
+                pase, ya sea como un array de opciones o en un objeto
+                <code>Zend_Config</code>.
+            </para>
+        </note>
+
+        <para>
+            Ya que el orden en el cual los decoradores son registrados importa
+            -- el primer decorador registrado es ejecutado primero -- necesitará
+            estar seguro de registrar sus decoradores en el orden apropiado, o
+            asegurarse de que estableció las opciones de colocación en el modo apropiado. Por
+            dar un ejemplo, aquí esta el código que registran los decoradores
+            por defecto:
+        </para>
+
+        <programlisting role="php"><![CDATA[
+$this->addDecorators(array(
+    array('ViewHelper'),
+    array('Errors'),
+    array('Description', array('tag' => 'p', 'class' => 'description')),
+    array('HtmlTag', array('tag' => 'dd')),
+    array('Label', array('tag' => 'dt')),
+));
+]]>
+        </programlisting>
+
+        <para>
+            El contenido inicial es creado por el decorador 'ViewHelper', que
+            crea el propio elemento. En seguida, el decorador 'Errors' consulta
+            los mensajes de error del elemento, y, si hay alguno presente, los
+            pasa al auxiliar vista 'FormErrors' para mostrarlos. Si una
+            descripción está presente, el decorador 'Description' añadirá
+            un párrafo con class 'description' conteniendo el texto descriptivo
+            para el contenido agregado. El siguiente decorador, 'HtmlTag',
+            envuelve al elemento, los errores, y la descripción en una etiqueta 
+            HTML &lt;dd&gt;. Finalmente, el último decorador, 'label', recupera
+            la etiqueta del elemento y la pasa al auxiliar vista 'FormLabel',
+            envolviéndolo en una etiqueta &lt;dt&gt;; por default el valor es 
+            añadido al inicio del contenido. El resultado de la salida
+            básicamente se ve así:
+        </para>
+
+        <programlisting role="html"><![CDATA[
+<dt><label for="foo" class="optional">Foo</label></dt>
+<dd>
+    <input type="text" name="foo" id="foo" value="123" />
+    <ul class="errors">
+        <li>"123" is not an alphanumeric value</li>
+    </ul>
+    <p class="description">
+        This is some descriptive text regarding the element.
+    </p>
+</dd>
+]]>
+</programlisting>
+
+        <para>
+            Para más información sobre decoradores, lea la <link linkend="zend.form.decorators"> sección de Zend_Form_Decorator</link>.
+        </para>
+
+        <note>
+            <title>Usando múltiples decoradores al mismo tiempo</title>
+
+            <para>
+                Internamente, <code>Zend_Form_Element</code> utiliza una clase
+                decorador como mecanismo de búsqueda para la recuperación de
+                decoradores. Como resultado, no puede registrar múltiples 
+                decoradores del mismo tipo; decoradores subsecuentes 
+                simplemente sobreescribirán aquellos que ya existían.
+            </para>
+
+            <para>
+                Para evitar esto, puede usar <emphasis>alias</emphasis>. En
+                lugar de pasar un decorador o nombre de decorador como primer
+                argumento a <code>addDecorator()</code>, pase una matriz con un
+                solo elemento, con el alias apuntando al nombre o objeto
+                decorador:
+            </para>
+
+            <programlisting role="php"><![CDATA[
+// Alias a 'FooBar':
+$element->addDecorator(array('FooBar' => 'HtmlTag'),
+                       array('tag' => 'div'));
+
+// Y recuperandolo posteriormente:
+$decorator = $element->getDecorator('FooBar');
+]]>
+            </programlisting>
+
+            <para>
+                En los métodos <code>addDecorators()</code> y
+                <code>setDecorators()</code>, necesitará pasar la opción
+                'decorator' en la matriz representando el decorador:
+            </para>
+
+            <programlisting role="php"><![CDATA[
+// Y dos decoradores 'HtmlTag', 'FooBar' como alias:
+$element->addDecorators(
+    array('HtmlTag', array('tag' => 'div')),
+    array(
+        'decorator' => array('FooBar' => 'HtmlTag'),
+        'options' => array('tag' => 'dd')
+    ),
+);
+
+// Y recuperándolos posteriormente:
+$htmlTag = $element->getDecorator('HtmlTag');
+$fooBar  = $element->getDecorator('FooBar');
+]]>
+            </programlisting>
+        </note>
+
+        <para>
+            Métodos asociados con decoradores incluyen:
+        </para>
+
+        <itemizedlist>
+            <listitem><para>
+                <code>addDecorator($nameOrDecorator, array $options = null)</code>
+            </para></listitem>
+
+            <listitem><para>
+                <code>addDecorators(array $decorators)</code>
+            </para></listitem>
+
+            <listitem><para>
+                <code>setDecorators(array $decorators)</code> (sobreescribe
+                todos los decoradores)
+            </para></listitem>
+
+            <listitem><para>
+                <code>getDecorator($name)</code> (recupera un objeto decorador
+                por su nombre)
+            </para></listitem>
+
+            <listitem><para>
+                <code>getDecorators()</code> (recupera todos los decoradores)
+            </para></listitem>
+
+            <listitem><para>
+                <code>removeDecorator($name)</code> (elimina un decorador por su
+                nombre)
+            </para></listitem>
+
+            <listitem><para>
+                <code>clearDecorators()</code> (elimina todos los decoradores)
+            </para></listitem>
+        </itemizedlist>
+
+        <para>
+            <code>Zend_Form_Element</code> también utiliza la sobrecarga para
+            permitir generar decoradores específicos. <code>__call()</code>
+            interceptará métodos que comiencen con el texto 'render' y utilizará
+            el resto del nombre del método para buscar un decorador; si se
+            encuentra, entonces será generado <emphasis>sólo ese</emphasis> 
+            decorador. Cualquier argumento pasado al llamado del método será
+            usado como contenido para pasar  al método <code>render()</code> del
+            decorador. Como ejemplo:
+        </para>
+
+        <programlisting role="php"><![CDATA[
+// Genera solo el decorador ViewHelper:
+echo $element->renderViewHelper();
+
+// Genera solo el decorador HtmlTag, pasándole contenido:
+echo $element->renderHtmlTag("This is the html tag content");
+]]></programlisting>
+
+        <para>
+            Si el decorador no existe, una excepción es lanzada.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.form.elements.metadata">
+        <title>Metadatos y atributos</title>
+
+        <para>
+            <code>Zend_Form_Element</code> manipula una variedad de atributos y
+            medatados del elemento. Atributos básicos incluyen:
+        </para>
+
+        <itemizedlist>
+            <listitem><para>
+                <emphasis>name</emphasis>: el nombre del elemento. Emplea los
+                métodos de acceso <code>setName()</code> y <code>getName()</code>.
+            </para></listitem>
+
+            <listitem><para>
+                <emphasis>label</emphasis>: la etiqueta del elemento. Emplea los
+                métodos de acceso <code>setLabel()</code> y <code>getLabel()</code>.
+            </para></listitem>
+
+            <listitem><para>
+                <emphasis>order</emphasis>: el índice en el cual los elementos
+                deben ir mostrándose en el formulario. Emplea los métodos de
+                acceso <code>setOrder()</code> y <code>getOrder()</code>.
+            </para></listitem>
+
+            <listitem><para>
+                <emphasis>value</emphasis>: El valor del elemento actual. Emplea
+                los métodos de acceso <code>setValue()</code> y 
+                <code>getValue()</code>.
+            </para></listitem>
+
+            <listitem><para>
+                <emphasis>description</emphasis>: una descripción del elemento;
+                a menudo utilizada para proveer un tooltip o ayuda contextual
+                con javascript describiendo el propósito del elemento. Emplea
+                los métodos de acceso <code>setDescription()</code> y 
+                <code>getDescription()</code>.
+            </para></listitem>
+
+            <listitem><para>
+                <emphasis>required</emphasis>: bandera que indica si un elemento
+                es requerido o no cuando se efectúa la validación del
+                formulario. Emplea los métodos de acceso 
+                <code>setRequired()</code> y <code>getRequired()</code>. Esta
+                bandera es false por defecto.
+            </para></listitem>
+
+            <listitem><para>
+                <emphasis>allowEmpty</emphasis>: bandera indicando si un
+                elemento no-requerido (opcional) debe intentar validar o no
+                valores vacíos. Cuando es true, y la bandera required es false,
+                valores vacíos no pasarán la cadena de validación, y se supone
+                verdadero. Emplea los métodos de acceso 
+                <code>setAllowEmpty()</code> y <code>getAllowEmpty()</code>.
+                Esta bandera es true por defecto.
+            </para></listitem>
+
+            <listitem><para>
+                <emphasis>autoInsertNotEmptyValidator</emphasis>: bandera 
+                indicando insertar o no un validador 'NotEmpty' cuando un
+                elemento es requerido. Por defecto, esta bandera es true.
+                Establezca la bandera con
+                <code>setAutoInsertNotEmptyValidator($flag)</code> y determine
+                el valor con <code>autoInsertNotEmptyValidator()</code>.
+            </para></listitem>
+        </itemizedlist>
+
+        <para>
+            Los elementos del formulario pueden requerir metainformación
+            adicional. Para elementos XHTML del formuladio, por ejemplo, puede
+            querer especificar atributos como el class o id. Para facilitar esto
+            hay un conjunto de métodos de acceso:
+        </para>
+
+        <itemizedlist>
+            <listitem><para>
+                <emphasis>setAttrib($name, $value)</emphasis>: añade un atributo
+            </para></listitem>
+
+            <listitem><para>
+                <emphasis>setAttribs(array $attribs)</emphasis>: como
+                addAttribs(), pero sobreescribiendo
+            </para></listitem>
+
+            <listitem><para>
+                <emphasis>getAttrib($name)</emphasis>: recupera el valor de solo
+                un atributo
+            </para></listitem>
+
+            <listitem><para>
+                <emphasis>getAttribs()</emphasis>: recupera todos los atributos
+                como pares clave/valor
+            </para></listitem>
+        </itemizedlist>
+
+        <para>
+            La mayoría de las veces, como sea, puede simplemente acceder a ellos
+            como propiedades de objeto, ya que <code>Zend_Form_Element</code>
+            utiliza la sobrecarga para facilitar el acceso a ellos:
+        </para>
+
+        <programlisting role="php"><![CDATA[
+// Equivalente a $element->setAttrib('class', 'text'):
+$element->class = 'text;
+]]>
+        </programlisting>
+
+        <para>
+            Por defecto, todos los atributos son pasados al auxiliar vista usado 
+            por el elemento durante la generación, y generados como atributos de
+            la etiqueta del elemento.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.form.elements.standard">
+        <title>Elementos Estándar</title>
+
+        <para>
+            <code>Zend_Form</code> contiene un buen número de elementos
+            estándar; por favor lea el capítulo <link linkend="zend.form.standardElements">Elementos Estándar</link> para
+            todos los detalles.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.form.elements.methods">
+        <title>Métodos de Zend_Form_Element</title>
+
+        <para>
+            <code>Zend_Form_Element</code> tiene muchos, muchos métodos. Lo que
+            sigue es un sumario de sus funciones, agrupados por tipo:
+        </para>
+
+        <itemizedlist>
+            <listitem><para>Configuración:</para>
+                <itemizedlist>
+                    <listitem><para><code>setOptions(array $options)</code></para></listitem>
+                    <listitem><para><code>setConfig(Zend_Config $config)</code></para></listitem>
+                </itemizedlist>
+            </listitem>
+
+            <listitem><para>I18n:</para>
+                <itemizedlist>
+                    <listitem><para><code>setTranslator(Zend_Translate_Adapter $translator = null)</code></para></listitem>
+                    <listitem><para><code>getTranslator()</code></para></listitem>
+                    <listitem><para><code>setDisableTranslator($flag)</code></para></listitem>
+                    <listitem><para><code>translatorIsDisabled()</code></para></listitem>
+                </itemizedlist>
+            </listitem>
+
+            <listitem><para>Propiedades:</para>
+                <itemizedlist>
+                    <listitem><para><code>setName($name)</code></para></listitem>
+                    <listitem><para><code>getName()</code></para></listitem>
+                    <listitem><para><code>setValue($value)</code></para></listitem>
+                    <listitem><para><code>getValue()</code></para></listitem>
+                    <listitem><para><code>getUnfilteredValue()</code></para></listitem>
+                    <listitem><para><code>setLabel($label)</code></para></listitem>
+                    <listitem><para><code>getLabel()</code></para></listitem>
+                    <listitem><para><code>setDescription($description)</code></para></listitem>
+                    <listitem><para><code>getDescription()</code></para></listitem>
+                    <listitem><para><code>setOrder($order)</code></para></listitem>
+                    <listitem><para><code>getOrder()</code></para></listitem>
+                    <listitem><para><code>setRequired($flag)</code></para></listitem>
+                    <listitem><para><code>getRequired()</code></para></listitem>
+                    <listitem><para><code>setAllowEmpty($flag)</code></para></listitem>
+                    <listitem><para><code>getAllowEmpty()</code></para></listitem>
+                    <listitem><para><code>setAutoInsertNotEmptyValidator($flag)</code></para></listitem>
+                    <listitem><para><code>autoInsertNotEmptyValidator()</code></para></listitem>
+                    <listitem><para><code>setIgnore($flag)</code></para></listitem>
+                    <listitem><para><code>getIgnore()</code></para></listitem>
+                    <listitem><para><code>getType()</code></para></listitem>
+                    <listitem><para><code>setAttrib($name, $value)</code></para></listitem>
+                    <listitem><para><code>setAttribs(array $attribs)</code></para></listitem>
+                    <listitem><para><code>getAttrib($name)</code></para></listitem>
+                    <listitem><para><code>getAttribs()</code></para></listitem>
+                </itemizedlist>
+            </listitem>
+
+            <listitem><para>Cargadores y rutas de plugin:</para>
+                <itemizedlist>
+                    <listitem><para><code>setPluginLoader(Zend_Loader_PluginLoader_Interface $loader, $type)</code></para></listitem>
+                    <listitem><para><code>getPluginLoader($type)</code></para></listitem>
+                    <listitem><para><code>addPrefixPath($prefix, $path, $type = null)</code></para></listitem>
+                    <listitem><para><code>addPrefixPaths(array $spec)</code></para></listitem>
+                </itemizedlist>
+            </listitem>
+
+            <listitem><para>Validación:</para>
+                <itemizedlist>
+                    <listitem><para><code>addValidator($validator, $breakChainOnFailure = false, $options = array())</code></para></listitem>
+                    <listitem><para><code>addValidators(array $validators)</code></para></listitem>
+                    <listitem><para><code>setValidators(array $validators)</code></para></listitem>
+                    <listitem><para><code>getValidator($name)</code></para></listitem>
+                    <listitem><para><code>getValidators()</code></para></listitem>
+                    <listitem><para><code>removeValidator($name)</code></para></listitem>
+                    <listitem><para><code>clearValidators()</code></para></listitem>
+                    <listitem><para><code>isValid($value, $context = null)</code></para></listitem>
+                    <listitem><para><code>getErrors()</code></para></listitem>
+                    <listitem><para><code>getMessages()</code></para></listitem>
+                </itemizedlist>
+            </listitem>
+
+            <listitem><para>Filtros:</para>
+                <itemizedlist>
+                    <listitem><para><code>addFilter($filter, $options = array())</code></para></listitem>
+                    <listitem><para><code>addFilters(array $filters)</code></para></listitem>
+                    <listitem><para><code>setFilters(array $filters)</code></para></listitem>
+                    <listitem><para><code>getFilter($name)</code></para></listitem>
+                    <listitem><para><code>getFilters()</code></para></listitem>
+                    <listitem><para><code>removeFilter($name)</code></para></listitem>
+                    <listitem><para><code>clearFilters()</code></para></listitem>
+                </itemizedlist>
+            </listitem>
+
+            <listitem><para>Generación:</para>
+                <itemizedlist>
+                    <listitem><para><code>setView(Zend_View_Interface $view = null)</code></para></listitem>
+                    <listitem><para><code>getView()</code></para></listitem>
+                    <listitem><para><code>addDecorator($decorator, $options = null)</code></para></listitem>
+                    <listitem><para><code>addDecorators(array $decorators)</code></para></listitem>
+                    <listitem><para><code>setDecorators(array $decorators)</code></para></listitem>
+                    <listitem><para><code>getDecorator($name)</code></para></listitem>
+                    <listitem><para><code>getDecorators()</code></para></listitem>
+                    <listitem><para><code>removeDecorator($name)</code></para></listitem>
+                    <listitem><para><code>clearDecorators()</code></para></listitem>
+                    <listitem><para><code>render(Zend_View_Interface $view = null)</code></para></listitem>
+                </itemizedlist>
+            </listitem>
+        </itemizedlist>
+    </sect2>
+
+    <sect2 id="zend.form.elements.config">
+        <title>Configuración</title>
+
+        <para>
+            El constructor de <code>Zend_Form_Element</code> acepta tanto una
+            matriz de opciones como un objeto <code>Zend_Config</code>
+            conteniendo opciones, y esto puede configurarse usando
+            <code>setOptions()</code> o <code>setConfig()</code>. Hablando de
+            manera general, las claves son nombradas de la siguiente manera:
+        </para>
+
+        <itemizedlist>
+            <listitem><para>
+                Si 'set' + clave se refiere a un método de 
+                <code>Zend_Form_Element</code>, entonces el valor provisto será
+                pasado a el método.
+            </para></listitem>
+
+            <listitem><para>
+                De otra manera, el valor será usado para establecer un atributo.
+            </para></listitem>
+        </itemizedlist>
+
+        <para>
+            Excepciones a la regla incluyen las siguientes:
+        </para>
+
+        <itemizedlist>
+            <listitem><para>
+                <code>prefixPath</code> será pasado a
+                <code>addPrefixPaths()</code>
+            </para></listitem>
+
+            <listitem>
+                <para>
+                    Los siguientes setters no pueden establecerse de esta manera:
+                </para>
+
+                <itemizedlist>
+                    <listitem><para>
+                            <code>setAttrib</code> (aunque
+                            <code>setAttribs</code> <emphasis>funcionará</emphasis>
+                    </para></listitem>
+
+                    <listitem><para><code>setConfig</code></para></listitem>
+
+                    <listitem><para><code>setOptions</code></para></listitem>
+
+                    <listitem><para><code>setPluginLoader</code></para></listitem>
+
+                    <listitem><para><code>setTranslator</code></para></listitem>
+
+                    <listitem><para><code>setView</code></para></listitem>
+                </itemizedlist>
+            </listitem>
+        </itemizedlist>
+
+        <para>
+            Como ejemplo, aquí esta un archivo de configuración pasado para
+            cada tipo de dato configurable:
+        </para>
+
+        <programlisting role="ini"><![CDATA[
+[element]
+name = "foo"
+value = "foobar"
+label = "Foo:"
+order = 10
+required = true
+allowEmpty = false
+autoInsertNotEmptyValidator = true
+description = "Foo elements are for examples"
+ignore = false
+attribs.id = "foo"
+attribs.class = "element"
+; sets 'onclick' attribute
+onclick = "autoComplete(this, '/form/autocomplete/element')"
+prefixPaths.decorator.prefix = "My_Decorator"
+prefixPaths.decorator.path = "My/Decorator/"
+disableTranslator = 0
+validators.required.validator = "NotEmpty"
+validators.required.breakChainOnFailure = true
+validators.alpha.validator = "alpha"
+validators.regex.validator = "regex"
+validators.regex.options.pattern = "/^[A-F].*/$"
+filters.ucase.filter = "StringToUpper"
+decorators.element.decorator = "ViewHelper"
+decorators.element.options.helper = "FormText"
+decorators.label.decorator = "Label"
+]]>
+</programlisting>
+    </sect2>
+
+    <sect2 id="zend.form.elements.custom">
+        <title>Elementos personalizados</title>
+
+        <para>
+            Usted puede crear sus propios elementos personalizados simplemente
+            extendiendo la clase <code>Zend_Form_Element</code>. Las razones
+            comunes para hacer esto incluyen:
+        </para>
+
+        <itemizedlist>
+            <listitem><para>
+                Elementos que comparten validadores y/o filtros comunes 
+            </para></listitem>
+
+            <listitem><para>
+                Elementos que tienen decoradores con funcionalidad personalizada
+            </para></listitem>
+        </itemizedlist>
+
+        <para>
+            Hay dos métodos típicamente usados para extender un elemento:
+            <code>init()</code>, el cual puede usarse para añadir una lógica de
+            inicialización personalizada a su elemento, y
+            <code>loadDefaultDecorators()</code>, el cual puede usarse para
+            establecer una lista de decoradores usados por su elemento de manera
+            predeterminada.
+        </para>
+
+        <para>
+            Como un ejemplo, digamos que todos los elementos de tipo texto en un
+            formulario que está creando, necesitan ser filtrados con
+            <code>StringTrim</code>, validados con una expresión regular, y que
+            quiere usar un decorador personalizado que ha creado para
+            mostrarlos, 'My_Decorator_TextItem'; adicionalmente, tiene un número
+            de atributos estándars, incluyendo 'size', 'maxLength', y 'class'
+            que quisiera especificar. Puede definir un elemento tal como sigue:
+        </para>
+
+        <programlisting role="php"><![CDATA[
+class My_Element_Text extends Zend_Form_Element
+{
+    public function init()
+    {
+        $this->addPrefixPath('My_Decorator', 'My/Decorator/', 'decorator')
+             ->addFilters('StringTrim')
+             ->addValidator('Regex', false, array('/^[a-z0-9]{6,}$/i'))
+             ->addDecorator('TextItem')
+             ->setAttrib('size', 30)
+             ->setAttrib('maxLength', 45)
+             ->setAttrib('class', 'text');
+    }
+}
+]]>
+        </programlisting>
+
+        <para>
+            Entonces puede informar a su objeto formulario acerca del prefijo de
+            ruta para elementos de ese tipo, y comenzar creando elementos:
+        </para>
+
+        <programlisting role="php"><![CDATA[
+$form->addPrefixPath('My_Element', 'My/Element/', 'element')
+     ->addElement('foo', 'text');
+]]>
+        </programlisting>
+
+        <para>
+            El elemento 'foo' será ahora del tipo <code>My_Element_Text</code>,
+            y mostrará el comportamiento que ha especificado.
+        </para>
+
+        <para>
+            Otro método que puede querer sobreescribir cuando extienda
+            <code>Zend_Form_Element</code> es el método
+            <code>loadDefaultDecorators()</code>. Este método carga
+            condicionalmente un grupo de decoradores predefinidos para su
+            elemento; puede querer sustituir su propio decorador en su clase
+            extendida:
+        </para>
+
+        <programlisting role="php"><![CDATA[
+class My_Element_Text extends Zend_Form_Element
+{
+    public function loadDefaultDecorators()
+    {
+        $this->addDecorator('ViewHelper')
+             ->addDecorator('DisplayError')
+             ->addDecorator('Label')
+             ->addDecorator('HtmlTag',
+                            array('tag' => 'div', 'class' => 'element'));
+    }
+}
+]]>
+        </programlisting>
+
+        <para>
+            Hay muchas maneras de personalizar elementos; asegúrese de leer la
+            documentación de la API de <code>Zend_Form_Element</code> para
+            conocer todos los métodos disponibles.
+        </para>
+    </sect2>
+</sect1>
+<!--
+vim:se ts=4 sw=4 tw=80 ai et:
+-->

+ 745 - 745
documentation/manual/es/module_specs/Zend_Form-StandardElements.xml

@@ -1,745 +1,745 @@
-<sect1 id="zend.form.standardElements">
-    <title>Elementos Enviados en el Formulario Estandard de Zend Framework</title>
-
-    <para>
-        Zend Framework viene con clases de elementos concretos cubriendo la 
-        mayoría de los elementos de los formularios HTML. La mayoría simplemente 
-        especifica una vista de ayuda para usar cuando se decora el elemento, 
-        pero varios ofrecen funcionalidad adicional. La siguiente es una lista
-        de todas las clases, así como también una descripción de la 
-        funcionalidad que ofrecen.
-    </para>
-
-    <sect2 id="zend.form.standardElements.button">
-        <title>Zend_Form_Element_Button</title>
-
-        <para>
-            Usada para crear elementos HTML de tipo button,
-            <code>Zend_Form_Element_Button</code> extiende <link linkend="zend.form.standardElements.submit">Zend_Form_Element_Submit</link>,
-            derivandi sy funcionalidad personalizada. It specifies the 'formButton'
-            view helper for decoration.
-        </para>
-
-        <para>
-            Like the submit element, it uses the element's label as the element
-            value for display purposes; in other words, to set the text of the
-            button, set the value of the element. The label will be translated
-            if a translation adapter is present.
-        </para>
-
-        <para>
-            Because the label is used as part of the element, the button element
-            uses only the <link linkend="zend.form.standardDecorators.viewHelper">ViewHelper</link>
-            and <link linkend="zend.form.standardDecorators.dtDdWrapper">DtDdWrapper</link>
-            decorators.
-        </para>
-
-        <para>
-            Después de llenar o validar un formulario, se puede verificar si el
-            botón dado fue clickeado usando el método <code>isChecked()</code>.
-        </para>
-    </sect2>
-
-    <sect2 id="zend.form.standardElements.captcha">
-        <title>Zend_Form_Element_Captcha</title>
-
-        <para>
-            Los CAPTCHAs son usados para prevenir el envio automático de 
-            formularios por los robots y otros procesos automatizados.
-        </para>
-
-        <para>
-            The Captcha form element allows you to specify which 
-            <link linkend="zend.captcha.adapters">Zend_Captcha adapter</link> you
-            wish to utilize as a form captcha. It then sets this adapter as a
-            validator to the object, and uses a Captcha decorator for rendering
-            (which proxies to the captcha adapter).
-        </para>
-
-        <para>
-            Adapters may be any adapters in <code>Zend_Captcha</code>, as well
-            as any custom adapters you may have defined elsewhere. To allow
-            this, you may pass an additional plugin loader type key, 'CAPTCHA'
-            or 'captcha', when specifying a plugin loader prefix path:
-        </para>
-
-        <programlisting role="php"><![CDATA[
-$element->addPrefixPath('My_Captcha', 'My/Captcha/', 'captcha');
-]]>
-        </programlisting>
-
-        <para>
-            Los Captcha entonces pueden ser cargados usando el método 
-            <code>setCaptcha()</code>, el cual puede tomar una instancia 
-            cualquiera de captcha instance, o el nombre corto del adaptador 
-            captcha:
-        </para>
-
-        <programlisting role="php"><![CDATA[
-// instancia concreta:
-$element->setCaptcha(new Zend_Captcha_Figlet());
-
-// Usando nombre corto:
-$element->setCaptcha('Dumb');
-]]>
-        </programlisting>
-
-        <para>
-            Si desea cargar sus elementos configuración, especifique la clave
-            'captcha' con un array conteniendo la clave 'captcha', o            
-            ambas claves 'captcha' y 'captchaOptions':
-        </para>
-
-        <programlisting role="php"><![CDATA[
-// Usindo la clave captcha simple:
-$element = new Zend_Form_Element_Captcha('foo', array(
-    'label' => "Please verify you're a human",
-    'captcha' => array(
-        'captcha' => 'Figlet',
-        'wordLen' => 6,
-        'timeout' => 300,
-    ),
-));
-
-// Usindo captcha y captchaOptions:
-$element = new Zend_Form_Element_Captcha('foo', array(
-    'label' => "Please verify you're a human"
-    'captcha' => 'Figlet',
-    'captchaOptions' => array(
-        'captcha' => 'Figlet',
-        'wordLen' => 6,
-        'timeout' => 300,
-    ),
-));
-]]>
-        </programlisting>
-
-        <para>
-            El decorador usado es determinado consultando el adaptador captcha.
-            Por defecto, es usado el 
-            <link linkend="zend.form.standardDecorators.captcha">Captcha
-            decorator</link>, pero un adaptadpr puede especificar uno                
-            diferente vía su método<code>getDecorator()</code>.
-        </para>
-
-        <para>
-            Como ha notado, el adaptador captcha actúa él mismo como un validador
-            para el elemento. Adicionalmente, el validador NotEmpty validator 
-            no es usado y el elemento es marcado como requerido. Enla mayoría de
-            los casos, usted no necesitará hacer nada más para tener un captcha 
-            presente en su formulario.
-        </para>
-    </sect2>
-
-    <sect2 id="zend.form.standardElements.checkbox">
-        <title>Zend_Form_Element_Checkbox</title>
-
-        <para>
-            Las casillas de verigicación (checkboxes) HTML le permiten devolver 
-            un valor específico, pero básicamente operata como los booleanos: 
-            cuando está marcada, el valor es enviado; cuando no está marcada, no                     se envía nada. Internamente, Zend_Form_Element_Checkbox forza este 
-            estado.
-        </para>
-
-        <para>
-            Por defecto, si la casilla (checkbox) está marcada su valor es '1', 
-            y si no está marcada su valor es '0'.
-            You can specify the values to use using the
-            <code>setCheckedValue()</code> and <code>setUncheckedValue()</code>
-            accessors, respectively. Internally, any time you set the value, if
-            the provided value matches the checked value, then it is set, but
-            any other value causes the unchecked value to be set.
-        </para>
-
-        <para>
-            Additionally, setting the value sets the <code>checked</code>
-            property of the checkbox. You can query this using
-            <code>isChecked()</code> or simply accessing the property. Using the
-            <code>setChecked($flag)</code> method will both set the state of the
-            flag as well as set the appropriate checked or unchecked value in the
-            element. Please use this method when setting the checked state of a
-            checkbox element to ensure the value is set properly.
-        </para>
-
-        <para>
-            <code>Zend_Form_Element_Checkbox</code> uses the 'formCheckbox' view
-            helper. The checked value is always used to populate it.
-        </para>
-    </sect2>
-
-    <sect2 id="zend.form.standardElements.file">
-        <title>Zend_Form_Element_File</title>
-
-        <para>
-            The File form element provides a mechanism for supplying file upload
-            fields to your form. It utilizes <link linkend="zend.file.transfer.introduction">Zend_File_Transfer</link>
-            internally to provide this functionality, and the
-            <code>FormFile</code> view helper as also the <code>File</code>
-            decorator to display the form element.
-        </para>
-
-        <para>
-            By default, it uses the <code>Http</code> transfer adapter, which
-            introspects the <code>$_FILES</code> array and allows you to attach
-            validators and filters. Validators and filters attached to the form
-            element will be attached to the transfer adapter.
-        </para>
-
-        <example id="zend.form.standardElements.file.usage">
-            <title>File form element usage</title>
-
-            <para>
-                The above explanation of using the File form element may seem
-                arcane, but actual usage is relatively trivial:
-            </para>
-
-            <programlisting role="php"><![CDATA[
-$element = new Zend_Form_Element_File('foo');
-$element->setLabel('Upload an image:')
-        ->setDestination('/var/www/upload');
-// ensure only 1 file
-$element->addValidator('Count', false, 1);
-// limit to 100K
-$element->addValidator('Size', false, 102400);
-// only JPEG, PNG, and GIFs
-$element->addValidator('Extension', false, 'jpg,png,gif');
-$form->addElement($element, 'foo');
-]]>
-            </programlisting>
-
-            <para>
-                También debe asegurarse de que se ha provisto un tipo de 
-                codificación corecto al formulario; se debe utilizar
-                'multipart/form-data'. Se puede hacer esto estableciendo el 
-                atributo 'enctype' en el formulario:
-            </para>
-
-            <programlisting role="php"><![CDATA[
-$form->setAttrib('enctype', 'multipart/form-data');
-]]>
-            </programlisting>
-
-            <para>
-                Cuando el atributo ha sido validado exitosamente, usted debe 
-                recibir el archivo para alamacenarlo en el destino final 
-                usando receive(). Adicionalmente puede determinar la 
-                ubicación final usando getFileName():
-            </para>
-
-            <programlisting role="php"><![CDATA[
-if (!$form->isValid) {
-    print "Ohoh... validation error";
-}
-
-if (!$form->foo->receive()) {
-    print "Error receiving the file";
-}
-
-$location = $form->foo->getFileName();
-]]>
-            </programlisting>
-
-        </example>
-
-        <note>
-            <title>Ubicaciones Predeterminadas para la Carga de Archivos</title>
-
-            <para>
-                Por defecto, los archivos son cargados al directorio temp del 
-                sistema.
-            </para>
-        </note>
-
-        <note>
-            <title>Valores de archivo</title>
-
-            <para>
-                Dentro de HTTP un elemento file no tiene valor. Por tanto y a 
-                causa de razones de seguridad usted solo obtendrá el nombre del
-                archivo cargado llamando  a getValue() y no el destino completo. 
-                si usted necesita la información completa  llame getFileName() y 
-                le retormará el destino y nombre de archivo completo.
-            </para>
-        </note>
-
-        <para>
-            <code>Zend_Form_Element_File</code> soporta también archivos
-            múltiples. Para llamar el método <code>setMultiFile($count)</code> 
-            usted puede establecer la cantidad de elementos file que usted desea 
-            crear. Esto le previene de establecer la misma configuración varias 
-            veces.
-        </para>
-
-        <example id="zend.form.standardElements.file.multiusage">
-            <title>Configuración de múltiples archivos</title>
-
-            <para>
-                Crear un elemento multi archivo es lo mismo que querer configurar
-                un elemento único. Sólo tiene que llamar a 
-                <code>setMultiFile()</code> adicionalmente después de la creación:
-            </para>
-
-            <programlisting role="php"><![CDATA[
-$element = new Zend_Form_Element_File('foo');
-$element->setLabel('Upload an image:')
-        ->setDestination('/var/www/upload');
-// asegura mínimo 1, maximo 3 archivos
-$element->addValidator('Count', false, array('min' => 1, 'max' => 3));
-// limita a 100K
-$element->addValidator('Size', false, 102400);
-// solo JPEG, PNG, y GIFs
-$element->addValidator('Extension', false, 'jpg,png,gif');
-// define 3 elementos file idénticos
-$element->setMultiFile(3);
-$form->addElement($element, 'foo');
-]]>
-            </programlisting>
-
-            <para>
-                En su vista usted ahora obtendrá 3 elementos para carga de 
-                archivos idénticos los cuales comparten la misma configuración.
-                para obtener  el conjunto de el número de archivos múltiples 
-                simplemente llame  <code>getMultiFile()</code>.
-            </para>
-
-        </example>
-
-        <note>
-            <title>Elementos File en Subformularioss</title>
-
-            <para>
-                Cuando usted use elementos file in subformularios debería 
-                establecer nombres únicos.
-                Así, cuando usted nombre su elemento file en el subformulario1, 
-                debe darle un nombre diferente el el subformulario2.
-            </para>
-
-            <para>
-                Tan pronto como haya dos elementos file nombrados de forma 
-                idéntica, el segundo elemento no se mostrará o enviará.
-            </para>
-        </note>
-
-        <para>
-            Para limitar el tamaño del archivo, el cual es cargado por el 
-            cliente, debe establecer el tamaño máximo de archivo que el 
-            formulario acepta . Esto limitará eñ tamaño del archivo en el lado 
-            del cliente configurando la opción <code>MAX_FILE_SIZE</code>
-            en el formulario. Tan pronto como establesca este valor usando 
-            el método <code>setMaxFileSize($size)</code>, estó será generado
-            con el elemento file.
-        </para>
-
-        <programlisting role="php"><![CDATA[
-$element = new Zend_Form_Element_File('foo');
-$element->setLabel('Upload an image:')
-        ->setDestination('/var/www/upload')
-        ->addValidator('Size', false, 102400) // límite en 100K
-        ->setMaxFileSize(102400); // limita el tamaño del archivo en el lado del cliente
-$form->addElement($element, 'foo');
-]]>
-        </programlisting>
-
-        <note>
-            <title>MaxFileSize con elementos file múltiples</title>
-
-            <para>
-                Cuando usted usa elementos file múltiples en los formularios tiene
-                que establecer el <code>MAX_FILE_SIZE</code> una sola vez.
-                 Establecerlo otra vez sobreescribirá el valor previamente 
-                 establecido.
-            </para>
-
-            <para>
-                Note, que usted puede establecer <code>MAX_FILE_SIZE</code> 
-                una sola ves, incluso si usas múltiples formularios.
-            </para>
-        </note>
-    </sect2>
-
-    <sect2 id="zend.form.standardElements.hidden">
-        <title>Zend_Form_Element_Hidden</title>
-
-        <para>
-            Los elementos Hidden simplemente injectan datos que deben ser 
-            enviados, pero que el usuario no debe manipular.
-            <code>Zend_Form_Element_Hidden</code> logra esto através del uso de
-            el helper de vista 'formHidden'.
-        </para>
-    </sect2>
-
-    <sect2 id="zend.form.standardElements.hash">
-        <title>Zend_Form_Element_Hash</title>
-
-        <para>
-            Este elemento provee protección de ataques desde CSRF sobre 
-            formularios, asegurando que el dato es enviado por la sesión del
-            usuario que generó el formulario y no por un script pillero. 
-            La protección se logra mediante la adición de un elemento hash a             
-            un formulario y verificandolo cuando el formulario es enviado.
-        </para>
-
-        <para>
-            El nombre del elemnto hash debe ser único. Se recomienda usar la 
-            opción <literal>salt</literal> para el elemento, dos hashes con
-            el mismo nombre y diferentes salts no chocan:
-        </para>
-
-        <programlisting role="php"><![CDATA[
-$form->addElement('hash', 'no_csrf_foo', array('salt' => 'unique'));
-]]>
-        </programlisting>
-
-        <para>
-            Puede establecer el salt más tarde usando el método
-            <code>setSalt($salt)</code>.
-        </para>
-
-        <para>
-            Internamente, el elemento alamacena un identificador único usando
-            <code>Zend_Session_Namespace</code>, y lo comprueba en el momento
-            que se envía (comprueba que el TTL has no espiró). El validador 
-            'Identical' entonces es usado para asegurarse que el hash enviado
-            marcha con el hash alamacenado.
-        </para>
-
-        <para>
-            El helper de vista 'formHidden' es usado par generar el elemento 
-            en el formulario.
-            form.
-        </para>
-    </sect2>
-
-    <sect2 id="zend.form.standardElements.Image">
-        <title>Zend_Form_Element_Image</title>
-
-        <para>
-            Las imáagenes pueden ser usadas como elmentos de formulario, y le
-            permite  especificar elementos gráficos como botones de formulario.
-        </para>
-
-        <para>
-            Los elementos Image necesitan una imagen fuente. 
-            <code>Zend_Form_Element_Image</code>  le permite especificar esto
-            usando el método de acceso <code>setImage()</code>
-            (o clave de configuración 'image'). Opcionalmente, también puede 
-            especificar un valor para utilizar al momento de enviar la imagen
-             utilizando  el método de acceso <code>setImageValue()</code> 
-            (o clave de configuración 'imageValue'). Cuando el valor establecido
-            para el elemento son similares al <code>imageValue</code>, entonces  
-            el método de acceso <code>isChecked()</code> devolverá true.
-        </para>
-
-        <para>
-            El elemento Image usa el 
-            <link linkend="zend.form.standardDecorators.image">Decorador de 
-            Imagen </link> para generar (así como el estandard Errors,
-            HtmlTag, y decorador Label). Opcionalmente, puede especificar una
-            etiqueta para el decorador <code>Image</code> que luego 
-            envuelva al elemento imagen.
-        </para>
-    </sect2>
-
-    <sect2 id="zend.form.standardElements.multiCheckbox">
-        <title>Zend_Form_Element_MultiCheckbox</title>
-
-        <para>
-            A menudo tiene un conjunto de checkboxes, y desea agrupar los 
-            resultados. Esto es como un 
-            <link linkend="zend.form.standardElements.multiselect">Multiselect</link>,
-            pero en lugar de estar en una lista desplegable, necesita mostrarlos en pares checkbox/value (casilla de verificación/valor).
-        </para>
-
-        <para>
-            <code>Zend_Form_Element_MultiCheckbox</code> hace esto sencillo. Like
-            all other elements extending the base Multi element, you can specify
-            a list of options, and easily validate against that same list. The
-            'formMultiCheckbox' view helper ensures that these are returned as
-            an array in the form submission.
-        </para>
-
-        <para>
-            By default, this element registers an <code>InArray</code> validator
-            which validates against the array keys of registered options. You
-            can disable this behavior by either calling
-            <code>setRegisterInArrayValidator(false)</code>, or by passing a
-            false value to the <code>registerInArrayValidator</code>
-            configuration key.
-        </para>
-
-        <para>
-            You may manipulate the various checkbox options using the following
-            methods:
-        </para>
-
-        <itemizedlist>
-            <listitem><para><code>addMultiOption($option, $value)</code></para></listitem>
-
-            <listitem><para><code>addMultiOptions(array $options)</code></para></listitem>
-
-            <listitem><para><code>setMultiOptions(array $options)</code>
-                    (overwrites existing options)</para></listitem>
-
-            <listitem><para>getMultiOption($option)</para></listitem>
-
-            <listitem><para>getMultiOptions()</para></listitem>
-
-            <listitem><para><code>removeMultiOption($option)</code></para></listitem>
-
-            <listitem><para><code>clearMultiOptions()</code></para></listitem>
-        </itemizedlist>
-
-        <para>
-            To mark checked items, you need to pass an array of values to
-            <code>setValue()</code>. The following will check the values "bar"
-            and "bat":
-        </para>
-
-        <programlisting role="php"><![CDATA[
-$element = new Zend_Form_Element_MultiCheckbox('foo', array(
-    'multiOptions' => array(
-        'foo' => 'Foo Option',
-        'bar' => 'Bar Option',
-        'baz' => 'Baz Option',
-        'bat' => 'Bat Option',
-    );
-));
-
-$element->setValue(array('bar', 'bat'));
-]]>
-        </programlisting>
-
-        <para>
-            Note that even when setting a single value, you must pass an array.
-        </para>
-    </sect2>
-
-    <sect2 id="zend.form.standardElements.multiselect">
-        <title>Zend_Form_Element_Multiselect</title>
-
-        <para>
-            XHTML <code>select</code> elements allow a 'multiple' attribute,
-            indicating multiple options may be selected for submission, instead
-            of the usual one. <code>Zend_Form_Element_Multiselect</code> extends
-            <link linkend="zend.form.standardElements.select">Zend_Form_Element_Select</link>,
-            and sets the <code>multiple</code> attribute to 'multiple'. Like
-            other classes that inherit from the base
-            <code>Zend_Form_Element_Multi</code> class, you can manipulate the
-            options for the select using:
-        </para>
-
-        <itemizedlist>
-            <listitem><para><code>addMultiOption($option, $value)</code></para></listitem>
-
-            <listitem><para><code>addMultiOptions(array $options)</code></para></listitem>
-
-            <listitem><para><code>setMultiOptions(array $options)</code>
-                    (overwrites existing options)</para></listitem>
-
-            <listitem><para>getMultiOption($option)</para></listitem>
-
-            <listitem><para>getMultiOptions()</para></listitem>
-
-            <listitem><para><code>removeMultiOption($option)</code></para></listitem>
-
-            <listitem><para><code>clearMultiOptions()</code></para></listitem>
-        </itemizedlist>
-
-        <para>
-            If a translation adapter is registered with the form and/or element,
-            option values will be translated for display purposes.
-        </para>
-
-        <para>
-            By default, this element registers an <code>InArray</code> validator
-            which validates against the array keys of registered options. You
-            can disable this behavior by either calling
-            <code>setRegisterInArrayValidator(false)</code>, or by passing a
-            false value to the <code>registerInArrayValidator</code>
-            configuration key.
-        </para>
-    </sect2>
-
-    <sect2 id="zend.form.standardElements.password">
-        <title>Zend_Form_Element_Password</title>
-
-        <para>
-            Password elements are basically normal text elements -- except that
-            you typically do not want the submitted password displayed in error
-            messages or the element itself when the form is re-displayed.
-        </para>
-
-        <para>
-            <code>Zend_Form_Element_Password</code> achieves this by calling
-            <code>setObscureValue(true)</code> on each validator (ensuring that
-            the password is obscured in validation error messages), and using
-            the 'formPassword' view helper (which does not display the value
-            passed to it).
-        </para>
-    </sect2>
-
-    <sect2 id="zend.form.standardElements.radio">
-        <title>Zend_Form_Element_Radio</title>
-
-        <para>
-            Radio elements allow you to specify several options, of which you
-            need a single value returned. <code>Zend_Form_Element_Radio</code>
-            extends the base <code>Zend_Form_Element_Multi</code> class,
-            allowing you to specify a number of options, and then uses the
-            <code>formRadio</code> view helper to display these.
-        </para>
-
-        <para>
-            By default, this element registers an <code>InArray</code> validator
-            which validates against the array keys of registered options. You
-            can disable this behavior by either calling
-            <code>setRegisterInArrayValidator(false)</code>, or by passing a
-            false value to the <code>registerInArrayValidator</code>
-            configuration key.
-        </para>
-
-        <para>
-            Like all elements extending the Multi element base class, the
-            following methods may be used to manipulate the radio options
-            displayed:
-        </para>
-
-        <itemizedlist>
-            <listitem><para><code>addMultiOption($option, $value)</code></para></listitem>
-
-            <listitem><para><code>addMultiOptions(array $options)</code></para></listitem>
-
-            <listitem><para><code>setMultiOptions(array $options)</code>
-                    (overwrites existing options)</para></listitem>
-
-            <listitem><para>getMultiOption($option)</para></listitem>
-
-            <listitem><para>getMultiOptions()</para></listitem>
-
-            <listitem><para><code>removeMultiOption($option)</code></para></listitem>
-
-            <listitem><para><code>clearMultiOptions()</code></para></listitem>
-        </itemizedlist>
-    </sect2>
-
-    <sect2 id="zend.form.standardElements.reset">
-        <title>Zend_Form_Element_Reset</title>
-
-        <para>
-            Reset buttons are typically used to clear a form, and are not part
-            of submitted data. However, as they serve a purpose in the display,
-            they are included in the standard elements.
-        </para>
-
-        <para>
-            <code>Zend_Form_Element_Reset</code> extends <link linkend="zend.form.standardElements.submit">Zend_Form_Element_Submit</link>.
-            As such, the label is used for the button display, and will be
-            translated if a translation adapter is present. It utilizes only the
-            'ViewHelper' and 'DtDdWrapper' decorators, as there should never be
-            error messages for such elements, nor will a label be necessary.
-        </para>
-    </sect2>
-
-    <sect2 id="zend.form.standardElements.select">
-        <title>Zend_Form_Element_Select</title>
-
-        <para>
-            Select boxes are a common way of limiting to specific choices for a
-            given form datum. <code>Zend_Form_Element_Select</code> allows you
-            to generate these quickly and easily.
-        </para>
-
-        <para>
-            By default, this element registers an <code>InArray</code> validator
-            which validates against the array keys of registered options. You
-            can disable this behavior by either calling
-            <code>setRegisterInArrayValidator(false)</code>, or by passing a
-            false value to the <code>registerInArrayValidator</code>
-            configuration key.
-        </para>
-
-        <para>
-            As it extends the base Multi element, the following methods may be
-            used to manipulate the select options:
-        </para>
-
-        <itemizedlist>
-            <listitem><para><code>addMultiOption($option, $value)</code></para></listitem>
-
-            <listitem><para><code>addMultiOptions(array $options)</code></para></listitem>
-
-            <listitem><para><code>setMultiOptions(array $options)</code>
-                    (overwrites existing options)</para></listitem>
-
-            <listitem><para>getMultiOption($option)</para></listitem>
-
-            <listitem><para>getMultiOptions()</para></listitem>
-
-            <listitem><para><code>removeMultiOption($option)</code></para></listitem>
-
-            <listitem><para><code>clearMultiOptions()</code></para></listitem>
-        </itemizedlist>
-
-        <para>
-            <code>Zend_Form_Element_Select</code> uses the 'formSelect' view
-            helper for decoration.
-        </para>
-    </sect2>
-
-    <sect2 id="zend.form.standardElements.submit">
-        <title>Zend_Form_Element_Submit</title>
-
-        <para>
-            Submit buttons are used to submit a form. You may use multiple
-            submit buttons; you can use the button used to submit the form to
-            decide what action to take with the data submitted.
-            <code>Zend_Form_Element_Submit</code> makes this decisioning easy,
-            by adding a <code>isChecked()</code> method; as only one button
-            element will be submitted by the form, after populating or
-            validating the form, you can call this method on each submit button
-            to determine which one was used.
-        </para>
-
-        <para>
-            <code>Zend_Form_Element_Submit</code> uses the label as the "value"
-            of the submit button, translating it if a translation adapter is
-            present. <code>isChecked()</code> checks the submitted value against
-            the label in order to determine if the button was used.
-        </para>
-
-        <para>
-            The <link linkend="zend.form.standardDecorators.viewHelper">ViewHelper</link>
-            and <link linkend="zend.form.standardDecorators.dtDdWrapper">DtDdWrapper</link>
-            decorators to render the element. No label decorator is used, as the
-            button label is used when rendering the element; also, typically,
-            you will not associate errors with a submit element.
-        </para>
-    </sect2>
-
-    <sect2 id="zend.form.standardElements.text">
-        <title>Zend_Form_Element_Text</title>
-
-        <para>
-            By far the most prevalent type of form element is the text element,
-            allowing for limited text entry; it's an ideal element for most data
-            entry. <code>Zend_Form_Element_Text</code> simply uses the
-            'formText' view helper to display the element.
-        </para>
-    </sect2>
-
-    <sect2 id="zend.form.standardElements.textarea">
-        <title>Zend_Form_Element_Textarea</title>
-
-        <para>
-            Textareas are used when large quantities of text are expected, and
-            place no limits on the amount of text submitted (other than maximum
-            size limits as dictated by your server or PHP).
-            <code>Zend_Form_Element_Textarea</code> uses the 'textArea' view
-            helper to display such elements, placing the value as the content of
-            the element.
-        </para>
-    </sect2>
-</sect1>
-<!--
-vim:se ts=4 sw=4 tw=80 et:
--->
+<sect1 id="zend.form.standardElements">
+    <title>Elementos Enviados en el Formulario Estandard de Zend Framework</title>
+
+    <para>
+        Zend Framework viene con clases de elementos concretos cubriendo la 
+        mayoría de los elementos de los formularios HTML. La mayoría simplemente 
+        especifica una vista de ayuda para usar cuando se decora el elemento, 
+        pero varios ofrecen funcionalidad adicional. La siguiente es una lista
+        de todas las clases, así como también una descripción de la 
+        funcionalidad que ofrecen.
+    </para>
+
+    <sect2 id="zend.form.standardElements.button">
+        <title>Zend_Form_Element_Button</title>
+
+        <para>
+            Usada para crear elementos HTML de tipo button,
+            <code>Zend_Form_Element_Button</code> extiende <link linkend="zend.form.standardElements.submit">Zend_Form_Element_Submit</link>,
+            derivandi sy funcionalidad personalizada. It specifies the 'formButton'
+            view helper for decoration.
+        </para>
+
+        <para>
+            Like the submit element, it uses the element's label as the element
+            value for display purposes; in other words, to set the text of the
+            button, set the value of the element. The label will be translated
+            if a translation adapter is present.
+        </para>
+
+        <para>
+            Because the label is used as part of the element, the button element
+            uses only the <link linkend="zend.form.standardDecorators.viewHelper">ViewHelper</link>
+            and <link linkend="zend.form.standardDecorators.dtDdWrapper">DtDdWrapper</link>
+            decorators.
+        </para>
+
+        <para>
+            Después de llenar o validar un formulario, se puede verificar si el
+            botón dado fue clickeado usando el método <code>isChecked()</code>.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.form.standardElements.captcha">
+        <title>Zend_Form_Element_Captcha</title>
+
+        <para>
+            Los CAPTCHAs son usados para prevenir el envio automático de 
+            formularios por los robots y otros procesos automatizados.
+        </para>
+
+        <para>
+            The Captcha form element allows you to specify which 
+            <link linkend="zend.captcha.adapters">Zend_Captcha adapter</link> you
+            wish to utilize as a form captcha. It then sets this adapter as a
+            validator to the object, and uses a Captcha decorator for rendering
+            (which proxies to the captcha adapter).
+        </para>
+
+        <para>
+            Adapters may be any adapters in <code>Zend_Captcha</code>, as well
+            as any custom adapters you may have defined elsewhere. To allow
+            this, you may pass an additional plugin loader type key, 'CAPTCHA'
+            or 'captcha', when specifying a plugin loader prefix path:
+        </para>
+
+        <programlisting role="php"><![CDATA[
+$element->addPrefixPath('My_Captcha', 'My/Captcha/', 'captcha');
+]]>
+        </programlisting>
+
+        <para>
+            Los Captcha entonces pueden ser cargados usando el método 
+            <code>setCaptcha()</code>, el cual puede tomar una instancia 
+            cualquiera de captcha instance, o el nombre corto del adaptador 
+            captcha:
+        </para>
+
+        <programlisting role="php"><![CDATA[
+// instancia concreta:
+$element->setCaptcha(new Zend_Captcha_Figlet());
+
+// Usando nombre corto:
+$element->setCaptcha('Dumb');
+]]>
+        </programlisting>
+
+        <para>
+            Si desea cargar sus elementos configuración, especifique la clave
+            'captcha' con un array conteniendo la clave 'captcha', o            
+            ambas claves 'captcha' y 'captchaOptions':
+        </para>
+
+        <programlisting role="php"><![CDATA[
+// Usindo la clave captcha simple:
+$element = new Zend_Form_Element_Captcha('foo', array(
+    'label' => "Please verify you're a human",
+    'captcha' => array(
+        'captcha' => 'Figlet',
+        'wordLen' => 6,
+        'timeout' => 300,
+    ),
+));
+
+// Usindo captcha y captchaOptions:
+$element = new Zend_Form_Element_Captcha('foo', array(
+    'label' => "Please verify you're a human"
+    'captcha' => 'Figlet',
+    'captchaOptions' => array(
+        'captcha' => 'Figlet',
+        'wordLen' => 6,
+        'timeout' => 300,
+    ),
+));
+]]>
+        </programlisting>
+
+        <para>
+            El decorador usado es determinado consultando el adaptador captcha.
+            Por defecto, es usado el 
+            <link linkend="zend.form.standardDecorators.captcha">Captcha
+            decorator</link>, pero un adaptadpr puede especificar uno                
+            diferente vía su método<code>getDecorator()</code>.
+        </para>
+
+        <para>
+            Como ha notado, el adaptador captcha actúa él mismo como un validador
+            para el elemento. Adicionalmente, el validador NotEmpty validator 
+            no es usado y el elemento es marcado como requerido. Enla mayoría de
+            los casos, usted no necesitará hacer nada más para tener un captcha 
+            presente en su formulario.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.form.standardElements.checkbox">
+        <title>Zend_Form_Element_Checkbox</title>
+
+        <para>
+            Las casillas de verigicación (checkboxes) HTML le permiten devolver 
+            un valor específico, pero básicamente operata como los booleanos: 
+            cuando está marcada, el valor es enviado; cuando no está marcada, no                     se envía nada. Internamente, Zend_Form_Element_Checkbox forza este 
+            estado.
+        </para>
+
+        <para>
+            Por defecto, si la casilla (checkbox) está marcada su valor es '1', 
+            y si no está marcada su valor es '0'.
+            You can specify the values to use using the
+            <code>setCheckedValue()</code> and <code>setUncheckedValue()</code>
+            accessors, respectively. Internally, any time you set the value, if
+            the provided value matches the checked value, then it is set, but
+            any other value causes the unchecked value to be set.
+        </para>
+
+        <para>
+            Additionally, setting the value sets the <code>checked</code>
+            property of the checkbox. You can query this using
+            <code>isChecked()</code> or simply accessing the property. Using the
+            <code>setChecked($flag)</code> method will both set the state of the
+            flag as well as set the appropriate checked or unchecked value in the
+            element. Please use this method when setting the checked state of a
+            checkbox element to ensure the value is set properly.
+        </para>
+
+        <para>
+            <code>Zend_Form_Element_Checkbox</code> uses the 'formCheckbox' view
+            helper. The checked value is always used to populate it.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.form.standardElements.file">
+        <title>Zend_Form_Element_File</title>
+
+        <para>
+            The File form element provides a mechanism for supplying file upload
+            fields to your form. It utilizes <link linkend="zend.file.transfer.introduction">Zend_File_Transfer</link>
+            internally to provide this functionality, and the
+            <code>FormFile</code> view helper as also the <code>File</code>
+            decorator to display the form element.
+        </para>
+
+        <para>
+            By default, it uses the <code>Http</code> transfer adapter, which
+            introspects the <code>$_FILES</code> array and allows you to attach
+            validators and filters. Validators and filters attached to the form
+            element will be attached to the transfer adapter.
+        </para>
+
+        <example id="zend.form.standardElements.file.usage">
+            <title>File form element usage</title>
+
+            <para>
+                The above explanation of using the File form element may seem
+                arcane, but actual usage is relatively trivial:
+            </para>
+
+            <programlisting role="php"><![CDATA[
+$element = new Zend_Form_Element_File('foo');
+$element->setLabel('Upload an image:')
+        ->setDestination('/var/www/upload');
+// ensure only 1 file
+$element->addValidator('Count', false, 1);
+// limit to 100K
+$element->addValidator('Size', false, 102400);
+// only JPEG, PNG, and GIFs
+$element->addValidator('Extension', false, 'jpg,png,gif');
+$form->addElement($element, 'foo');
+]]>
+            </programlisting>
+
+            <para>
+                También debe asegurarse de que se ha provisto un tipo de 
+                codificación corecto al formulario; se debe utilizar
+                'multipart/form-data'. Se puede hacer esto estableciendo el 
+                atributo 'enctype' en el formulario:
+            </para>
+
+            <programlisting role="php"><![CDATA[
+$form->setAttrib('enctype', 'multipart/form-data');
+]]>
+            </programlisting>
+
+            <para>
+                Cuando el atributo ha sido validado exitosamente, usted debe 
+                recibir el archivo para alamacenarlo en el destino final 
+                usando receive(). Adicionalmente puede determinar la 
+                ubicación final usando getFileName():
+            </para>
+
+            <programlisting role="php"><![CDATA[
+if (!$form->isValid) {
+    print "Ohoh... validation error";
+}
+
+if (!$form->foo->receive()) {
+    print "Error receiving the file";
+}
+
+$location = $form->foo->getFileName();
+]]>
+            </programlisting>
+
+        </example>
+
+        <note>
+            <title>Ubicaciones Predeterminadas para la Carga de Archivos</title>
+
+            <para>
+                Por defecto, los archivos son cargados al directorio temp del 
+                sistema.
+            </para>
+        </note>
+
+        <note>
+            <title>Valores de archivo</title>
+
+            <para>
+                Dentro de HTTP un elemento file no tiene valor. Por tanto y a 
+                causa de razones de seguridad usted solo obtendrá el nombre del
+                archivo cargado llamando  a getValue() y no el destino completo. 
+                si usted necesita la información completa  llame getFileName() y 
+                le retormará el destino y nombre de archivo completo.
+            </para>
+        </note>
+
+        <para>
+            <code>Zend_Form_Element_File</code> soporta también archivos
+            múltiples. Para llamar el método <code>setMultiFile($count)</code> 
+            usted puede establecer la cantidad de elementos file que usted desea 
+            crear. Esto le previene de establecer la misma configuración varias 
+            veces.
+        </para>
+
+        <example id="zend.form.standardElements.file.multiusage">
+            <title>Configuración de múltiples archivos</title>
+
+            <para>
+                Crear un elemento multi archivo es lo mismo que querer configurar
+                un elemento único. Sólo tiene que llamar a 
+                <code>setMultiFile()</code> adicionalmente después de la creación:
+            </para>
+
+            <programlisting role="php"><![CDATA[
+$element = new Zend_Form_Element_File('foo');
+$element->setLabel('Upload an image:')
+        ->setDestination('/var/www/upload');
+// asegura mínimo 1, maximo 3 archivos
+$element->addValidator('Count', false, array('min' => 1, 'max' => 3));
+// limita a 100K
+$element->addValidator('Size', false, 102400);
+// solo JPEG, PNG, y GIFs
+$element->addValidator('Extension', false, 'jpg,png,gif');
+// define 3 elementos file idénticos
+$element->setMultiFile(3);
+$form->addElement($element, 'foo');
+]]>
+            </programlisting>
+
+            <para>
+                En su vista usted ahora obtendrá 3 elementos para carga de 
+                archivos idénticos los cuales comparten la misma configuración.
+                para obtener  el conjunto de el número de archivos múltiples 
+                simplemente llame  <code>getMultiFile()</code>.
+            </para>
+
+        </example>
+
+        <note>
+            <title>Elementos File en Subformularioss</title>
+
+            <para>
+                Cuando usted use elementos file in subformularios debería 
+                establecer nombres únicos.
+                Así, cuando usted nombre su elemento file en el subformulario1, 
+                debe darle un nombre diferente el el subformulario2.
+            </para>
+
+            <para>
+                Tan pronto como haya dos elementos file nombrados de forma 
+                idéntica, el segundo elemento no se mostrará o enviará.
+            </para>
+        </note>
+
+        <para>
+            Para limitar el tamaño del archivo, el cual es cargado por el 
+            cliente, debe establecer el tamaño máximo de archivo que el 
+            formulario acepta . Esto limitará eñ tamaño del archivo en el lado 
+            del cliente configurando la opción <code>MAX_FILE_SIZE</code>
+            en el formulario. Tan pronto como establesca este valor usando 
+            el método <code>setMaxFileSize($size)</code>, estó será generado
+            con el elemento file.
+        </para>
+
+        <programlisting role="php"><![CDATA[
+$element = new Zend_Form_Element_File('foo');
+$element->setLabel('Upload an image:')
+        ->setDestination('/var/www/upload')
+        ->addValidator('Size', false, 102400) // límite en 100K
+        ->setMaxFileSize(102400); // limita el tamaño del archivo en el lado del cliente
+$form->addElement($element, 'foo');
+]]>
+        </programlisting>
+
+        <note>
+            <title>MaxFileSize con elementos file múltiples</title>
+
+            <para>
+                Cuando usted usa elementos file múltiples en los formularios tiene
+                que establecer el <code>MAX_FILE_SIZE</code> una sola vez.
+                 Establecerlo otra vez sobreescribirá el valor previamente 
+                 establecido.
+            </para>
+
+            <para>
+                Note, que usted puede establecer <code>MAX_FILE_SIZE</code> 
+                una sola ves, incluso si usas múltiples formularios.
+            </para>
+        </note>
+    </sect2>
+
+    <sect2 id="zend.form.standardElements.hidden">
+        <title>Zend_Form_Element_Hidden</title>
+
+        <para>
+            Los elementos Hidden simplemente injectan datos que deben ser 
+            enviados, pero que el usuario no debe manipular.
+            <code>Zend_Form_Element_Hidden</code> logra esto através del uso de
+            el helper de vista 'formHidden'.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.form.standardElements.hash">
+        <title>Zend_Form_Element_Hash</title>
+
+        <para>
+            Este elemento provee protección de ataques desde CSRF sobre 
+            formularios, asegurando que el dato es enviado por la sesión del
+            usuario que generó el formulario y no por un script pillero. 
+            La protección se logra mediante la adición de un elemento hash a             
+            un formulario y verificandolo cuando el formulario es enviado.
+        </para>
+
+        <para>
+            El nombre del elemnto hash debe ser único. Se recomienda usar la 
+            opción <literal>salt</literal> para el elemento, dos hashes con
+            el mismo nombre y diferentes salts no chocan:
+        </para>
+
+        <programlisting role="php"><![CDATA[
+$form->addElement('hash', 'no_csrf_foo', array('salt' => 'unique'));
+]]>
+        </programlisting>
+
+        <para>
+            Puede establecer el salt más tarde usando el método
+            <code>setSalt($salt)</code>.
+        </para>
+
+        <para>
+            Internamente, el elemento alamacena un identificador único usando
+            <code>Zend_Session_Namespace</code>, y lo comprueba en el momento
+            que se envía (comprueba que el TTL has no espiró). El validador 
+            'Identical' entonces es usado para asegurarse que el hash enviado
+            marcha con el hash alamacenado.
+        </para>
+
+        <para>
+            El helper de vista 'formHidden' es usado par generar el elemento 
+            en el formulario.
+            form.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.form.standardElements.Image">
+        <title>Zend_Form_Element_Image</title>
+
+        <para>
+            Las imáagenes pueden ser usadas como elmentos de formulario, y le
+            permite  especificar elementos gráficos como botones de formulario.
+        </para>
+
+        <para>
+            Los elementos Image necesitan una imagen fuente. 
+            <code>Zend_Form_Element_Image</code>  le permite especificar esto
+            usando el método de acceso <code>setImage()</code>
+            (o clave de configuración 'image'). Opcionalmente, también puede 
+            especificar un valor para utilizar al momento de enviar la imagen
+             utilizando  el método de acceso <code>setImageValue()</code> 
+            (o clave de configuración 'imageValue'). Cuando el valor establecido
+            para el elemento son similares al <code>imageValue</code>, entonces  
+            el método de acceso <code>isChecked()</code> devolverá true.
+        </para>
+
+        <para>
+            El elemento Image usa el 
+            <link linkend="zend.form.standardDecorators.image">Decorador de 
+            Imagen </link> para generar (así como el estandard Errors,
+            HtmlTag, y decorador Label). Opcionalmente, puede especificar una
+            etiqueta para el decorador <code>Image</code> que luego 
+            envuelva al elemento imagen.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.form.standardElements.multiCheckbox">
+        <title>Zend_Form_Element_MultiCheckbox</title>
+
+        <para>
+            A menudo tiene un conjunto de checkboxes, y desea agrupar los 
+            resultados. Esto es como un 
+            <link linkend="zend.form.standardElements.multiselect">Multiselect</link>,
+            pero en lugar de estar en una lista desplegable, necesita mostrarlos en pares checkbox/value (casilla de verificación/valor).
+        </para>
+
+        <para>
+            <code>Zend_Form_Element_MultiCheckbox</code> hace esto sencillo. Like
+            all other elements extending the base Multi element, you can specify
+            a list of options, and easily validate against that same list. The
+            'formMultiCheckbox' view helper ensures that these are returned as
+            an array in the form submission.
+        </para>
+
+        <para>
+            By default, this element registers an <code>InArray</code> validator
+            which validates against the array keys of registered options. You
+            can disable this behavior by either calling
+            <code>setRegisterInArrayValidator(false)</code>, or by passing a
+            false value to the <code>registerInArrayValidator</code>
+            configuration key.
+        </para>
+
+        <para>
+            You may manipulate the various checkbox options using the following
+            methods:
+        </para>
+
+        <itemizedlist>
+            <listitem><para><code>addMultiOption($option, $value)</code></para></listitem>
+
+            <listitem><para><code>addMultiOptions(array $options)</code></para></listitem>
+
+            <listitem><para><code>setMultiOptions(array $options)</code>
+                    (overwrites existing options)</para></listitem>
+
+            <listitem><para>getMultiOption($option)</para></listitem>
+
+            <listitem><para>getMultiOptions()</para></listitem>
+
+            <listitem><para><code>removeMultiOption($option)</code></para></listitem>
+
+            <listitem><para><code>clearMultiOptions()</code></para></listitem>
+        </itemizedlist>
+
+        <para>
+            To mark checked items, you need to pass an array of values to
+            <code>setValue()</code>. The following will check the values "bar"
+            and "bat":
+        </para>
+
+        <programlisting role="php"><![CDATA[
+$element = new Zend_Form_Element_MultiCheckbox('foo', array(
+    'multiOptions' => array(
+        'foo' => 'Foo Option',
+        'bar' => 'Bar Option',
+        'baz' => 'Baz Option',
+        'bat' => 'Bat Option',
+    );
+));
+
+$element->setValue(array('bar', 'bat'));
+]]>
+        </programlisting>
+
+        <para>
+            Note that even when setting a single value, you must pass an array.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.form.standardElements.multiselect">
+        <title>Zend_Form_Element_Multiselect</title>
+
+        <para>
+            XHTML <code>select</code> elements allow a 'multiple' attribute,
+            indicating multiple options may be selected for submission, instead
+            of the usual one. <code>Zend_Form_Element_Multiselect</code> extends
+            <link linkend="zend.form.standardElements.select">Zend_Form_Element_Select</link>,
+            and sets the <code>multiple</code> attribute to 'multiple'. Like
+            other classes that inherit from the base
+            <code>Zend_Form_Element_Multi</code> class, you can manipulate the
+            options for the select using:
+        </para>
+
+        <itemizedlist>
+            <listitem><para><code>addMultiOption($option, $value)</code></para></listitem>
+
+            <listitem><para><code>addMultiOptions(array $options)</code></para></listitem>
+
+            <listitem><para><code>setMultiOptions(array $options)</code>
+                    (overwrites existing options)</para></listitem>
+
+            <listitem><para>getMultiOption($option)</para></listitem>
+
+            <listitem><para>getMultiOptions()</para></listitem>
+
+            <listitem><para><code>removeMultiOption($option)</code></para></listitem>
+
+            <listitem><para><code>clearMultiOptions()</code></para></listitem>
+        </itemizedlist>
+
+        <para>
+            If a translation adapter is registered with the form and/or element,
+            option values will be translated for display purposes.
+        </para>
+
+        <para>
+            By default, this element registers an <code>InArray</code> validator
+            which validates against the array keys of registered options. You
+            can disable this behavior by either calling
+            <code>setRegisterInArrayValidator(false)</code>, or by passing a
+            false value to the <code>registerInArrayValidator</code>
+            configuration key.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.form.standardElements.password">
+        <title>Zend_Form_Element_Password</title>
+
+        <para>
+            Password elements are basically normal text elements -- except that
+            you typically do not want the submitted password displayed in error
+            messages or the element itself when the form is re-displayed.
+        </para>
+
+        <para>
+            <code>Zend_Form_Element_Password</code> achieves this by calling
+            <code>setObscureValue(true)</code> on each validator (ensuring that
+            the password is obscured in validation error messages), and using
+            the 'formPassword' view helper (which does not display the value
+            passed to it).
+        </para>
+    </sect2>
+
+    <sect2 id="zend.form.standardElements.radio">
+        <title>Zend_Form_Element_Radio</title>
+
+        <para>
+            Radio elements allow you to specify several options, of which you
+            need a single value returned. <code>Zend_Form_Element_Radio</code>
+            extends the base <code>Zend_Form_Element_Multi</code> class,
+            allowing you to specify a number of options, and then uses the
+            <code>formRadio</code> view helper to display these.
+        </para>
+
+        <para>
+            By default, this element registers an <code>InArray</code> validator
+            which validates against the array keys of registered options. You
+            can disable this behavior by either calling
+            <code>setRegisterInArrayValidator(false)</code>, or by passing a
+            false value to the <code>registerInArrayValidator</code>
+            configuration key.
+        </para>
+
+        <para>
+            Like all elements extending the Multi element base class, the
+            following methods may be used to manipulate the radio options
+            displayed:
+        </para>
+
+        <itemizedlist>
+            <listitem><para><code>addMultiOption($option, $value)</code></para></listitem>
+
+            <listitem><para><code>addMultiOptions(array $options)</code></para></listitem>
+
+            <listitem><para><code>setMultiOptions(array $options)</code>
+                    (overwrites existing options)</para></listitem>
+
+            <listitem><para>getMultiOption($option)</para></listitem>
+
+            <listitem><para>getMultiOptions()</para></listitem>
+
+            <listitem><para><code>removeMultiOption($option)</code></para></listitem>
+
+            <listitem><para><code>clearMultiOptions()</code></para></listitem>
+        </itemizedlist>
+    </sect2>
+
+    <sect2 id="zend.form.standardElements.reset">
+        <title>Zend_Form_Element_Reset</title>
+
+        <para>
+            Reset buttons are typically used to clear a form, and are not part
+            of submitted data. However, as they serve a purpose in the display,
+            they are included in the standard elements.
+        </para>
+
+        <para>
+            <code>Zend_Form_Element_Reset</code> extends <link linkend="zend.form.standardElements.submit">Zend_Form_Element_Submit</link>.
+            As such, the label is used for the button display, and will be
+            translated if a translation adapter is present. It utilizes only the
+            'ViewHelper' and 'DtDdWrapper' decorators, as there should never be
+            error messages for such elements, nor will a label be necessary.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.form.standardElements.select">
+        <title>Zend_Form_Element_Select</title>
+
+        <para>
+            Select boxes are a common way of limiting to specific choices for a
+            given form datum. <code>Zend_Form_Element_Select</code> allows you
+            to generate these quickly and easily.
+        </para>
+
+        <para>
+            By default, this element registers an <code>InArray</code> validator
+            which validates against the array keys of registered options. You
+            can disable this behavior by either calling
+            <code>setRegisterInArrayValidator(false)</code>, or by passing a
+            false value to the <code>registerInArrayValidator</code>
+            configuration key.
+        </para>
+
+        <para>
+            As it extends the base Multi element, the following methods may be
+            used to manipulate the select options:
+        </para>
+
+        <itemizedlist>
+            <listitem><para><code>addMultiOption($option, $value)</code></para></listitem>
+
+            <listitem><para><code>addMultiOptions(array $options)</code></para></listitem>
+
+            <listitem><para><code>setMultiOptions(array $options)</code>
+                    (overwrites existing options)</para></listitem>
+
+            <listitem><para>getMultiOption($option)</para></listitem>
+
+            <listitem><para>getMultiOptions()</para></listitem>
+
+            <listitem><para><code>removeMultiOption($option)</code></para></listitem>
+
+            <listitem><para><code>clearMultiOptions()</code></para></listitem>
+        </itemizedlist>
+
+        <para>
+            <code>Zend_Form_Element_Select</code> uses the 'formSelect' view
+            helper for decoration.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.form.standardElements.submit">
+        <title>Zend_Form_Element_Submit</title>
+
+        <para>
+            Submit buttons are used to submit a form. You may use multiple
+            submit buttons; you can use the button used to submit the form to
+            decide what action to take with the data submitted.
+            <code>Zend_Form_Element_Submit</code> makes this decisioning easy,
+            by adding a <code>isChecked()</code> method; as only one button
+            element will be submitted by the form, after populating or
+            validating the form, you can call this method on each submit button
+            to determine which one was used.
+        </para>
+
+        <para>
+            <code>Zend_Form_Element_Submit</code> uses the label as the "value"
+            of the submit button, translating it if a translation adapter is
+            present. <code>isChecked()</code> checks the submitted value against
+            the label in order to determine if the button was used.
+        </para>
+
+        <para>
+            The <link linkend="zend.form.standardDecorators.viewHelper">ViewHelper</link>
+            and <link linkend="zend.form.standardDecorators.dtDdWrapper">DtDdWrapper</link>
+            decorators to render the element. No label decorator is used, as the
+            button label is used when rendering the element; also, typically,
+            you will not associate errors with a submit element.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.form.standardElements.text">
+        <title>Zend_Form_Element_Text</title>
+
+        <para>
+            By far the most prevalent type of form element is the text element,
+            allowing for limited text entry; it's an ideal element for most data
+            entry. <code>Zend_Form_Element_Text</code> simply uses the
+            'formText' view helper to display the element.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.form.standardElements.textarea">
+        <title>Zend_Form_Element_Textarea</title>
+
+        <para>
+            Textareas are used when large quantities of text are expected, and
+            place no limits on the amount of text submitted (other than maximum
+            size limits as dictated by your server or PHP).
+            <code>Zend_Form_Element_Textarea</code> uses the 'textArea' view
+            helper to display such elements, placing the value as the content of
+            the element.
+        </para>
+    </sect2>
+</sect1>
+<!--
+vim:se ts=4 sw=4 tw=80 et:
+-->

+ 554 - 554
documentation/manual/es/module_specs/Zend_XmlRpc_Client.xml

@@ -1,554 +1,554 @@
-<sect1 id="zend.xmlrpc.client">
-    <title>Zend_XmlRpc_Client</title>
-
-    <sect2 id="zend.xmlrpc.client.introduction">
-        <title>Introdución</title>
-
-        <para>
-            Zend Framework provee soporte para consumo remoto para servicios XML-RPC
-            como un cliente en el paquete <code>Zend_XmlRpc_Client</code>
-            . Su mejor característica es la conversión atuomática de tipos 
-            entre PHP y XML-RPC, un servidor de objeto proxy, y acceso a 
-            capacidades de instrospección del servidor.
-        </para>
-
-    </sect2>
-
-
-    <sect2 id="zend.xmlrpc.client.method-calls">
-        <title>Method Calls</title>
-
-        <para>
-            El constructor de <code>Zend_XmlRpc_Client</code> recibe la 
-            URL del servidor XML-RPC como su primer parámetro.
-            La nueva instacia devuelta pu7ede ser usada para llamar cualquier número de métodos remotos en el punto final.
-        </para>
-
-        <para>
-            Para llamar un método remoto con el cliente XML-RPC, instáncealo 
-            y usa el método de instancia <code>call()</code> . El código de ejemplo a continuación utiliza una demostración en el servidor XML-RPC en el sitio wed del Zend Framework
-            . Puede utilizarlo para probar o explorar los componentes 
-            <code>Zend_XmlRpc</code>.
-        </para>
-
-        <example id="zend.xmlrpc.client.method-calls.example-1">
-            <title>XML-RPC Method Call</title>
-            <programlisting role="php"><![CDATA[
-$client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
-
-echo $client->call('test.sayHello');
-
-// hello
-]]>
-            </programlisting>
-        </example>
-
-        <para>
-            El valor XML-RPC devuelto desde la llamada al método remoto automáticamente será convertida al tipo nativo PHP equivalente            
-
-            . En el ejemplo anterior, es devuelto un <code>string</code> PHP 
-            y está listo para ser usada inmediatamente.
-        </para>
-
-        <para>
-            El primer parámetro del método <code>call()</code> recibe el nombre del método remoto a llamar. Si el método remoto requiere algún parámetro, este puede ser enviado por el suministro de un segundo, parámetro opcional a <code>call()</code> con un <code>array</code> de
-            valores para pasar el método remoto:
-        </para>
-
-        <example id="zend.xmlrpc.client.method-calls.example-2">
-            <title>XML-RPC Method Call with Parameters</title>
-            <programlisting role="php"><![CDATA[
-$client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
-
-$arg1 = 1.1;
-$arg2 = 'foo';
-
-$result = $client->call('test.sayHello', array($arg1, $arg2));
-
-// $result es un tipo nativo PHP 
-]]>
-            </programlisting>
-        </example>
-
-        <para>
-            si el método remoto no requiere parámetros,  este parámetro opcional 
-            podrá ser excluido o se puede pasar un <code>array()</code>
-            vacío. El array de parámeters para el método repoto puede contener tipos nativos PHPs, objetos <code>Zend_XmlRpc_Value</code>
-            , o una combinación de estos.
-        </para>
-
-        <para>
-            El método <code>call()</code> convertirá automáticamente la respuesta
-            XML-RPC y devolverá su tipo nativo PHP equivalente. Un objeto
-            <code>Zend_XmlRpc_Response</code> para el valor devuelto también estará
-            disponible para llamar el método <code>getLastResponse()</code>
-            después de la llamada.
-        </para>
-    </sect2>
-
-    <sect2 id="zend.xmlrpc.value.parameters">
-        <title>Tipos y Conversiones</title>
-        <para>
-            Algunas llamadas a métodos remoto requieren parámetros.  Estos son 
-           dados al método <code>call()</code> de <code>Zend_XmlRpc_Client</code>
-            como un array en el segundo parámetro.  Cada parámetro puede ser dado
-            como cualquier tipo nativo PHP ya que este será convertido automáticamente,
-            o como un  objeto que representa un tipo específico de XML-RPC 
-            (uno de los objetos  <code>Zend_XmlRpc_Value</code>).
-        </para>
-
-        <sect3 id="zend.xmlrpc.value.parameters.php-native">
-            <title>Tipos Nativos PHP como Parámetro</title>
-            <para>
-                Los parámetros pueden ser pasados a <code>call()</code> como variables 
-                PHP nativas, ya sea un <code>string</code>,
-                <code>integer</code>, <code>float</code>,
-                <code>boolean</code>, <code>array</code>, o un
-                <code>object</code>. En este caso, cada tipo PHP nativo será
-                autodetectada y convertida en uno de los tipos XML-RPC 
-                de acuerdo con esta tabla:
-            </para>
-
-            <table id="zend.xmlrpc.value.parameters.php-native.table-1">
-                <title>Tipos de Conversión entre PHP y XML-RPC</title>
-                <tgroup cols="2">
-                    <thead>
-                        <row>
-                            <entry>Tipo Nativo PHP</entry>
-                            <entry>Tipo XML-RPC</entry>
-                        </row>
-                    </thead>
-                    <tbody>
-                        <row>
-                            <entry>integer</entry>
-                            <entry>int</entry>
-                        </row>
-                        <row>
-                            <entry>double</entry>
-                            <entry>double</entry>
-                        </row>
-                        <row>
-                            <entry>boolean</entry>
-                            <entry>boolean</entry>
-                        </row>
-                        <row>
-                            <entry>string</entry>
-                            <entry>string</entry>
-                        </row>
-                        <row>
-                            <entry>array</entry>
-                            <entry>array</entry>
-                        </row>
-                        <row>
-                            <entry>array asociativo</entry>
-                            <entry>struct</entry>
-                        </row>
-                        <row>
-                            <entry>object</entry>
-                            <entry>array</entry>
-                        </row>
-                    </tbody>
-                </tgroup>
-            </table>
-
-            <note>
-                <title>¿A qué tipo se convierten los arrays Vacios?</title>
-
-                <para>
-                    Pasar un array vacío a un método XML-RPC es problemático,
-                    as it could represent either an array or a struct.
-                    <code>Zend_XmlRpc_Client</code> detects such conditions and
-                    makes a request to the server's
-                    <code>system.methodSignature</code> method to determine the
-                    appropriate XML-RPC type to cast to.
-                </para>
-
-                <para>
-                    However, this in itself can lead to issues. First off,
-                    servers that do not support
-                    <code>system.methodSignature</code> will log failed
-                    requests, and <code>Zend_XmlRpc_Client</code> will resort to
-                    casting the value to an XML-RPC array type. Additionally,
-                    this means that any call with array arguments will result in
-                    an additional call to the remote server.
-                </para>
-
-                <para>
-                    To disable the lookup entirely, you can call the
-                    <code>setSkipSystemLookup()</code> method prior to making
-                    your XML-RPC call:
-                </para>
-
-                <programlisting role="php"><![CDATA[
-$client->setSkipSystemLookup(true);
-$result = $client->call('foo.bar', array(array()));
-]]>
-                </programlisting>
-            </note>
-        </sect3>
-
-        <sect3 id="zend.xmlrpc.value.parameters.xmlrpc-value">
-            <title><code>Zend_XmlRpc_Value</code> Objects as Parameters</title>
-            <para>
-                Parameters may also be created as <code>Zend_XmlRpc_Value</code>
-                instances to specify an exact XML-RPC type.  The primary reasons
-                for doing this are:
-
-                <itemizedlist>
-                    <listitem>
-                        <para>
-                            When you want to make sure the correct parameter
-                            type is passed to the procedure (i.e. the
-                            procedure requires an integer and you may get it
-                            from a database as a string)
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-                            When the procedure requires <code>base64</code> or
-                            <code>dateTime.iso8601</code> type (which doesn't exists as a
-                            PHP native type)
-                        </para>
-                    </listitem>
-                    <listitem>
-                        <para>
-                            When auto-conversion may fail (i.e. you want to
-                            pass an empty XML-RPC struct as a parameter. Empty
-                            structs are represented as empty arrays in PHP
-                            but, if you give an empty array as a parameter it
-                            will be auto-converted to an XML-RPC array since
-                            it's not an associative array)
-                        </para>
-                    </listitem>
-                </itemizedlist>
-            </para>
-
-            <para>
-                There are two ways to create a <code>Zend_XmlRpc_Value</code>
-                object: instantiate one of the <code>Zend_XmlRpc_Value</code>
-                subclasses directly, or use the static factory method
-                <code>Zend_XmlRpc_Value::getXmlRpcValue()</code>.
-            </para>
-
-            <table id="zend.xmlrpc.value.parameters.xmlrpc-value.table-1">
-                <title><code>Zend_XmlRpc_Value</code> Objects for XML-RPC Types</title>
-                <tgroup cols="3">
-                    <thead>
-                        <row>
-                            <entry>XML-RPC Type</entry>
-                            <entry><code>Zend_XmlRpc_Value</code> Constant</entry>
-                            <entry><code>Zend_XmlRpc_Value</code> Object</entry>
-                        </row>
-                    </thead>
-                    <tbody>
-                        <row>
-                            <entry>int</entry>
-                            <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_INTEGER</code></entry>
-                            <entry><code>Zend_XmlRpc_Value_Integer</code></entry>
-                        </row>
-                        <row>
-                            <entry>double</entry>
-                            <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_DOUBLE</code></entry>
-                            <entry><code>Zend_XmlRpc_Value_Double</code></entry>
-                        </row>
-                        <row>
-                            <entry>boolean</entry>
-                            <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_BOOLEAN</code></entry>
-                            <entry><code>Zend_XmlRpc_Value_Boolean</code></entry>
-                        </row>
-                        <row>
-                            <entry>string</entry>
-                            <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_STRING</code></entry>
-                            <entry><code>Zend_XmlRpc_Value_String</code></entry>
-                        </row>
-                        <row>
-                            <entry>base64</entry>
-                            <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_BASE64</code></entry>
-                            <entry><code>Zend_XmlRpc_Value_Base64</code></entry>
-                        </row>
-                        <row>
-                            <entry>dateTime.iso8601</entry>
-                            <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_DATETIME</code></entry>
-                            <entry><code>Zend_XmlRpc_Value_DateTime</code></entry>
-                        </row>
-                        <row>
-                            <entry>array</entry>
-                            <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_ARRAY</code></entry>
-                            <entry><code>Zend_XmlRpc_Value_Array</code></entry>
-                        </row>
-                        <row>
-                            <entry>struct</entry>
-                            <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_STRUCT</code></entry>
-                            <entry><code>Zend_XmlRpc_Value_Struct</code></entry>
-                        </row>
-                    </tbody>
-                </tgroup>
-            </table>
-
-            <para>
-                <note>
-                    <title>Automatic Conversion</title>
-                    <para>
-                        When building a new <code>Zend_XmlRpc_Value</code>
-                        object, its value is set by a PHP type. The PHP type
-                        will be converted to the specified type using
-                        PHP casting. For example, if a string is given as a
-                        value to the <code>Zend_XmlRpc_Value_Integer</code>
-                        object, it will be converted using
-                        <code>(int)$value</code>.
-                    </para>
-                </note>
-            </para>
-        </sect3>
-    </sect2>
-
-    <sect2 id="zend.xmlrpc.client.requests-and-responses">
-        <title>Server Proxy Object</title>
-        <para>
-            Another way to call remote methods with the XML-RPC client is to
-            use the server proxy.  This is a PHP object that proxies a remote
-            XML-RPC namespace, making it work as close to a native PHP object
-            as possible.
-        </para>
-
-        <para>
-            To instantiate a server proxy, call the <code>getProxy()</code>
-            instance method of <code>Zend_XmlRpc_Client</code>. This will
-            return an instance of <code>Zend_XmlRpc_Client_ServerProxy</code>.
-            Any method call on the server proxy object will be forwarded to
-            the remote, and parameters may be passed like any other PHP
-            method.
-        </para>
-
-        <example id="zend.xmlrpc.client.requests-and-responses.example-1">
-            <title>Proxy the Default Namespace</title>
-            <programlisting role="php"><![CDATA[
-$client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
-
-$server = $client->getProxy();           // Proxy the default namespace
-
-$hello = $server->test->sayHello(1, 2);  // test.Hello(1, 2) returns "hello"
-]]>
-            </programlisting>
-        </example>
-
-        <para>
-            The <code>getProxy()</code> method receives an optional argument
-            specifying which namespace of the remote server to proxy. If it
-            does not receive a namespace, the default namespace will be
-            proxied.  In the next example, the <code>test</code> namespace
-            will be proxied:
-        </para>
-
-        <example id="zend.xmlrpc.client.requests-and-responses.example-2">
-            <title>Proxy Any Namespace</title>
-            <programlisting role="php"><![CDATA[
-$client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
-
-$test  = $client->getProxy('test');     // Proxy the "test" namespace
-
-$hello = $test->sayHello(1, 2);         // test.Hello(1,2) returns "hello"
-]]>
-            </programlisting>
-        </example>
-
-        <para>
-            If the remote server supports nested namespaces of any depth,
-            these can also be used through the server proxy. For example, if
-            the server in the example above had a method
-            <code>test.foo.bar()</code>, it could be called as
-            <code>$test-&gt;foo-&gt;bar()</code>.
-        </para>
-    </sect2>
-
-
-    <sect2 id="zend.xmlrpc.client.error-handling">
-        <title>Error Handling</title>
-        <para>
-            Two kinds of errors can occur during an XML-RPC method call: HTTP
-            errors and XML-RPC faults. The <code>Zend_XmlRpc_Client</code>
-            recognizes each and provides the ability to detect and trap them
-            independently.
-        </para>
-
-        <sect3 id="zend.xmlrpc.client.error-handling.http">
-            <title>HTTP Errors</title>
-
-            <para>
-                If any HTTP error occurs, such as the remote HTTP server
-                returns a <code>404 Not Found</code>, a
-                <code>Zend_XmlRpc_Client_HttpException</code> will be thrown.
-            </para>
-
-            <example id="zend.xmlrpc.client.error-handling.http.example-1">
-                <title>Handling HTTP Errors</title>
-
-                <programlisting role="php"><![CDATA[
-$client = new Zend_XmlRpc_Client('http://foo/404');
-
-try {
-
-    $client->call('bar', array($arg1, $arg2));
-
-} catch (Zend_XmlRpc_Client_HttpException $e) {
-
-    // $e->getCode() returns 404
-    // $e->getMessage() returns "Not Found"
-
-}
-]]>
-                </programlisting>
-            </example>
-
-            <para>
-                Regardless of how the XML-RPC client is used, the
-                <code>Zend_XmlRpc_Client_HttpException</code> will be thrown
-                whenever an HTTP error occurs.
-            </para>
-        </sect3>
-
-        <sect3 id="zend.xmlrpc.client.error-handling.faults">
-            <title>XML-RPC Faults</title>
-
-            <para>
-                An XML-RPC fault is analogous to a PHP exception. It is a
-                special type returned from an XML-RPC method call that has
-                both an error code and an error message. XML-RPC faults are
-                handled differently depending on the context of how the
-                <code>Zend_XmlRpc_Client</code> is used.
-            </para>
-
-            <para>
-                When the <code>call()</code> method or the server
-                proxy object is used, an XML-RPC fault will result in a
-                <code>Zend_XmlRpc_Client_FaultException</code> being thrown.
-                The code and message of the exception will map directly to
-                their respective values in the original XML-RPC fault
-                response.
-            </para>
-
-            <example id="zend.xmlrpc.client.error-handling.faults.example-1">
-                <title>Handling XML-RPC Faults</title>
-
-                <programlisting role="php"><![CDATA[
-$client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
-
-try {
-
-    $client->call('badMethod');
-
-} catch (Zend_XmlRpc_Client_FaultException $e) {
-
-    // $e->getCode() returns 1
-    // $e->getMessage() returns "Unknown method"
-
-}
-]]>
-                </programlisting>
-            </example>
-
-            <para>
-                When the <code>call()</code> method is used to make the
-                request, the <code>Zend_XmlRpc_Client_FaultException</code> will be
-                thrown on fault. A <code>Zend_XmlRpc_Response</code> object
-                containing the fault will also be available by calling
-                <code>getLastResponse()</code>.
-            </para>
-
-            <para>
-                When the <code>doRequest()</code> method is used to make the
-                request, it will not throw the exception. Instead, it will
-                return a <code>Zend_XmlRpc_Response</code> object returned
-                will containing the fault. This can be checked with
-                <code>isFault()</code> instance method of
-                <code>Zend_XmlRpc_Response</code>.
-            </para>
-        </sect3>
-
-    </sect2>
-
-    <sect2 id="zend.xmlrpc.client.introspection">
-        <title>Server Introspection</title>
-        <para>
-            Some XML-RPC servers support the de facto introspection methods under the XML-RPC
-            <code>system.</code> namespace.  <code>Zend_XmlRpc_Client</code> provides special
-            support for servers with these capabilities.
-        </para>
-
-        <para>
-            A <code>Zend_XmlRpc_Client_ServerIntrospection</code> instance may be retrieved by calling
-            the <code>getIntrospector()</code> method of <code>Zend_XmlRpcClient</code>.  It can
-            then be used to perform introspection operations on the server.
-        </para>
-    </sect2>
-
-    <sect2 id="zend.xmlrpc.client.request-to-response">
-        <title>From Request to Response</title>
-        <para>
-            Under the hood, the <code>call()</code> instance method of <code>Zend_XmlRpc_Client</code>
-            builds a request object (<code>Zend_XmlRpc_Request</code>) and sends it to another method,
-            <code>doRequest()</code>, that returns a response object (<code>Zend_XmlRpc_Response</code>).
-        </para>
-
-        <para>
-            The <code>doRequest()</code> method is also available for use directly:
-        </para>
-
-        <example id="zend.xmlrpc.client.request-to-response.example-1">
-            <title>Processing Request to Response</title>
-
-            <programlisting role="php"><![CDATA[
-$client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
-
-$request = new Zend_XmlRpc_Request();
-$request->setMethod('test.sayHello');
-$request->setParams(array('foo', 'bar'));
-
-$client->doRequest($request);
-
-// $server->getLastRequest() returns instanceof Zend_XmlRpc_Request
-// $server->getLastResponse() returns instanceof Zend_XmlRpc_Response
-]]>
-            </programlisting>
-        </example>
-
-        <para>
-            Whenever an XML-RPC method call is made by the client through any
-            means, either the <code>call()</code> method,
-            <code>doRequest()</code> method, or server proxy, the last request
-            object and its resultant response object will always be available
-            through the methods <code>getLastRequest()</code> and
-            <code>getLastResponse()</code> respectively.
-        </para>
-    </sect2>
-
-    <sect2 id="zend.xmlrpc.client.http-client">
-        <title>HTTP Client and Testing</title>
-
-        <para>
-            In all of the prior examples, an HTTP client was never specified.
-            When this is the case, a new instance of
-            <code>Zend_Http_Client</code> will be created with its default
-            options and used by <code>Zend_XmlRpc_Client</code> automatically.
-        </para>
-
-        <para>
-            The HTTP client can be retrieved at any time with the
-            <code>getHttpClient()</code> method. For most cases, the default
-            HTTP client will be sufficient. However, the
-            <code>setHttpClient()</code> method allows for a different HTTP
-            client instance to be injected.
-        </para>
-
-        <para>
-            The <code>setHttpClient()</code> is particularly useful for unit testing.  When combined
-            with the <code>Zend_Http_Client_Adapter_Test</code>, remote services can be mocked
-            out for testing.  See the unit tests for <code>Zend_XmlRpc_Client</code> for examples
-            of how to do this.
-        </para>
-    </sect2>
-
-</sect1>
-<!--
-vim:se ts=4 sw=4 et:
--->
+<sect1 id="zend.xmlrpc.client">
+    <title>Zend_XmlRpc_Client</title>
+
+    <sect2 id="zend.xmlrpc.client.introduction">
+        <title>Introdución</title>
+
+        <para>
+            Zend Framework provee soporte para consumo remoto para servicios XML-RPC
+            como un cliente en el paquete <code>Zend_XmlRpc_Client</code>
+            . Su mejor característica es la conversión atuomática de tipos 
+            entre PHP y XML-RPC, un servidor de objeto proxy, y acceso a 
+            capacidades de instrospección del servidor.
+        </para>
+
+    </sect2>
+
+
+    <sect2 id="zend.xmlrpc.client.method-calls">
+        <title>Method Calls</title>
+
+        <para>
+            El constructor de <code>Zend_XmlRpc_Client</code> recibe la 
+            URL del servidor XML-RPC como su primer parámetro.
+            La nueva instacia devuelta pu7ede ser usada para llamar cualquier número de métodos remotos en el punto final.
+        </para>
+
+        <para>
+            Para llamar un método remoto con el cliente XML-RPC, instáncealo 
+            y usa el método de instancia <code>call()</code> . El código de ejemplo a continuación utiliza una demostración en el servidor XML-RPC en el sitio wed del Zend Framework
+            . Puede utilizarlo para probar o explorar los componentes 
+            <code>Zend_XmlRpc</code>.
+        </para>
+
+        <example id="zend.xmlrpc.client.method-calls.example-1">
+            <title>XML-RPC Method Call</title>
+            <programlisting role="php"><![CDATA[
+$client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
+
+echo $client->call('test.sayHello');
+
+// hello
+]]>
+            </programlisting>
+        </example>
+
+        <para>
+            El valor XML-RPC devuelto desde la llamada al método remoto automáticamente será convertida al tipo nativo PHP equivalente            
+
+            . En el ejemplo anterior, es devuelto un <code>string</code> PHP 
+            y está listo para ser usada inmediatamente.
+        </para>
+
+        <para>
+            El primer parámetro del método <code>call()</code> recibe el nombre del método remoto a llamar. Si el método remoto requiere algún parámetro, este puede ser enviado por el suministro de un segundo, parámetro opcional a <code>call()</code> con un <code>array</code> de
+            valores para pasar el método remoto:
+        </para>
+
+        <example id="zend.xmlrpc.client.method-calls.example-2">
+            <title>XML-RPC Method Call with Parameters</title>
+            <programlisting role="php"><![CDATA[
+$client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
+
+$arg1 = 1.1;
+$arg2 = 'foo';
+
+$result = $client->call('test.sayHello', array($arg1, $arg2));
+
+// $result es un tipo nativo PHP 
+]]>
+            </programlisting>
+        </example>
+
+        <para>
+            si el método remoto no requiere parámetros,  este parámetro opcional 
+            podrá ser excluido o se puede pasar un <code>array()</code>
+            vacío. El array de parámeters para el método repoto puede contener tipos nativos PHPs, objetos <code>Zend_XmlRpc_Value</code>
+            , o una combinación de estos.
+        </para>
+
+        <para>
+            El método <code>call()</code> convertirá automáticamente la respuesta
+            XML-RPC y devolverá su tipo nativo PHP equivalente. Un objeto
+            <code>Zend_XmlRpc_Response</code> para el valor devuelto también estará
+            disponible para llamar el método <code>getLastResponse()</code>
+            después de la llamada.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.xmlrpc.value.parameters">
+        <title>Tipos y Conversiones</title>
+        <para>
+            Algunas llamadas a métodos remoto requieren parámetros.  Estos son 
+           dados al método <code>call()</code> de <code>Zend_XmlRpc_Client</code>
+            como un array en el segundo parámetro.  Cada parámetro puede ser dado
+            como cualquier tipo nativo PHP ya que este será convertido automáticamente,
+            o como un  objeto que representa un tipo específico de XML-RPC 
+            (uno de los objetos  <code>Zend_XmlRpc_Value</code>).
+        </para>
+
+        <sect3 id="zend.xmlrpc.value.parameters.php-native">
+            <title>Tipos Nativos PHP como Parámetro</title>
+            <para>
+                Los parámetros pueden ser pasados a <code>call()</code> como variables 
+                PHP nativas, ya sea un <code>string</code>,
+                <code>integer</code>, <code>float</code>,
+                <code>boolean</code>, <code>array</code>, o un
+                <code>object</code>. En este caso, cada tipo PHP nativo será
+                autodetectada y convertida en uno de los tipos XML-RPC 
+                de acuerdo con esta tabla:
+            </para>
+
+            <table id="zend.xmlrpc.value.parameters.php-native.table-1">
+                <title>Tipos de Conversión entre PHP y XML-RPC</title>
+                <tgroup cols="2">
+                    <thead>
+                        <row>
+                            <entry>Tipo Nativo PHP</entry>
+                            <entry>Tipo XML-RPC</entry>
+                        </row>
+                    </thead>
+                    <tbody>
+                        <row>
+                            <entry>integer</entry>
+                            <entry>int</entry>
+                        </row>
+                        <row>
+                            <entry>double</entry>
+                            <entry>double</entry>
+                        </row>
+                        <row>
+                            <entry>boolean</entry>
+                            <entry>boolean</entry>
+                        </row>
+                        <row>
+                            <entry>string</entry>
+                            <entry>string</entry>
+                        </row>
+                        <row>
+                            <entry>array</entry>
+                            <entry>array</entry>
+                        </row>
+                        <row>
+                            <entry>array asociativo</entry>
+                            <entry>struct</entry>
+                        </row>
+                        <row>
+                            <entry>object</entry>
+                            <entry>array</entry>
+                        </row>
+                    </tbody>
+                </tgroup>
+            </table>
+
+            <note>
+                <title>¿A qué tipo se convierten los arrays Vacios?</title>
+
+                <para>
+                    Pasar un array vacío a un método XML-RPC es problemático,
+                    as it could represent either an array or a struct.
+                    <code>Zend_XmlRpc_Client</code> detects such conditions and
+                    makes a request to the server's
+                    <code>system.methodSignature</code> method to determine the
+                    appropriate XML-RPC type to cast to.
+                </para>
+
+                <para>
+                    However, this in itself can lead to issues. First off,
+                    servers that do not support
+                    <code>system.methodSignature</code> will log failed
+                    requests, and <code>Zend_XmlRpc_Client</code> will resort to
+                    casting the value to an XML-RPC array type. Additionally,
+                    this means that any call with array arguments will result in
+                    an additional call to the remote server.
+                </para>
+
+                <para>
+                    To disable the lookup entirely, you can call the
+                    <code>setSkipSystemLookup()</code> method prior to making
+                    your XML-RPC call:
+                </para>
+
+                <programlisting role="php"><![CDATA[
+$client->setSkipSystemLookup(true);
+$result = $client->call('foo.bar', array(array()));
+]]>
+                </programlisting>
+            </note>
+        </sect3>
+
+        <sect3 id="zend.xmlrpc.value.parameters.xmlrpc-value">
+            <title><code>Zend_XmlRpc_Value</code> Objects as Parameters</title>
+            <para>
+                Parameters may also be created as <code>Zend_XmlRpc_Value</code>
+                instances to specify an exact XML-RPC type.  The primary reasons
+                for doing this are:
+
+                <itemizedlist>
+                    <listitem>
+                        <para>
+                            When you want to make sure the correct parameter
+                            type is passed to the procedure (i.e. the
+                            procedure requires an integer and you may get it
+                            from a database as a string)
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+                            When the procedure requires <code>base64</code> or
+                            <code>dateTime.iso8601</code> type (which doesn't exists as a
+                            PHP native type)
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+                            When auto-conversion may fail (i.e. you want to
+                            pass an empty XML-RPC struct as a parameter. Empty
+                            structs are represented as empty arrays in PHP
+                            but, if you give an empty array as a parameter it
+                            will be auto-converted to an XML-RPC array since
+                            it's not an associative array)
+                        </para>
+                    </listitem>
+                </itemizedlist>
+            </para>
+
+            <para>
+                There are two ways to create a <code>Zend_XmlRpc_Value</code>
+                object: instantiate one of the <code>Zend_XmlRpc_Value</code>
+                subclasses directly, or use the static factory method
+                <code>Zend_XmlRpc_Value::getXmlRpcValue()</code>.
+            </para>
+
+            <table id="zend.xmlrpc.value.parameters.xmlrpc-value.table-1">
+                <title><code>Zend_XmlRpc_Value</code> Objects for XML-RPC Types</title>
+                <tgroup cols="3">
+                    <thead>
+                        <row>
+                            <entry>XML-RPC Type</entry>
+                            <entry><code>Zend_XmlRpc_Value</code> Constant</entry>
+                            <entry><code>Zend_XmlRpc_Value</code> Object</entry>
+                        </row>
+                    </thead>
+                    <tbody>
+                        <row>
+                            <entry>int</entry>
+                            <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_INTEGER</code></entry>
+                            <entry><code>Zend_XmlRpc_Value_Integer</code></entry>
+                        </row>
+                        <row>
+                            <entry>double</entry>
+                            <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_DOUBLE</code></entry>
+                            <entry><code>Zend_XmlRpc_Value_Double</code></entry>
+                        </row>
+                        <row>
+                            <entry>boolean</entry>
+                            <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_BOOLEAN</code></entry>
+                            <entry><code>Zend_XmlRpc_Value_Boolean</code></entry>
+                        </row>
+                        <row>
+                            <entry>string</entry>
+                            <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_STRING</code></entry>
+                            <entry><code>Zend_XmlRpc_Value_String</code></entry>
+                        </row>
+                        <row>
+                            <entry>base64</entry>
+                            <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_BASE64</code></entry>
+                            <entry><code>Zend_XmlRpc_Value_Base64</code></entry>
+                        </row>
+                        <row>
+                            <entry>dateTime.iso8601</entry>
+                            <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_DATETIME</code></entry>
+                            <entry><code>Zend_XmlRpc_Value_DateTime</code></entry>
+                        </row>
+                        <row>
+                            <entry>array</entry>
+                            <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_ARRAY</code></entry>
+                            <entry><code>Zend_XmlRpc_Value_Array</code></entry>
+                        </row>
+                        <row>
+                            <entry>struct</entry>
+                            <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_STRUCT</code></entry>
+                            <entry><code>Zend_XmlRpc_Value_Struct</code></entry>
+                        </row>
+                    </tbody>
+                </tgroup>
+            </table>
+
+            <para>
+                <note>
+                    <title>Automatic Conversion</title>
+                    <para>
+                        When building a new <code>Zend_XmlRpc_Value</code>
+                        object, its value is set by a PHP type. The PHP type
+                        will be converted to the specified type using
+                        PHP casting. For example, if a string is given as a
+                        value to the <code>Zend_XmlRpc_Value_Integer</code>
+                        object, it will be converted using
+                        <code>(int)$value</code>.
+                    </para>
+                </note>
+            </para>
+        </sect3>
+    </sect2>
+
+    <sect2 id="zend.xmlrpc.client.requests-and-responses">
+        <title>Server Proxy Object</title>
+        <para>
+            Another way to call remote methods with the XML-RPC client is to
+            use the server proxy.  This is a PHP object that proxies a remote
+            XML-RPC namespace, making it work as close to a native PHP object
+            as possible.
+        </para>
+
+        <para>
+            To instantiate a server proxy, call the <code>getProxy()</code>
+            instance method of <code>Zend_XmlRpc_Client</code>. This will
+            return an instance of <code>Zend_XmlRpc_Client_ServerProxy</code>.
+            Any method call on the server proxy object will be forwarded to
+            the remote, and parameters may be passed like any other PHP
+            method.
+        </para>
+
+        <example id="zend.xmlrpc.client.requests-and-responses.example-1">
+            <title>Proxy the Default Namespace</title>
+            <programlisting role="php"><![CDATA[
+$client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
+
+$server = $client->getProxy();           // Proxy the default namespace
+
+$hello = $server->test->sayHello(1, 2);  // test.Hello(1, 2) returns "hello"
+]]>
+            </programlisting>
+        </example>
+
+        <para>
+            The <code>getProxy()</code> method receives an optional argument
+            specifying which namespace of the remote server to proxy. If it
+            does not receive a namespace, the default namespace will be
+            proxied.  In the next example, the <code>test</code> namespace
+            will be proxied:
+        </para>
+
+        <example id="zend.xmlrpc.client.requests-and-responses.example-2">
+            <title>Proxy Any Namespace</title>
+            <programlisting role="php"><![CDATA[
+$client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
+
+$test  = $client->getProxy('test');     // Proxy the "test" namespace
+
+$hello = $test->sayHello(1, 2);         // test.Hello(1,2) returns "hello"
+]]>
+            </programlisting>
+        </example>
+
+        <para>
+            If the remote server supports nested namespaces of any depth,
+            these can also be used through the server proxy. For example, if
+            the server in the example above had a method
+            <code>test.foo.bar()</code>, it could be called as
+            <code>$test-&gt;foo-&gt;bar()</code>.
+        </para>
+    </sect2>
+
+
+    <sect2 id="zend.xmlrpc.client.error-handling">
+        <title>Error Handling</title>
+        <para>
+            Two kinds of errors can occur during an XML-RPC method call: HTTP
+            errors and XML-RPC faults. The <code>Zend_XmlRpc_Client</code>
+            recognizes each and provides the ability to detect and trap them
+            independently.
+        </para>
+
+        <sect3 id="zend.xmlrpc.client.error-handling.http">
+            <title>HTTP Errors</title>
+
+            <para>
+                If any HTTP error occurs, such as the remote HTTP server
+                returns a <code>404 Not Found</code>, a
+                <code>Zend_XmlRpc_Client_HttpException</code> will be thrown.
+            </para>
+
+            <example id="zend.xmlrpc.client.error-handling.http.example-1">
+                <title>Handling HTTP Errors</title>
+
+                <programlisting role="php"><![CDATA[
+$client = new Zend_XmlRpc_Client('http://foo/404');
+
+try {
+
+    $client->call('bar', array($arg1, $arg2));
+
+} catch (Zend_XmlRpc_Client_HttpException $e) {
+
+    // $e->getCode() returns 404
+    // $e->getMessage() returns "Not Found"
+
+}
+]]>
+                </programlisting>
+            </example>
+
+            <para>
+                Regardless of how the XML-RPC client is used, the
+                <code>Zend_XmlRpc_Client_HttpException</code> will be thrown
+                whenever an HTTP error occurs.
+            </para>
+        </sect3>
+
+        <sect3 id="zend.xmlrpc.client.error-handling.faults">
+            <title>XML-RPC Faults</title>
+
+            <para>
+                An XML-RPC fault is analogous to a PHP exception. It is a
+                special type returned from an XML-RPC method call that has
+                both an error code and an error message. XML-RPC faults are
+                handled differently depending on the context of how the
+                <code>Zend_XmlRpc_Client</code> is used.
+            </para>
+
+            <para>
+                When the <code>call()</code> method or the server
+                proxy object is used, an XML-RPC fault will result in a
+                <code>Zend_XmlRpc_Client_FaultException</code> being thrown.
+                The code and message of the exception will map directly to
+                their respective values in the original XML-RPC fault
+                response.
+            </para>
+
+            <example id="zend.xmlrpc.client.error-handling.faults.example-1">
+                <title>Handling XML-RPC Faults</title>
+
+                <programlisting role="php"><![CDATA[
+$client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
+
+try {
+
+    $client->call('badMethod');
+
+} catch (Zend_XmlRpc_Client_FaultException $e) {
+
+    // $e->getCode() returns 1
+    // $e->getMessage() returns "Unknown method"
+
+}
+]]>
+                </programlisting>
+            </example>
+
+            <para>
+                When the <code>call()</code> method is used to make the
+                request, the <code>Zend_XmlRpc_Client_FaultException</code> will be
+                thrown on fault. A <code>Zend_XmlRpc_Response</code> object
+                containing the fault will also be available by calling
+                <code>getLastResponse()</code>.
+            </para>
+
+            <para>
+                When the <code>doRequest()</code> method is used to make the
+                request, it will not throw the exception. Instead, it will
+                return a <code>Zend_XmlRpc_Response</code> object returned
+                will containing the fault. This can be checked with
+                <code>isFault()</code> instance method of
+                <code>Zend_XmlRpc_Response</code>.
+            </para>
+        </sect3>
+
+    </sect2>
+
+    <sect2 id="zend.xmlrpc.client.introspection">
+        <title>Server Introspection</title>
+        <para>
+            Some XML-RPC servers support the de facto introspection methods under the XML-RPC
+            <code>system.</code> namespace.  <code>Zend_XmlRpc_Client</code> provides special
+            support for servers with these capabilities.
+        </para>
+
+        <para>
+            A <code>Zend_XmlRpc_Client_ServerIntrospection</code> instance may be retrieved by calling
+            the <code>getIntrospector()</code> method of <code>Zend_XmlRpcClient</code>.  It can
+            then be used to perform introspection operations on the server.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.xmlrpc.client.request-to-response">
+        <title>From Request to Response</title>
+        <para>
+            Under the hood, the <code>call()</code> instance method of <code>Zend_XmlRpc_Client</code>
+            builds a request object (<code>Zend_XmlRpc_Request</code>) and sends it to another method,
+            <code>doRequest()</code>, that returns a response object (<code>Zend_XmlRpc_Response</code>).
+        </para>
+
+        <para>
+            The <code>doRequest()</code> method is also available for use directly:
+        </para>
+
+        <example id="zend.xmlrpc.client.request-to-response.example-1">
+            <title>Processing Request to Response</title>
+
+            <programlisting role="php"><![CDATA[
+$client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
+
+$request = new Zend_XmlRpc_Request();
+$request->setMethod('test.sayHello');
+$request->setParams(array('foo', 'bar'));
+
+$client->doRequest($request);
+
+// $server->getLastRequest() returns instanceof Zend_XmlRpc_Request
+// $server->getLastResponse() returns instanceof Zend_XmlRpc_Response
+]]>
+            </programlisting>
+        </example>
+
+        <para>
+            Whenever an XML-RPC method call is made by the client through any
+            means, either the <code>call()</code> method,
+            <code>doRequest()</code> method, or server proxy, the last request
+            object and its resultant response object will always be available
+            through the methods <code>getLastRequest()</code> and
+            <code>getLastResponse()</code> respectively.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.xmlrpc.client.http-client">
+        <title>HTTP Client and Testing</title>
+
+        <para>
+            In all of the prior examples, an HTTP client was never specified.
+            When this is the case, a new instance of
+            <code>Zend_Http_Client</code> will be created with its default
+            options and used by <code>Zend_XmlRpc_Client</code> automatically.
+        </para>
+
+        <para>
+            The HTTP client can be retrieved at any time with the
+            <code>getHttpClient()</code> method. For most cases, the default
+            HTTP client will be sufficient. However, the
+            <code>setHttpClient()</code> method allows for a different HTTP
+            client instance to be injected.
+        </para>
+
+        <para>
+            The <code>setHttpClient()</code> is particularly useful for unit testing.  When combined
+            with the <code>Zend_Http_Client_Adapter_Test</code>, remote services can be mocked
+            out for testing.  See the unit tests for <code>Zend_XmlRpc_Client</code> for examples
+            of how to do this.
+        </para>
+    </sect2>
+
+</sect1>
+<!--
+vim:se ts=4 sw=4 et:
+-->