<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Backtheweb &#187; PHP</title>
	<atom:link href="http://www.backtheweb.com/category/php/feed" rel="self" type="application/rss+xml" />
	<link>http://www.backtheweb.com</link>
	<description>Notas y recursos de un desarrollador web</description>
	<lastBuildDate>Wed, 21 Jul 2010 21:59:56 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Instalar APC en Snow Leopard</title>
		<link>http://www.backtheweb.com/php/instalar-apc-en-snow-leopard.html</link>
		<comments>http://www.backtheweb.com/php/instalar-apc-en-snow-leopard.html#comments</comments>
		<pubDate>Wed, 21 Jul 2010 00:25:49 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[APC]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[Snow Leopa]]></category>

		<guid isPermaLink="false">http://www.backtheweb.com/?p=368</guid>
		<description><![CDATA[Actualmente estoy integrando Doctrine 2 con Zend Framework.
A la hora de executar en la terminal doctrine orm:validate-schema me encontraba con el siguiente error:
PHP Fatal error:  Call to undefined function Doctrine\Common\Cache\apc_fetch() in /vhosts/doctrine/library/Doctrine/Common/Cache/ApcCache.php on line 59
Esto sucede porque no tengo instalado el APC.
Para instalar correctamente el APC se han de indicar en Snow Leopard unos [...]]]></description>
			<content:encoded><![CDATA[<p>Actualmente estoy integrando <strong>Doctrine 2</strong> con<strong> Zend Framework</strong>.</p>
<p>A la hora de executar en la terminal <code>doctrine orm:validate-schema</code> me encontraba con el siguiente error:</p>
<p><code>PHP Fatal error:  Call to undefined function Doctrine\Common\Cache\apc_fetch() in /vhosts/doctrine/library/Doctrine/Common/Cache/ApcCache.php on line 59</code></p>
<p>Esto sucede porque no tengo instalado el <strong>APC</strong>.</p>
<p>Para instalar correctamente el <strong>APC</strong> se han de indicar en <strong>Snow Leopard</strong> unos flags para que el <strong>APC</strong> se compile con la arquitectura adecuada</p>
<pre><code>wget http://pecl.php.net/get/APC-3.1.3p1.tgz
tar -xvf APC-3.1.3p1.tgz
cd APC-3.1.3p1
/usr/local/zend/bin/phpize

MACOSX_DEPLOYMENT_TARGET=10.6
CFLAGS="-arch i386 -arch x86_64 -g -Os -pipe -no-cpp-precomp"
CCFLAGS="-arch i386 -arch x86_64 -g -Os -pipe"
CXXFLAGS="-arch i386 -arch x86_64 -g -Os -pipe"
LDFLAGS="-arch i386 -arch x86_64 -bind_at_load"
export CFLAGS CXXFLAGS LDFLAGS CCFLAGS MACOSX_DEPLOYMENT_TARGET

./configure --enable-apc-mmap --with-apxs=/usr/sbin/apxs --with-php-config=/usr/local/zend/bin/php-config

make
sudo make install
</code></pre>
<p>Luego insertamos en el <em>php.ini</em></p>
<pre><code>extension=apc.so

apc.enabled=1
apc.shm_segments=1
apc.shm_size=128
apc.ttl=7200
apc.user_ttl=7200
apc.num_files_hint=1024
apc.mmap_file_mask=/tmp/apc.XXXXXX
apc.enable_cli=1</code></pre>
<p>Reinicia el <em>apache</em> y revisa la configuración del <strong>APC</strong> con <code>phpinfo()</code>, verás que se ha compilado correctamente.</p>
<p><strong>Actualización</strong>: Si al recargar las paginas web se os queda la página en blanco mirar los logs de php. Si os aparece:<br />
<code> Module 'apc' already loaded in Unknown on line 0</code> comentar la linea <code>extension=apc.so</code> poniendo un &#8220;;&#8221; (punto y comoa) delante.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.backtheweb.com/php/instalar-apc-en-snow-leopard.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend Form Decorator, parte I</title>
		<link>http://www.backtheweb.com/php/zend-form-decorator-parte-i.html</link>
		<comments>http://www.backtheweb.com/php/zend-form-decorator-parte-i.html#comments</comments>
		<pubDate>Fri, 20 Nov 2009 23:05:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://www.backtheweb.com/?p=347</guid>
		<description><![CDATA[Los formularios de Zend Framework es una de las cosas que más me gustan del framework porque te permite validar, procesar y modificar los formularios de una forma muy rápida y limpia. No obstante, de entrada queda todo muy limitado por la forma de presentar los datos con una lista de definición (dl). Aveces soy [...]]]></description>
			<content:encoded><![CDATA[<p>Los <strong>formularios</strong> de <strong>Zend Framework</strong> es una de las cosas que más me gustan del <em>framework</em> porque te permite validar, procesar y modificar los formularios de una forma muy rápida y limpia. No obstante, de entrada queda todo muy limitado por la forma de presentar los datos con una <em>lista de definición (dl)</em>. Aveces soy muy purista, y usar <code>dl</code>, <code>dt</code> y <code>dd</code> para maquetar un formulario no lo encuentro nada semántico (y tampoco con li).</p>
<p>La primera necesidad que me surge es cambiar el <code>dl</code> por un <code>div</code> y los <code>dt</code>&#8217;s y <code>dd</code>&#8217;s por <code>p</code>&#8217;s del <strong>formulario</strong>:</p>
<pre><code>$form-&gt;clearDecorators()
	-&gt;addDecorator('FormElements')
	-&gt;addDecorator('HtmlTag', 	array('tag' =&gt; '</code>', 'class' =&gt; 'zend_form'))
	-&gt;addDecorator('Form')
	-&gt;setElementDecorators(array(
		array('ViewHelper'),
		array('Errors'),
		array('Description', 	array('tag' =&gt; 'span', 'class' =&gt; 'element-description')),
		array('Label', 			array('separator' =&gt; ' ')),
		array('HtmlTag', 		array('tag' =&gt; 'p', 'class' =&gt; 'element-group')
	),
));</pre>
<p><span id="more-347"></span>De esta forma todos los elementos del <strong>formulario</strong> estarán construidos con una <code>p</code> y con la clase <code>element-group</code>, las ayudas descriptivas estaran dentro de la misma <code>p</code> pero dentro de un <code>span</code> y con la clase <code>element-group-description</code></p>
<p>El segundo aspecto es hacer que el <code>submit</code> no tenga <code>label</code>, para eso basta con no ponerlo, pero al hacerlo con listas de definición nos crea un <code>dt</code> vacío. pero además quiero que disponga de un <em>link</em> de &#8220;volver&#8221; o &#8220;cancelar&#8221;:</p>
<pre><code>$form-&gt;addElement('submit', 'submit', array(
	'ignore'   		=&gt; true,
	'description'	=&gt; '&lt;a href=\"#\"&gt;Cancel&lt;/a&gt;',
	'decorators' 	=&gt; array(
		array('ViewHelper'),
		array('Description', 	array('escape' =&gt; false, 'tag' =&gt; 'span', 'class'=&gt;'element-canel-link')),
		array('HtmlTag', 		array('tag' =&gt; 'p', 'class'=&gt;'submit-group'))
	)
));</code></pre>
<p>Aquí lo importante son los valores que pasamos a la array <code>Description</code> y lo mismo lo podemos hacer para un <code>input</code>.</p>
<pre><code>$form-&gt;addElement('password', 'credential', array(
	'label'      	=&gt; 'Password',
	'required'   	=&gt; true,
	'filters'    =&gt; array('StringTrim', 'StripTags'),
	'description'	=&gt; '&lt;a href=\"#\"&gt;Remember password&lt;/a&gt;',
	'decorators' 	=&gt; array(
		array('ViewHelper'),
		array('Description', 	array('escape' =&gt; false, 'tag' =&gt; 'span', 'class'=&gt;'element-description')),
		array('Label', 			array('separator'=&gt;' ')),
		array('Errors'),
		array('HtmlTag', 		array('tag' =&gt; 'p', 'class'=&gt;'element-group'))
	)
));</code></pre>
<p>Otro gran problema que se presenta con <strong>Zend Form</strong> es que al imprimir un <em>checkbox</em> lo pone después del <code>label</code> y eso es poco usable.</p>
<pre><code>$form-&gt;addElement('checkbox', 'rememberme', array(
	'label'     =&gt; 'Remember me',
	'value'		=&gt; '1',
	'checked' 	=&gt; false,
	'decorators' 	=&gt; array(
		array('ViewHelper'),
		array('Label', 			array('placement' =&gt; 'APPEND')),
		array('Errors'),
		array('HtmlTag', 		array('tag' =&gt; 'p', 'class'=&gt;'element-group'))
	)
));</code></pre>
<p>(Creo que aquí hay un bug, además del <code>checbox</code> me ha añadido un <code>input hidden</code>, pero no debería darnos muchos problemas, espero))</p>
<p>De esta forma my clase formulario queda así:</p>
<pre><code>class Default_Form_Login extends Zend_Form
{
    /**
     * init()
     *
     * @see    http://framework.zend.com/manual/en/zend.form.html
     * @return void
     */
    public function init()
    {
        // Set the method for the display form to POST
        $this-&gt;setMethod('post');
        $this-&gt;setAction('/auth/login/');
        $this-&gt;setAttrib('id', 'loginForm');

        $this-&gt;clearDecorators()
        	-&gt;addDecorator('FormElements')
         	-&gt;addDecorator('HtmlTag', array('tag' =&gt; '
</code>
<div>', 'class' =&gt; 'zend_form'))
         	-&gt;addDecorator('Form')
        	-&gt;setElementDecorators(array(
	            array('ViewHelper'),
	            array('Errors'),
	            array('Description',	array('tag' =&gt; 'span', 'class' =&gt; 'element-description')),
	            array('Label', 			array('separator' =&gt; ' ')),
	            array('HtmlTag', 		array('tag' =&gt; 'p', 'class' =&gt; 'element-group')
			),
        ));

        $this-&gt;addElement('text', 'identity', array(
            'label'      	=&gt; 'Email',
        	'value'			=&gt; '',
            'required'   	=&gt; true,
            'filters'    	=&gt; array('StringTrim', 'StripTags', 'StringToLower'),
        	'validators' 	=&gt; array('EmailAddress'),
        ));

        $this-&gt;addElement('password', 'credential', array(
            'label'      	=&gt; 'Password',
            'required'   	=&gt; true,
        	'filters'    =&gt; array('StringTrim', 'StripTags'),
        	'description'	=&gt; '&lt;a href=\"#\"&gt;Remember password&lt;/a&gt;',
			'decorators' 	=&gt; array(
				array('ViewHelper'),
	            array('Description', 	array('escape' =&gt; false, 'tag' =&gt; 'span', 'class'=&gt;'element-description')),
	            array('Label', 			array('separator'=&gt;' ')),
	            array('Errors'),
				array('HtmlTag', 		array('tag' =&gt; 'p', 'class'=&gt;'element-group'))
			)
        ));

        $this-&gt;addElement('checkbox', 'rememberme', array(
            'label'     =&gt; 'Remember me',
            'value'		=&gt; '1',
        	'checked' 	=&gt; false,
        	'decorators' 	=&gt; array(
				array('ViewHelper'),
	            array('Label', 			array('placement' =&gt; 'APPEND')),
	            array('Errors'),
				array('HtmlTag', 		array('tag' =&gt; 'p', 'class'=&gt;'element-group'))
			)
        ));

        // Add the submit button
       	$this-&gt;addElement('submit', 'submit', array(
            'ignore'   		=&gt; true,
       		'description'	=&gt; '&lt;a href=\"#\"&gt;Cancel&lt;/a&gt;',
       		//set decorator
			'decorators' 	=&gt; array(
				array('ViewHelper'),
				array('Description', 	array('escape' =&gt; false, 'tag' =&gt; 'span', 'class'=&gt;'element-canel-link')),
				array('HtmlTag', 		array('tag' =&gt; 'p', 'class'=&gt;'submit-group'))
			)
        ));

        // And finally add some CSRF protection
        $this-&gt;addElement('hash', 'csrf', array(
        	'ignore' =&gt; true,
       		//set decorator
        	'decorators' =&gt;
			array(
				array('ViewHelper'),
				array('HtmlTag', 		array('tag' =&gt; 'p', 'class'=&gt;'element-group-hidden'))
			)
        ));
    }
}</div>
</pre>
<p>Lo ideal sería crear una clase con <code>Zend_Form_Decorator</code> para que realizará estos cambios automáticamente, pero eso es ya lo dejo para otro post. Así que hasta aquí la primera parte de los <strong>Decorators</strong>, otro día (espero) veremos como tratar otros elementos, los errores, etc&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.backtheweb.com/php/zend-form-decorator-parte-i.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Zend Layout y ActionStacks de Zend Framework</title>
		<link>http://www.backtheweb.com/php/zend-layout-actionstacks-zend-framework.html</link>
		<comments>http://www.backtheweb.com/php/zend-layout-actionstacks-zend-framework.html#comments</comments>
		<pubDate>Tue, 29 Sep 2009 23:16:22 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://www.backtheweb.com/?p=325</guid>
		<description><![CDATA[En la documentación deZend Layout no acaba de quedar muy claro como se usa y suele provocar muchas confusiones si solo hacemos una lectura vertical del manual.
Zend Layout es uno de mis objetos preferidos por la versatilidad que ofrece y una vez entiendes el proceso y como combinarlo con el resto del Framework y los [...]]]></description>
			<content:encoded><![CDATA[<p>En la documentación de<strong>Zend Layout</strong> no acaba de quedar muy claro como se usa y suele provocar muchas confusiones si solo hacemos una lectura vertical del manual.</p>
<p><strong>Zend Layout</strong> es uno de mis objetos preferidos por la versatilidad que ofrece y una vez entiendes el proceso y como combinarlo con el resto del Framework y los <em>placeholders</em> obtienes una gestión muy clara de las plantillas.</p>
<p>Vamos a suponer el siguiente <em>layout</em>:</p>
<pre><code>&lt;div&gt;
&lt;?php echo $this-&gt;render('header.phtml') ?&gt;
&lt;h1&gt;&lt;?php echo $this-&gt;placeholder('h1') ?&gt;&lt;/h1&gt;
&lt;?php echo $this-&gt;layout()-&gt;nav ?&gt;
&lt;?php echo $this-&gt;layout()-&gt;content ?&gt;
&lt;/div&gt;</code></pre>
<p><span id="more-325"></span>Cada bloque de código <strong>php</strong> realiza una acción diferente.</p>
<ul>
<li><em>$this-&gt;render(&#8217;header.phtml&#8217;) </em> se encargará de llamar al archivo <em>header.phtml</em> que estará ubicado en el mismo nivel que el <em>layout</em>.</li>
<li><em>$this-&gt;placeholder(&#8217;h1&#8242;) </em> nos devolverá el valor que hallamos definido en la plantilla usando <em>$this-&gt;placeholder(&#8217;h1&#8242;)-&gt;set(&#8217;Mi h1&#8242;); </em></li>
<li><em>$this-&gt;layout()-&gt;nav</em> es un <strong>ActionStack</strong></li>
<li><em>$this-&gt;layout()-&gt;content</em> nos devolverá el contenido de la plantilla</li>
</ul>
<p>Pero ¿Que són los <em>ActionStacks</em>? ¿como se usan los? y ¿Para que sirven? Básicamente lo que logramos con los <em>ActionStacks</em> es renderizar un fragmento de código generado por una acción que no es la misma que estamos ejecutando en el momento de renderizar la página.</p>
<p>Todo será más fácil si usamos el <abbr title="Modelo Vista Controlador">MVC</abbr> o <em>Zend Application</em></p>
<p>Para hacer un <em>ActionStack</em> necesitaremos dos cosas: Un controlador y una llamada a este.</p>
<p>Lo primero será crear un controlador como cualquier otro, por ejemplo: <em>NavegacionController</em> con una acción <em>menuAction</em>. Esta acción renderizará <em>menu.phtml</em> pero le indicaremos en que segmento de la plantilla o layout se deberá renderizarse:</p>
<pre><code>
class NavegacionController extends Zend_Controller_Action{

    public function menuAction(){

    	// renderiza menu.phtml en el segmento nav
    	$this-&gt;_helper-&gt;viewRenderer-&gt;setResponseSegment('nav');
    }
}
</code></pre>
<p>Lo siguiente es hacer la llamada desde la acción principal.</p>
<pre><code>
class IndexController extends Zend_Controller_Action {

	public function indexAction() {

		$this-&gt;_helper-&gt;actionStack ('menu', 'navegacion', 'default');
	}
}
</code></pre>
<p>Es decir, cuando llamemos a <em>IndexAction</em> del <em>IndexController</em> el se encargará de llamar a <em>menuAction</em> del <em>navegaciónController</em> para que renderize <em>scripts/navegacion/menu.phtml</em> en el segmento <em>nav</em> que hemos indicado en el <em>layout</em> con <em>$this-&gt;layout()-&gt;nav</em>.</p>
<p>Entonces vemos que el primer parámetro es la acción, el segundo el controlador y el tercero es opcional y se refiere al módulo que por defecto es <em>default</em>.</p>
<p>Para profundizar más con los <em>layouts</em> estan los <em>Placeholder Helper</em> pero esto se sale ya del tema y lo dejo para otro post.</p>
<p>Espero que os se útil.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.backtheweb.com/php/zend-layout-actionstacks-zend-framework.html/feed</wfw:commentRss>
		<slash:comments>56</slash:comments>
		</item>
		<item>
		<title>Zend Framework no funciona en MAMP PRO</title>
		<link>http://www.backtheweb.com/php/zend-framework-no-funciona-en-mamp-pro.html</link>
		<comments>http://www.backtheweb.com/php/zend-framework-no-funciona-en-mamp-pro.html#comments</comments>
		<pubDate>Thu, 03 Sep 2009 21:39:12 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://www.backtheweb.com/?p=317</guid>
		<description><![CDATA[Pues hoy me he de comer las palabras que dije ayer en el post que hablaba de MAMP. Hoy he querido probar MAMP Pro y me ha decepcionado.
A diferencia de la versión lite, con la Pro puedes configurar los virtual hosts sin tocar ningún fichero de conflagración ni el fichero hosts lo cual resulta muy [...]]]></description>
			<content:encoded><![CDATA[<p>Pues hoy me he de comer las palabras que dije ayer en el post que hablaba de <a title="MAMP, Mac Apache MySQL PHP, la mejor alternativa siempre" href="http://www.backtheweb.com/general/mamp-mac-apache-mysql-php-la-mejor-alternativa-siempre.html">MAMP</a>. Hoy he querido probar <strong>MAMP Pro</strong> y me ha decepcionado.</p>
<p>A diferencia de la versión <em>lite</em>, con la <em>Pro </em>puedes configurar los <em>virtual hosts</em> sin tocar ningún fichero de conflagración ni el fichero <em>hosts</em> lo cual resulta muy práctico cuando no te mueves con soltura por la <em>Terminal</em>.</p>
<p>El problema en cuestión ha sido un &#8220;<strong>Fatal error</strong>: <em>Allowed memory size of </em>&#8230;&#8221; al ejecutar una apalicación desarrollada en <strong>Zend Framework</strong>. Por defecto <strong>PHP </strong>establece un máximo memoria de 8 Mb y cambiar este valor es tan fácil como editar el parámetro  <em>memory_limit</em> el <em>php.ini</em>.</p>
<p><span id="more-317"></span></p>
<p>Considero que este tipo de ajustes no se deberían realizar a menos que sean realmente necesarios como cuando trabajas con imágenes pero al ser un desarrollo local tampoco es que me mporte mucho así que he editado el <em>php.ini</em>.</p>
<p>¿Cual ha sido la sorpresa? Por mucho que editará el fichero no se reflejaban los cambios. Consulto la ubicación del <em>php.ini</em> con <em>phpInfo()</em> y veo que el fichero esta ubicado en:</p>
<pre>/Library/Application Support/living-e/MAMP PRO/conf/php.ini</pre>
<p>Ok, soy tonto, estaba tocando el fichero <strong>MAMP</strong> y no de <strong>MAMP Pro</strong> (costumbre de usar la verión <em>lite)</em> así que edito el fichero correcto y reinicio.</p>
<p>¿Otra vez? Nada, no se refleja el cambio  8 por 12 y nada. Sigue en 8Mb. La cosa estaba clara yo editaba el fichero correcto pero al arrancar <strong>MAMP Pro</strong> se sobrescribe los cambios. Por lo tanto el fichero <em>php.ini</em> esta en otro lugar y no podía ser otro que dentro de la misma aplicación.</p>
<p>Entonces es cuando abro el contenido de <strong>MAMP Pro</strong> y encuentro el fichero correcto en:</p>
<pre>/Applications/MAMP PRO 1.72/MAMP PRO.app/Contents/Resources/php5.ini</pre>
<p>Ok, todo listo, reiniciamos el <strong>Apache</strong> y comprobamos que los ajustes sean correctos. Y lo son, pero nada el <strong>Fatal Error </strong>aparece igualmente por lo que acabo subiendo el limite de memoria a 32Mb pero nada.</p>
<p>La conclusión es <strong>Zend Framework</strong> no funciona en <strong>MAMP Pro</strong>. Quizás no he buscado suficientemente bien en <em>Google</em>, pero si empezamos así.. mejor volver a usar <a title="MacPorts" href="http://www.macports.org/">MacPorts</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.backtheweb.com/php/zend-framework-no-funciona-en-mamp-pro.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Como manejar fechas en Zend Framework con Zend Form y Zend Validate</title>
		<link>http://www.backtheweb.com/php/como-manejar-fechas-en-zend-framework-con-zend-form-y-zend-validate.html</link>
		<comments>http://www.backtheweb.com/php/como-manejar-fechas-en-zend-framework-con-zend-form-y-zend-validate.html#comments</comments>
		<pubDate>Sun, 30 Aug 2009 08:00:16 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://www.backtheweb.com/?p=271</guid>
		<description><![CDATA[Validar una fecha en un formulario usando los módulos Zend Form y Zend Validate no tiene ningún misterio tan solo deberemos agregar la clase Zend_Validate_Date a la opción valdators de nuestro elemento tipo text del fomulario, algo así:

$form-&#62;addElement('text', 'date', array(
	'label'      =&#62; 'date',
	'validators' =&#62; array('date')

));

El problema lo encontramos cuando queremos usar [...]]]></description>
			<content:encoded><![CDATA[<p>Validar una fecha en un formulario usando los módulos <strong>Zend Form</strong> y <strong>Zend Validate</strong> no tiene ningún misterio tan solo deberemos agregar la clase <strong>Zend_Validate_Date</strong> a la opción <em>valdators</em> de nuestro elemento tipo <em>text</em> del fomulario, algo así:</p>
<pre><code>
$form-&gt;addElement('text', 'date', array(
	'label'      =&gt; 'date',
	'validators' =&gt; array('date')

));
</code></pre>
<p>El problema lo encontramos cuando queremos usar un determinado formato de fecha y lo queremos almacenar en la base de datos. Este tipo de tareas son las que un programador siempre recopila en una función y se las guarda en su librería para facilitarse la tareas repetitivas en sus proyectos. En cierto modo estas tareas ya las hacen o deberían hacer los <strong>frameworks</strong> (pues los <em>frameworks</em> son al final una recopliación de funciones y clases para facilitarnos el trabajo).</p>
<p><span id="more-271"></span></p>
<p>En el <strong>Zend Framework</strong> no existe por ahora una forma muy clara de como automatizar este proceso si usamos el módulo <strong>Zend Application</strong> pero con un par de apaños y sin usar ningún <em>plugin</em> o <em>helper</em> veamos como lo podemos solucionar con lo que nos ofrece el <em>framework</em></p>
<p>Primeros, vamos a suponer que estamos creando una aplicación con la misma estructura que se usa en el <em>Quick Start</em> del <strong>Zend Framework</strong>. Entonces ¿Que neceistamos?</p>
<ul>
<li>
<ol>Un objeto de formulario <strong>Zend_Form</strong></ol>
<ol>Un modelo de datos <strong>Zend_DB_Table</strong> y un mapeador</ol>
<ol>internacionalizar la aplicación con <strong>Zend_Locale</strong></ol>
</li>
</ul>
<p>¿Por dónde empezamos?<br />
Lo primero que haremos será que nuestro formulario valide las fechas con el formato que a nosotros nos interesa <em>dd/mm/yyyy</em> (es decir el más común en la lengua hispánica). Para ello en nuestra objeto formulario que extiende el <strong>Zend_Form</strong> debe existir un elemento tipo texto para introducir la fecha:</p>
<pre><code>
$this-&gt;addElement('text', 'fecha', array(
	'label'      =&gt; 'fecha',
	'required'   =&gt; true,
	'filters'    =&gt; array('StringTrim', 'StripTags'),
	'validators' =&gt; array('date')
));</code></pre>
<p>Lo que estamos haciendo es que solo las fechas serán validas pero no estamos indicando en que formato. Aquí es cuando entra en juego <strong>Zend Locale</strong> por lo que añdiremos en nuestro <em>bootstrap</em> la siguiente función:</p>
<pre><code>
protected function _initLocale(){

	$locale = new Zend_Locale();
	$locale-&gt;setLocale('es_ES');
	Zend_Registry::set('Zend_Locale', $locale); // la registramos para su futuro uso en el resto de la aplicación
}
</code></pre>
<p>Una vez la fecha es valida la hemos de guardar en la base de datos con el formato tipico de <em>yyyy-mm-dd</em>. Nos situamos en la función <em>Save</em> de nuestro <em>mapper</em> y añadiremos al principio la conversión de tipo de fecha con <strong>Zend_date</strong>:</p>
<pre><code>
public function save(Default_Model_Mitabla $tabla){

	// Creamos un objeto Zend_Date y como parámetro la fecha que recibimos
    	$fecha 	= new Zend_Date($tabla-&gt;getFecha());

	$data = array(
		'nombre'   	=&gt; $tabla-&gt;getNombre(),
		'startDate'	=&gt; $startDate-&gt;getIso()		// retornamos la fecha en formato ISO 8601
	);

	if (null === ($id = $tabla-&gt;getId()) || $tabla-&gt;getID() == 0) {

		unset($data['id']);

		$this-&gt;getDbTable()-&gt;insert($data);

	} else {

		$this-&gt;getDbTable()-&gt;update($data, array('id = ?' =&gt; $id));
	}
}
</code></pre>
<p>Finalmente solo nos queda una cosa, recuperar las fechas de la base de datos en el formato que deseamos, por lo que modificaremos la función <em>Find</em> del <em>mapper</em>:</p>
<pre><code>
public function find($id, Default_Model_Mitabla $tabla){

	$result = $this-&gt;getDbTable()-&gt;find($id);

	if (0 == count($result)) {
            return;
	}

	$row = $result-&gt;current();

	$fecha 	= new Zend_Date($row-&gt;fecha, 	Zend_Date::ISO_8601);

	$job-&gt;setId($row-&gt;id)
			-&gt;setNombre($row-&gt;nombre)
			-&gt;setStartDate(str_replace('00:00:00', '', $fecha-&gt;getDate()));
}
</code></pre>
<p>Nuevamente lo que hacemos es crear un objeto <strong>Zend Date</strong> pasando como primer argumento la fecha que recibimos de la base de datos y como segundo el formato en que la recibimos. Luego con <em>getDate()</em> devolvemos la fecha en el formato esperado tal como hemos indicado con <strong>Zend_Locale</strong>. Notad que he añadido un <em>str_replace</em> pues como se trata de un campo de tipo <em>Date</em> y no <em>Datetime</em> no me interesa que me retorne la hora.</p>
<p>De esta forma, en principio, nos será fácil mantener una aplicación en diferentes idiomas y las fechas se mostraran en el formato propio del idioma indicado, prueba a cambiar el argumento <em>locale</em> del objeto <strong>&gt;Zend Locale y todo debería funcionar correctamente.</strong></p>
<p><strong>Espero que os sea útil y se veis algún error o sabéis la forma de hacerlo mucho más fácil espero vuestros comentarios.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.backtheweb.com/php/como-manejar-fechas-en-zend-framework-con-zend-form-y-zend-validate.html/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Como activar los helpers con Zend_Application</title>
		<link>http://www.backtheweb.com/php/como-activar-los-helpers-con-zend_application.html</link>
		<comments>http://www.backtheweb.com/php/como-activar-los-helpers-con-zend_application.html#comments</comments>
		<pubDate>Sat, 22 Aug 2009 17:47:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://www.backtheweb.com/?p=244</guid>
		<description><![CDATA[Últimamente le encuentro más pegas que ventajas al modulo Zend_Application que incorpora la versión 1.9 del Zend Framework. Esta vez se trata de los helpers.
El primer problema lo encontramos a la hora de construir la aplicación con Zend_Tool, pues este no crear la carpeta pertinente. Y esto nos lleva al segundo problema y es que [...]]]></description>
			<content:encoded><![CDATA[<p>Últimamente le encuentro más pegas que ventajas al modulo <strong>Zend_Application</strong> que incorpora la versión 1.9 del <strong>Zend Framework</strong>. Esta vez se trata de los <strong>helpers</strong>.</p>
<p>El primer problema lo encontramos a la hora de construir la aplicación con <strong>Zend_Tool</strong>, pues este no crear la carpeta pertinente. Y esto nos lleva al segundo problema y es que <strong>Zend_Tool</strong> no registra el lugar donde serán llamados los <strong>helpers</strong>.<br />
<span id="more-244"></span><br />
Entonces lo primero que hemos de hacer es crear la carpeta<strong> helpers</strong>. ¿Dónde? En principio donde queramos. Lo lógico sería crearla dentro de la carpeta <em>controllers</em>, pero si usamos el <strong>Zend Studio</strong> cuando queramos crear un <em>helper</em> nos  lo pondrá en la raíz porque el lugar por defecto para crear los <strong>helpers </strong>es dentro de <em>application</em> es decir: <em>/application/helpers</em>.</p>
<p>Lo segundo que hemos de hacer es añadir al <em>bootstrap</em> la siguiente linea (teniendo en cuenta que existe la constante <em>APPLICATION_PATH</em> que es la ruta de nuestra aplicación y que queremos guardar los <strong>helpers</strong> en <em>/application/helpers):</em></p>
<pre><code>
Zend_Controller_Action_HelperBroker::addPath(APPLICATION_PATH .'/helpers');
</pre>
<p></code></p>
<p>Pero existe otro problema aún si usamos diferentes módulos dentro de nuestra aplicación. Seguramente nos interesará que cada módulo tenga sus propios <strong>helpers</strong></p>
<p>Para ello debemos hacer algo parecido a lo que vimos en un post anterior <a href="http://www.backtheweb.com/php/zend-framework-como-hacer-un-layout-para-cada-modulo.html">como hacer un layout para cada modulo</a></p>
<p>Necesitaremos crear un <strong>plugin</strong>:</p>
<pre><code>
//My/Controller/Action/helpers.php

class My_Controller_Action_helpers extends Zend_Controller_plugin_Abstract{

	public function preDispatch(Zend_Controller_Request_Abstract $request){
		$config = Zend_Controller_Front::getInstance()->getParam('bootstrap')->getOptions();
		$moduleName = $request->getModuleName();
		Zend_Controller_Action_HelperBroker::addPath(APPLICATION_PATH . '/modules/' . $moduleName . '/helpers');
	}
}
</code></pre>
<p>y luego registrarlo en el <em>bootstrap</em>:</p>
<pre><code>
protected function _initPlugins(){

	$this->bootstrap('frontController');
	$plugin = new My_Controller_Action_Helpers();
	$this->frontController->registerPlugin($plugin);

	Zend_Controller_Action_HelperBroker::addPath(APPLICATION_PATH  . '/helpers');

}
</code></pre>
<p>En mi caso para no crear dos plugins tan solo he añadido la linea de llamada a <em>Zend_Controller_Action_HelperBroker</em> al plugin que ya había creado en el post anterior mencionado.</p>
<p>Buenos espero que os sea útil.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.backtheweb.com/php/como-activar-los-helpers-con-zend_application.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Zend framework, como hacer un layout para cada modulo</title>
		<link>http://www.backtheweb.com/php/zend-framework-como-hacer-un-layout-para-cada-modulo.html</link>
		<comments>http://www.backtheweb.com/php/zend-framework-como-hacer-un-layout-para-cada-modulo.html#comments</comments>
		<pubDate>Mon, 10 Aug 2009 23:37:50 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://www.backtheweb.com/?p=211</guid>
		<description><![CDATA[Si estas usando la última versión de Zend Framework, la 1.9.0, y usas Zend_Application para crear aplicaciones modulares habrás notado que no puedes asignar un layout diferente para cada modulo. Después de buscar y probar diferentes métodos algunos muy complejos y que no se muy bien porque no me funcionaban encontré la solución mezclando todo [...]]]></description>
			<content:encoded><![CDATA[<p>Si estas usando la última versión de <strong>Zend Framework</strong>, la 1.9.0, y usas <strong>Zend_Application</strong> para crear aplicaciones modulares habrás notado que no puedes asignar un <em>layout</em> diferente para cada modulo. Después de buscar y probar diferentes métodos algunos muy complejos y que no se muy bien porque no me funcionaban encontré la solución mezclando todo lo que había visto.</p>
<p>Vamos a suponer que queremos crear un modulo <em>Admin </em>para nuestra aplicación y que usamos la jerarquía de ficheros establecida con <strong>Zend Tool</strong>. Seguramente nuestro fichero <em>application.ini</em> empezará algo similar a esto:<br />
<span id="more-211"></span></p>
<pre><code>[production]

phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0

includePaths.library = APPLICATION_PATH "/../library"

bootstrap.path 	= APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"

resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
resources.layout.layout = layout

resources.view[] =
resources.view.basePath = APPLICATION_PATH "/views/"</code></pre>
<p>Y probablemente querremos añadir un par de lineas para que nuestro <em>Admin</em> tenga su propio <em>layout</em>.</p>
<pre><code>;Modules config
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
admin.resources.layout.layoutPath = APPLICATION_PATH "/modules/admin/layouts/scripts"
admin.resources.layout.layout = layout</code></pre>
<p>Claro esta que eso no es suficiente, deberemos añadir:</p>
<pre><code>resources.modules[] =</code></pre>
<p>Este debe ser el primer recurso que cargues, de otra forma no funcionará, para ello colócalo al principio de todo, justo por debajo de <em>[production]</em>.</p>
<p>Seguramente, todo esto ya lo has echo y sabes que no funciona, que lo que sucede es que se sobrescribirá el <em>resources.layout.layoutPath</em> y no funcionará. Por ello lo que necesitamos es un <em>Plugin</em> que nos cargue el <em>layout</em> correcto:</p>
<pre><code>
// My/Controller/Plugin/Layout.php

class My_Controller_Plugin_Layout extends Zend_Controller_plugin_Abstract{

	public function preDispatch(Zend_Controller_Request_Abstract $request){

        $config = Zend_Controller_Front::getInstance()-&gt;getParam('bootstrap')-&gt;getOptions();
	$moduleName = $request-&gt;getModuleName();

        if (isset($config[$moduleName]['resources']['layout']['layout'])) {

        	$layoutScript = $config[$moduleName]['resources']['layout']['layout'];
                Zend_Layout::getMvcInstance()-&gt;setLayout($layoutScript);
        }

        if (isset($config[$moduleName]['resources']['layout']['layoutPath'])) {

              $layoutPath = $config[$moduleName]['resources']['layout']['layoutPath'];
              $moduleDir = Zend_Controller_Front::getInstance()-&gt;getModuleDirectory();

              Zend_Layout::getMvcInstance()-&gt;setLayoutPath($layoutPath);
        }
    }
}</code></pre>
<p>Y a continuación añadimos a nuestro <em>Bootstrap.php</em>:</p>
<pre><code>protected function _initPlugins(){
		$this-&gt;bootstrap('frontController');

		$plugin = new My_Controller_Plugin_Layout();
		$this-&gt;frontController-&gt;registerPlugin($plugin);
	}</code></pre>
<p>Con esto lo que hacemos es que registrar el <em>plugin</em> para que sea interpretado por el <strong>Zend Framework</strong></p>
<p>Dado que he usado el <em>namespace</em> <em>My</em> necesitaré registrarlo en el fichero <em>application.ini</em> añadiendo la siguiente linea:</p>
<pre><code>autoloaderNamespaces[] = "My"</code></pre>
<p>De esta forma mi <em>application.ini</em> de la aplicación, no del módulo quedaría así:</p>
<pre><code>[production]

;First resource to load
resources.modules[] =

phpSettings.display_startup_errors 	= 0
phpSettings.display_errors = 0

includePaths.library = APPLICATION_PATH "/../library"

autoloaderNamespaces[] = "My"

bootstrap.path 	= APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"

resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"

resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
resources.layout.layout = layout

resources.view[] =
resources.view.basePath = APPLICATION_PATH "/views/"

;Modules config
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
admin.resources.layout.layoutPath = APPLICATION_PATH "/modules/admin/layouts/scripts"
admin.resources.layout.layout = layout</code></pre>
<p>Y listo, ya tenemos asignado un <em>layout</em> diferente para nuestro <em>Admin</em>. Para mejorar todo esto sería bueno que las especificaciones de cada módulo se declararán en el fichero <em>application.ini</em> de cada módulo, pero para eso necesitariamos crear un <em>Resource</em> que interpretará cada fichero por separado.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.backtheweb.com/php/zend-framework-como-hacer-un-layout-para-cada-modulo.html/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>
