Browse Source

DOCUMENTATION Spanish:
- convert CRLF => LF

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

mikaelkael 16 years ago
parent
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
             Normalmente, se espera que los usuarios usen
             una de las clases adaptadoras como
             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
             , pero si los datos de configuración están disponibles
             en un array PHP, se puede simplemente pasar los datos al
             en un array PHP, se puede simplemente pasar los datos al
             constructor
             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[
         <programlisting role="php"><![CDATA[
 // Dado un array de datos de configuración
 // Dado un array de datos de configuración
 $configArray = array(
 $configArray = array(
@@ -122,6 +122,6 @@ echo $config->webhost;
         </programlisting>
         </programlisting>
     </example>
     </example>
 </sect1>
 </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[
             <programlisting role="php"><![CDATA[
 $options['nestSeparator'] = ':';
 $options['nestSeparator'] = ':';
 $config = new Zend_Config_Ini('/path/to/config.ini',
 $config = new Zend_Config_Ini('/path/to/config.ini',
@@ -127,64 +127,64 @@ echo $config->database->params->dbname; // muestra "dbname"
                 <tbody>
                 <tbody>
                     <row>
                     <row>
                         <entry>
                         <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>
         <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>
             Hay un método separado para agregar cada al objeto Zend_Db_Select.</para>
 
 
         <example id="zend.db.select.building.example">
         <example id="zend.db.select.building.example">
@@ -129,8 +129,8 @@ $select->order( ...specify sorting criteria... );
 
 
         </example>
         </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>
             al objeto que se ha llamado, así puedes llamar inmediatamente a otro método.</para>
 
 
         <example id="zend.db.select.building.example-fluent">
         <example id="zend.db.select.building.example-fluent">
@@ -147,9 +147,9 @@ $select = $db->select()
 
 
         </example>
         </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>
             cierta lógica antes de añadir una cláusula a la consulta.</para>
 
 
         <sect3 id="zend.db.select.building.from">
         <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[
         <programlisting role="php"><![CDATA[
 try {
 try {
     Zend_Loader::loadClass('clasenoexistente');
     Zend_Loader::loadClass('clasenoexistente');
@@ -30,6 +30,6 @@ try {
     </para>
     </para>
 
 
 </sect1>
 </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:
+-->