<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress.com" -->
<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/"
	>

<channel>
	<title>symfony &amp;laquo; WordPress.com Tag Feed</title>
	<link>http://en.wordpress.com/tag/symfony/</link>
	<description>Feed of posts on WordPress.com tagged "symfony"</description>
	<pubDate>Sun, 29 Nov 2009 08:13:18 +0000</pubDate>

	<generator>http://en.wordpress.com/tags/</generator>
	<language>en</language>

<item>
<title><![CDATA[Pagination in symfony without criteria]]></title>
<link>http://rahuljaiswal.wordpress.com/2009/11/28/pagination-in-symfony-without-criteria/</link>
<pubDate>Sat, 28 Nov 2009 14:27:52 +0000</pubDate>
<dc:creator>jayz</dc:creator>
<guid>http://rahuljaiswal.wordpress.com/2009/11/28/pagination-in-symfony-without-criteria/</guid>
<description><![CDATA[I have created a news aggregator and needed to paginate the results. I had the &#8216;feed&#8217; ob]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I have created a news aggregator and needed to paginate the results. I had the &#8216;feed&#8217; object having an array of &#8216;feeditems&#8217; objects in my actions. So, I could not use sfPropelPager as it needs a criteria object to pull objects from the database. The solution which worked for me is presented here. Disclaimer: This is a complete rip-off from the snippets section on symfony site, modified slightly to work with the latest version of symfony and php. I will add another post to paginate in sfFeed2Plugin when I have time.</p>
<p>Add this class to lib/helper or anywhere in lib and include it in the file you need to use pagination.</p>
<p>myArrayPager.class.php</p>
<p>&#60;?php<br />
class myArrayPager extends sfPager<br />
{<br />
protected $resultsArray = null;</p>
<p>public function __construct($class = null, $maxPerPage = 10)<br />
{<br />
parent::__construct($class, $maxPerPage);<br />
}</p>
<p>public function init()<br />
{<br />
$this-&#62;setNbResults(count($this-&#62;resultsArray));</p>
<p>if (($this-&#62;getPage() == 0 &#124;&#124; $this-&#62;getMaxPerPage() == 0))<br />
{<br />
$this-&#62;setLastPage(0);<br />
} else {<br />
$this-&#62;setLastPage(ceil($this-&#62;getNbResults() / $this-&#62;getMaxPerPage()));<br />
}<br />
}</p>
<p>public function setResultArray($array)<br />
{<br />
$this-&#62;resultsArray = $array;<br />
}</p>
<p>public function getResultArray()<br />
{<br />
return $this-&#62;resultsArray;<br />
}</p>
<p>public function retrieveObject($offset) {<br />
return $this-&#62;resultsArray[$offset];<br />
}</p>
<p>public function getResults()<br />
{<br />
return array_slice($this-&#62;resultsArray, ($this-&#62;getPage() &#8211; 1) * $this-&#62;getMaxPerPage(), $this-&#62;maxPerPage);<br />
}<br />
}<br />
?&#62;</p>
<p>In the action, instead of setting an object holding array of items, set the pager. </p>
<p>		$empager = new myArrayPager(null, 10);  //10 items per page<br />
		$empager-&#62;setResultArray($this-&#62;feed-&#62;getItems());  //my object is &#8216;feed&#8217; which has &#8216;items&#8217; array<br />
		$empager-&#62;setPage($request-&#62;getParameter(&#8216;page&#8217;, 1));<br />
		$empager-&#62;init();</p>
<p>		$this-&#62;pager = $empager;</p>
<p>Implementation of view is exactly the same as with sfPropelPager or the equivalent doctrine pager.</p>
<p>Enjoy!</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Pagination without criteria in symfony, pagination in sfFeed2Plugin]]></title>
<link>http://rahuljaiswal.wordpress.com/2009/11/27/pagination-without-criteria-in-symfony-pagination-in-sffeed2plugin/</link>
<pubDate>Sat, 28 Nov 2009 03:51:36 +0000</pubDate>
<dc:creator>jayz</dc:creator>
<guid>http://rahuljaiswal.wordpress.com/2009/11/27/pagination-without-criteria-in-symfony-pagination-in-sffeed2plugin/</guid>
<description><![CDATA[I came across this situation when using sfFeed2Plugin to create a news aggregater. I had an array of]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I came across this situation when using sfFeed2Plugin to create a news aggregater. I had an array of feed objects and I needed to show the paginated results. Since I did not have any criteria object, I could not use sfPropelPager. This is what worked for me. </p>
<p>First copy the following class &#8211; myArrayPager.class.php to your lib/helper folder. This file is a direct rip-off from the snippets section of symfony. </p>
<p>setNbResults(count($this-&#62;resultsArray));</p>
<p>		if (($this-&#62;getPage() == 0 &#124;&#124; $this-&#62;getMaxPerPage() == 0))<br />
		{<br />
			$this-&#62;setLastPage(0);<br />
		}<br />
		else<br />
		{<br />
			$this-&#62;setLastPage(ceil($this-&#62;getNbResults() / $this-&#62;getMaxPerPage()));<br />
		}<br />
	}</p>
<p>	public function setResultArray($array)<br />
	{<br />
		$this-&#62;resultsArray = $array;<br />
	}</p>
<p>	public function getResultArray()<br />
	{<br />
		return $this-&#62;resultsArray;<br />
	}</p>
<p>	public function retrieveObject($offset) {<br />
		return $this-&#62;resultsArray[$offset];<br />
	}</p>
<p>	public function getResults()<br />
	{<br />
		return array_slice($this-&#62;resultsArray, ($this-&#62;getPage() &#8211; 1) * $this-&#62;getMaxPerPage(), $this-&#62;maxPerPage);<br />
	}</p>
<p>}<br />
?&#62; </p>
<p>Let&#8217;s assume we have the following array to paginate:</p>
<p>$myArray = //array of feeds or any array like array(&#8216;the first element&#8217;, &#8216;the second element&#8217;,'third one&#8217;, &#8216;fourth one&#8217;, &#8216;last one&#8217;);</p>
<p>In your action method, add the following lines to create and initiate the pager object:</p>
<p>$empager = new myArrayPager(null, sfConfig::get(&#8216;app_max_news_per_page&#8217;));  //max_news_per_page<br />
//needs to be defined in app.yml of the module<br />
$empager-&#62;setResultArray($myArray);<br />
$empager-&#62;setPage($request-&#62;getParameter(&#8216;page&#8217;, 1));<br />
$empager-&#62;init();<br />
$this-&#62;pager = $empager;</p>
<p>Note, variable myArray is set to the ResultArray of the pager. Any array can be assigned to myArray.</p>
<p>The view &#8211; showSuccess.php (assuming my action method is executeShow):</p>
<div id="news">
<h1>Latest Buzz</h1>
<p>
	 $pager));<br />
	?&#62;</p>
<p>	 &#8216;/feed/showL&#8217;, &#8216;pager&#8217; =&#62; $pager));<br />
	?&#62;</p>
<p>
</div>
<p>and the two partials:</p>
<p>_newslist.php</p>
<p>getResults() as $item): ?&#62;</p>
<div class="hr"></div>
<p>
	  <strong>getTitle()), 100), $item-&#62;getLink()) ?&#62;</strong><br />
	  getPubDate(), &#8220;EEE d MMMM yyyy&#8221;) ?&#62;<br />
	    &#124; Source: getFeed()-&#62;getTitle(), $item-&#62;getFeed()-&#62;getLink()) ?&#62;
	</p>
<div class="newsdescription">
	  	getDescription(), 800)), link_to(&#8216;&#60;&#60; More&#8217;, $item-&#62;getLink()) ;<br />
	  	?&#62;
  	</div>
<div class="clear"></div>
<p>_paginate.php</p>
<p>haveToPaginate()): ?&#62;</p>
<div class="pagination">
  	getFirstPage() == $pager-&#62;getPage()): ?&#62;<br />
  		<span class="selected">First</span></p>
<p>    	&#60;a href=&#34;?page=1&#8243;&#62;First</a></p>
<p> 	getFirstPage() == $pager-&#62;getPage()): ?&#62;<br />
    	<span class="selected">Previous</span></p>
<p>    	&#60;a href=&#34;?page=getPreviousPage() ?&#62;&#8221;&#62;Previous</a></p>
<p>    getLinks() as $page): ?&#62;<br />
      getPage()): ?&#62;<br />
        <span class="selected"></span></p>
<p>        &#60;a href=&#34;?page=&#8221;&#62;</a></p>
<p>	getLastPage() == $pager-&#62;getPage()): ?&#62;<br />
    	<span class="selected">Next</span></p>
<p>    	&#60;a href=&#34;?page=getNextPage() ?&#62;&#8221;&#62;Next</a></p>
<p> 	getLastPage() == $pager-&#62;getPage()): ?&#62;<br />
    	<span class="selected">Last</span></p>
<p>    	&#60;a href=&#34;?page=getLastPage() ?&#62;&#8221;&#62;Last</a></p></div>
<p>Pagination is generic and can be used in any code requiring pagination. Also, _newslist.php uses sfFeed2Plugin and sfWebBrowser plugins.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Como implementar Sphinx con symfony]]></title>
<link>http://sergioviteri.com/2009/11/23/como-implementar-sphinx-con-symfony/</link>
<pubDate>Mon, 23 Nov 2009 09:15:30 +0000</pubDate>
<dc:creator>Sergio Viteri</dc:creator>
<guid>http://sergioviteri.com/2009/11/23/como-implementar-sphinx-con-symfony/</guid>
<description><![CDATA[Como primera aproximación a un buscador simple en la primera versión de Voota, se nos ocurrió utiliz]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Como primera aproximación a un buscador simple en la primera versión de <a href="http://voota.es">Voota</a>, se nos ocurrió utilizar &#8220;<a href="http://www.google.com/cse/">Google custom search</a>&#8220;. Mala idea. Hoy, 5 días después de la puesta online, Google solo ha indexado 267 páginas y teniendo en cuenta que empezábamos con 1.549 políticos con sus 1.549 correspondientes fichas, los resultados no eran muy apropiados. Por ejemplo, buscando &#8220;Zapatero&#8221; aparecían varios resultados del <a href="http://blog.voota.es">blog</a>, alguna ficha de otros políticos y varios enlaces al ranking, pero <strong>no</strong> <a href="http://voota.es/es/politico/Rodr%C3%ADguez-Zapatero">la ficha del sr. presidente</a>.</p>
<p>Necesitábamos un buscador, sencillo, potente y que escalase bien con los futuros desarrollos que vienen. La solución fue mucho más fácil de lo esperado. Decidimos implementar nuestro propio motor de búsqueda con <a href="http://www.sphinxsearch.com/">Sphinx</a>. Así es como lo hicimos:</p>
<ol>
<li>Lo primero es instalar el motor de búsqueda, que básicamente consta de dos partes: El indexador, que obtiene las palabras clave de la base de datos (<a href="http://www.postgresql.org/">Postgresql</a> o <a href="http://www.mysql.com/">mysql</a>) y el demonio o servicio de búsqueda que atiende a las peticiones del servidor web.<br />
La instalación no tiene más misterio que seguir los pasos que explican en su web: <a href="http://www.sphinxsearch.com/docs/current.html">Manual de referencia de Sphinx</a>.</li>
<li>Después viene la fase de configuración. Aquí es donde se le dice a Sphinx que datos tiene que indexar para que puedan ser encontrados en el buscador del sitio web. En nuestro caso, de momento, sólo queríamos indexar los políticos:
<div style="border:1px solid black;background-color:#ccc;font-size:.8em;padding:4px;">source src1<br />
{<br />
type                                    = mysql<br />
sql_host                                = localhost<br />
sql_user                                = usuario<br />
sql_pass                                =<br />
sql_db                                  = voota<br />
sql_port                                = 3306  # optional, default is 3306<br />
sql_query_pre   = SET NAMES utf8<br />
sql_query                               = \<br />
SELECT id, vanity, alias, nombre, apellidos, bio, presentacion, residencia, formacion \<br />
FROM politico<br />
sql_ranged_throttle     = 0<br />
sql_query_info          = SELECT * FROM politico WHERE id=$id<br />
}<br />
source src1throttled : src1<br />
{<br />
sql_ranged_throttle                     = 100<br />
}<br />
index politico<br />
{<br />
source                  = src1<br />
path                    = /var/data/voota<br />
docinfo                 = extern<br />
mlock                   = 0<br />
morphology              = none<br />
min_word_len            = 1<br />
charset_type            = utf-8<br />
charset_table   = 0..9, A..Z-&#62;a..z, a..z, \<br />
U+C0-&#62;a, U+C1-&#62;a, U+C2-&#62;a, U+C3-&#62;a, \<br />
U+C4-&#62;a, U+C5-&#62;a, U+C6-&#62;a, \<br />
U+C7-&#62;c,U+E7-&#62;c, U+C8-&#62;e, U+C9-&#62;e, \<br />
U+CA-&#62;e, U+CB-&#62;e, U+CC-&#62;i, \<br />
U+CD-&#62;i, U+CE-&#62;i, U+CF-&#62;i, U+D0-&#62;d, \<br />
U+D1-&#62;n, U+D2-&#62;o, U+D3-&#62;o, \<br />
U+D4-&#62;o, U+D5-&#62;o, U+D6-&#62;o, U+D8-&#62;o, \<br />
U+D9-&#62;u, U+DA-&#62;u, U+DB-&#62;u, \<br />
U+DC-&#62;u, U+DD-&#62;y, U+DE-&#62;t, U+DF-&#62;s, \<br />
U+E0-&#62;a, U+E1-&#62;a, U+E2-&#62;a, U+E3-&#62;a, \<br />
U+E4-&#62;a, U+E5-&#62;a, U+E6-&#62;a, \<br />
U+E7-&#62;c,U+E7-&#62;c, U+E8-&#62;e, \<br />
U+E9-&#62;e, U+EA-&#62;e, U+EB-&#62;e, U+EC-&#62;i, \<br />
U+ED-&#62;i, U+EE-&#62;i, U+EF-&#62;i, \<br />
U+F0-&#62;d, U+F1-&#62;n, U+F2-&#62;o, U+F3-&#62;o, \<br />
U+F4-&#62;o, U+F5-&#62;o, U+F6-&#62;o, \<br />
U+F8-&#62;o, U+F9-&#62;u, U+FA-&#62;u, U+FB-&#62;u, \<br />
U+FC-&#62;u, U+FD-&#62;y, U+FE-&#62;t, U+FF-&#62;s,<br />
html_strip                              = 0<br />
}</div>
<p>Extracto del fichero de configuración de Sphinx</li>
<li>A continuación se arranca el servicio de búsqueda:<br />
<em>sudo searchd &#8211;config /usr/local/etc/sphinx.conf</em><br />
y se da la orden para que Sphinx realice la indexación (Esto será necesario hacerlo periódicamente):<br />
<em>sudo /usr/local/bin/indexer politico &#8211;rotate</em><br />
Muy bien, Sphinx configurado y escuchando.</li>
<li>Sólo falta escribir el código <a href="http://www.symfony-project.org/">Symfony</a> para interrogar al motor de búsqueda:
<div style="border:1px solid black;background-color:#ccc;font-size:.8em;padding:4px;">$this-&#62;q = $request-&#62;getParameter(&#8220;q&#8221;);$cl = new SphinxClient ();<br />
$cl-&#62;SetServer ( &#8216;localhost&#8217;, 3312 );<br />
$this-&#62;limit = 1000;<br />
$cl-&#62;SetLimits ( 0, $this-&#62;limit, $this-&#62;limit );<br />
$cl-&#62;SetArrayResult ( true );<br />
$this-&#62;res = $cl-&#62;Query ( SfVoUtil::stripAccents( $this-&#62;q ), &#8216;politico&#8217; );<br />
if ( $this-&#62;res!==false ) {<br />
if ( isset($this-&#62;res["matches"]) &#38;&#38; is_array($this-&#62;res["matches"]) ) {<br />
$c = new Criteria();<br />
$list = array();<br />
foreach ($this-&#62;res["matches"] as $idx =&#62; $match) {<br />
$list[] = $match['id'];<br />
}<br />
$c-&#62;add(PoliticoPeer::ID, $list, Criteria::IN);<br />
$c-&#62;addDescendingOrderByColumn(PoliticoPeer::SUMU);<br />
$this-&#62;politicosPager = new sfPropelPager(&#8216;Politico&#8217;, 10);<br />
$this-&#62;politicosPager-&#62;setCriteria($c);<br />
$this-&#62;politicosPager-&#62;setPage($this-&#62;getRequestParameter(&#8216;page&#8217;, 1));<br />
$this-&#62;politicosPager-&#62;init();if ($this-&#62;politicosPager-&#62;getNbResults() == 1){<br />
$res = $this-&#62;politicosPager-&#62;getResults();<br />
$this-&#62;redirect( &#8220;@politico_&#8221;.$this-&#62;getUser()-&#62;getCulture( &#8216;es&#8217; ).&#8221;?id=&#8221;.$res[0]-&#62;getVanity() );<br />
}<br />
}<br />
}</div>
<p>Código Symfony que realiza la búsqueda</li>
</ol>
<p>Listo, hoy puedes buscar Zapatero, José Luis Rodriguez o ZP en <a href="http://voota.es">Voota</a>, que seguro que encuentras lo que buscas, a no ser que quieras comprarte unos zapatos nuevos, claro <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Reload de la base sous Symfony 1.3 / 1.4]]></title>
<link>http://devandco.wordpress.com/2009/11/22/reload-de-la-base-sous-symfony-1-3-1-4/</link>
<pubDate>Sun, 22 Nov 2009 18:34:07 +0000</pubDate>
<dc:creator>devandco</dc:creator>
<guid>http://devandco.wordpress.com/2009/11/22/reload-de-la-base-sous-symfony-1-3-1-4/</guid>
<description><![CDATA[Vous avez créé votre modèle et souhaitez tout régénérer ? Pas de soucis vous lancez : symfony doctri]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Vous avez créé votre modèle et souhaitez tout régénérer ?<br />
Pas de soucis vous lancez :</p>
<p><strong>symfony doctrine:build-all-reload &#8211;no-confirmation</strong></p>
<p>et là &#8230;</p>
<p><span style="color:#ff0000;"><strong>Task &#8220;doctrine:build-all-reload&#8221; is not defined.</strong></span></p>
<p>Pas de soucis !&#8230;<br />
<strong>doctrine:build-all-reload</strong> est maintenant déprécié; il faut saisir :</p>
<p><strong>symfony doctrine:build &#8211;all </strong>ou<strong> symfony doctrine:build &#8211;all &#8211;and-load</strong></p>
<p>Et ça roule !</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Symfony - Fixtures con las Ciudades y Comunas de Chile]]></title>
<link>http://emartini.wordpress.com/2009/11/22/symfony-fixtures-con-las-ciudades-y-comunas-de-chile/</link>
<pubDate>Sun, 22 Nov 2009 02:12:33 +0000</pubDate>
<dc:creator>esteban.martini</dc:creator>
<guid>http://emartini.wordpress.com/2009/11/22/symfony-fixtures-con-las-ciudades-y-comunas-de-chile/</guid>
<description><![CDATA[Durante el desarrollo de nuestro proyecto para la Feria de Software tuvimos que tener algunos datos ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p style="text-align:justify;">Durante el desarrollo de nuestro proyecto para la <a title="Feria de Software UTFSM" href="http://www.feriadesoftware.cl/" target="_blank">Feria de Software</a> tuvimos que tener algunos datos de prueba para las <strong>comunas y ciudades de Chile</strong>, como no era fundamental tener las regiones simplificamos el modelo propuesto en <a title="snipplr.com - Regiones y Comunas de Chile" href="http://snipplr.com/view/525/sql--datos--regiones-y-comunas-de-chile/" target="_blank">este sitio</a> al siguiente (escrito en <a title="The Official YAML Web site" href="http://www.yaml.org/" target="_blank">notación YAML</a>)</p>
<p style="text-align:justify;">Para las <span style="text-decoration:underline;">ciudades</span>:</p>
<pre class="brush: php;">
  ciudad:
   id: ~
   nombre:      { type: varchar(100) }
</pre>
<p>Para las <span style="text-decoration:underline;">comunas</span></p>
<pre class="brush: php;">
  comuna:
   id: ~
   nombre:      { type: varchar(100) }
   ciudad_id:   { type: integer, foreignTable: ciudad, foreignReference: id, onDelete: restrict }
</pre>
<p style="text-align:justify;">Los cuales, como es de presumir, fueron agregados a nuestro <strong>esquema </strong>(./config/schema.yml)<strong>. </strong>Hasta aquí nada muy interesante, pero mientas discutíamos la forma más compleja y por ende mejor ( xD ) de cargar los datos,  <strong>Camila Maldonado</strong> se tomó la &#8216;molestia&#8217; de pasar la información directamente a un par de archivos yaml para ser cargados como <em>fixtures</em> (./data/fixtures) en nuestro proyecto. Les dejo a continuación los archivos:</p>
<p><span style="text-decoration:underline;"><span style="text-decoration:none;">Descarga</span></span>: <strong><a href="http://emartini.caccomex.cl/fixtures-chile_ciudades_comunas.zip">Fixtures symfony &#8211; Ciudades y Comunas de Chile</a> </strong>(zip &#8211; 5,5 KB)</p>
<p style="text-align:justify;">Es muy posible que falten varias comunas, pero como comenté sólo necesitábamos datos de prueba y éstos se ajustaron bastante bien: <strong>52 ciudades</strong> y <strong>345 comunas</strong> no está mal <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[[Symfony] Criteria Objek Syntax]]></title>
<link>http://catetancoding.wordpress.com/2009/11/19/symfony-criteria-objek-syntax/</link>
<pubDate>Thu, 19 Nov 2009 10:10:01 +0000</pubDate>
<dc:creator>masdabhakti</dc:creator>
<guid>http://catetancoding.wordpress.com/2009/11/19/symfony-criteria-objek-syntax/</guid>
<description><![CDATA[Catetan dikit, SQL Criteria WHERE column = value -&gt;add(column, value); WHERE column &lt;&gt; valu]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Catetan dikit,</p>
<table cellspacing="0">
<thead>
<tr>
<th>SQL</th>
<th>Criteria</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>WHERE column = value</code></td>
<td><code>-&#62;add(column, value);</code></td>
</tr>
<tr>
<td><code>WHERE column &#60;&#62; value</code></td>
<td><code>-&#62;add(column, value, Criteria::NOT_EQUAL);</code></td>
</tr>
<tr>
<td><strong>Other Comparison Operators</strong></td>
<td></td>
</tr>
<tr>
<td><code>&#62; , &#60;</code></td>
<td><code>Criteria::GREATER_THAN, Criteria::LESS_THAN</code></td>
</tr>
<tr>
<td><code>&#62;=, &#60;=</code></td>
<td><code>Criteria::GREATER_EQUAL, Criteria::LESS_EQUAL</code></td>
</tr>
<tr>
<td><code>IS NULL, IS NOT NULL</code></td>
<td><code>Criteria::ISNULL, Criteria::ISNOTNULL</code></td>
</tr>
<tr>
<td><code>LIKE, ILIKE</code></td>
<td><code>Criteria::LIKE, Criteria::ILIKE</code></td>
</tr>
<tr>
<td><code>IN, NOT IN</code></td>
<td><code>Criteria::IN, Criteria::NOT_IN</code></td>
</tr>
<tr>
<td><strong>Other SQL Keywords</strong></td>
<td></td>
</tr>
<tr>
<td><code>ORDER BY column ASC</code></td>
<td><code>-&#62;addAscendingOrderByColumn(column);</code></td>
</tr>
<tr>
<td><code>ORDER BY column DESC</code></td>
<td><code>-&#62;addDescendingOrderByColumn(column);</code></td>
</tr>
<tr>
<td><code>LIMIT limit</code></td>
<td><code>-&#62;setLimit(limit)</code></td>
</tr>
<tr>
<td><code>OFFSET offset</code></td>
<td><code>-&#62;setOffset(offset)</code></td>
</tr>
<tr>
<td><code>FROM table1, table2 WHERE table1.col1 = table2.col2</code></td>
<td><code>-&#62;addJoin(col1, col2)</code></td>
</tr>
<tr>
<td><code>FROM table1 LEFT JOIN table2 ON table1.col1 = table2.col2</code></td>
<td><code>-&#62;addJoin(col1, col2, Criteria::LEFT_JOIN)</code></td>
</tr>
<tr>
<td><code>FROM table1 RIGHT JOIN table2 ON table1.col1 = table2.col2</code></td>
<td><code>-&#62;addJoin(col1, col2, Criteria::RIGHT_JOIN)</code></td>
</tr>
</tbody>
</table>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Symfony - primele impresii]]></title>
<link>http://acrudulceag.wordpress.com/2009/11/16/symfony-primele-impresii/</link>
<pubDate>Mon, 16 Nov 2009 18:03:01 +0000</pubDate>
<dc:creator>adormitu</dc:creator>
<guid>http://acrudulceag.wordpress.com/2009/11/16/symfony-primele-impresii/</guid>
<description><![CDATA[In aceasta perioada trec printr-un stagiu de acomodare cu frameworkul Symfony, iar primele impresii ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>In aceasta perioada trec printr-un stagiu de acomodare cu frameworkul Symfony, iar primele impresii nu sunt deloc placute.</p>
<p>Primul lucru peste care dai indata ce incepi sa studiezi Symfonyul este modul in care acesta stocheaza setarile, si anume in format YAML. Acest lucru prezinta overhead in citirea configurarilor, si nu pot intelege de ce fisiere de configurare PHP nu sunt de ajuns. Overheadul nu pot zice cat este de mare, dar nevoia de a invata modul de folosire al YAML in cadrul Symfony e mult mai putin decat intuitiv. Asta nu in cazul celor evidente, pe cat in cazul definirii structurilor tabelelor (si nici in documentatie nu am gasit exact cum sa descriu anumite coloane de sql, a trebuit sa recurg la google pentru asta).</p>
<p>Daca ziceam ca se foloseste intensiv YAML, nu va speriati, aveti la dispozitie si XML, doar pentru definirea tabelelor. Si ca suntem cu vorba la definirea tabelelor, sa stiti ca acel YAML/XML este convertit in syntaxa SQL si rulat. <em>Asta e cu siguranta cel mai bun lucru pe care l-au putut realiza</em>.</p>
<p>Un alt aspect care din fazele incipiente pare &#8220;enervant&#8221; consta in trecerea constanta la console si la rularea unor serii de comenzi pentru fiecare modul, modificare db, configurare in parte. Si sa nu uitam de modul dezordonat in care parametrii acestuia se prezinta; pentru unele optiuni avand variante scurte, iar pentru majoritatea nu.</p>
<p>SVN aruncat de umplutura in documentatie.</p>
<p>Ce este <code>Criteria()</code>? Da, stiu ca este folosit pentru criterile de cautare in baza de date, dar in documentatie nu apare.</p>
<p>Modelul MVC implementat e supra-gandit. Sapte fisiere pentru generarea de pagini. Se vede ca sistemul de templateting a fost gandit de programatori mai vechi. Si termenii sunt aiurea: layout, template, fragment. Unde parca template nu e acelasi lucru cu fragment.</p>
<p>Tranzactiile sunt database independent, adica sunt facute din partea de PHP. Poate doar mie mi se pare acest lucru ciudat. De asemenea frameworkul e gandit astfel ca el la treceri db sa fie functional fara modificari de setari la db. Si acum ma gandesc, la un proiect de cate ori schimbi baza de date? Cel mai probabil niciodata.</p>
<p><a href="http://www.symfony-project.org/api/1_0/FormHelper">Helperul de formuri</a> nu mi se pare atat de bine gandit, precum nici validarea. Din nou YAML, in loc sa foloseasca un model precum <a href="http://codeigniter.com/user_guide/libraries/form_validation.html">cel de la CodeIgniter</a> (desigur si el ar putea fi imbunatatit, dar e un pas spre bine).</p>
<p>Folosinta excesiva de setter/getter pattern devine enervanta la un moment dat mai ales datorita numelor foarte lungi ale metodelor.</p>
<pre>
$this-&#62;getRequest()-&#62;getParameterHolder()-&#62;get($name)
// si varianta "scurta"
$this-&#62;getRequestParameter($name)
</pre>
<p>Pana acum nu a fost o experienta foarte placuta, iar aceste ganduri &#8220;negre&#8221; mi s-au format dupa doar o zi de utilizare. Poate a fost scris putin in graba caci vroiam sa zic cele enumerate inainte sa imi iasa din minte.</p>
<p>Cat despre cele placute in framework, singurul lucru care ma atras a fost scaffoldingul pus la dispozitie, eficace si simplu.</p>
<p>Cat despre faptul ca tutorialele acestora merg pe metodologia XP (Extreme Programming) nu a putut sa faca altceva decat sa ma irite si mai tare. Scrie intai, regandeste dupa.</p>
<p>Pana acum, doar eficace nu e termenul care sa imi vina in minte cand ma gandesc la Symfony.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Symfony 2.0]]></title>
<link>http://raulbarraltamayo.wordpress.com/2009/11/16/symfony-2-0/</link>
<pubDate>Sun, 15 Nov 2009 22:05:58 +0000</pubDate>
<dc:creator>raulbarraltamayo</dc:creator>
<guid>http://raulbarraltamayo.wordpress.com/2009/11/16/symfony-2-0/</guid>
<description><![CDATA[raul]]></description>
<content:encoded><![CDATA[raul]]></content:encoded>
</item>
<item>
<title><![CDATA[Symfony - Validador de RUT]]></title>
<link>http://emartini.wordpress.com/2009/11/14/symfony-validador-de-rut/</link>
<pubDate>Sat, 14 Nov 2009 15:33:17 +0000</pubDate>
<dc:creator>esteban.martini</dc:creator>
<guid>http://emartini.wordpress.com/2009/11/14/symfony-validador-de-rut/</guid>
<description><![CDATA[Utilizando la clase para validar RUT que mostré en esta entrada cree un sencillo validador de RUT pa]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p style="text-align:justify;">Utilizando la clase para validar RUT que <a title="Clase para validar RUT en PHP" href="http://emartini.wordpress.com/2009/11/14/clase-para-validar-rut-en-php/" target="_blank">mostré en esta entrada</a> cree un sencillo validador de RUT para los formulario de <em><strong>symfony 1.2</strong></em></p>
<p style="text-align:justify;">Por convención he creado la clase <strong>sfValidatorRut.class.php</strong> en el directorio <strong>/lib</strong> de la raíz del proyecto. Aquí está el código de esta clase:</p>
<p>
<pre class="brush: php;">
&#60;?php
/**
 * Validador de RUT para symfony 1.2
 *
 * @author Esteban Martini Muñoz
 * @version 1.0
 */
require_once dirname(__FILE__).'/../Rut.class.php';
class sfValidatorRut extends sfValidatorString
{
  public function configure ($options = array(), $messages = array())
  {
    $this-&#62;addMessage('invalid', 'El formato del RUT: %value% no es válido.');
    $this-&#62;addMessage('bad_dv', 'El dígito verificador del RUT es incorrecto.');
    $this-&#62;addMessage('required', 'RUT es requerido.');
  }
  public function doClean($value)
  {
      $clean = ltrim(rtrim(($value)));
      $rut = new Rut();
      if (!$rut-&#62;verificaFormatoRut($value))
        throw new sfValidatorError($this, 'invalid', array('value' =&#62; $value));
      else if(!$rut-&#62;isRut($value))
        throw new sfValidatorError($this, 'bad_dv', array('value' =&#62; $rut-&#62;getDV($value)));
      return (string)$rut-&#62;formatoUser($value);
  }
}
</pre>
<p style="text-align:justify;">Su uso es igual al resto de los <a href="http://www.symfony-project.org/book/1_2/10-Forms#chapter_10_form_validation">validadores de symfony</a> sólo basta asignar el tipo de validación al campo a verificar de nuestro formulario.</p>
<pre class="brush: php;">
//...
public function configure()
{
  $this-&#62;validatorSchema['rut_usuario'] = new sfValidatorRut();
}
//...
</pre>
<p>Espero les sea de utilidad.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Starting : PHP Framework Symfony]]></title>
<link>http://catetancoding.wordpress.com/2009/11/13/starting-php-framework-symfony/</link>
<pubDate>Fri, 13 Nov 2009 06:31:40 +0000</pubDate>
<dc:creator>masdabhakti</dc:creator>
<guid>http://catetancoding.wordpress.com/2009/11/13/starting-php-framework-symfony/</guid>
<description><![CDATA[Jangan tanya gw tentang deskripsi formalnya. Gw penulis code yang berasaskan best practice dengan ko]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><img class="alignnone" src="http://www.symfony-project.org/images/symfony_logo.gif" alt="" width="176" height="37" /></p>
<p>Jangan tanya gw tentang deskripsi formalnya. Gw penulis code yang berasaskan best practice dengan konsep seperlunya. Ketika koding sudah efektif dari segi algoritma, memori, dan run time nya, maka cukup sudah. Coding lama2  menyebabkan penggunaan dosis caffein dan nikotin meningkat.  Gak Sehat. *malah curhat*</p>
<p>Jadi, setelah cukup lama membangun aplikasi web deingan  Code Igniter (CI), sekarang gw dilibatkan dengan aplikasi yang  menggunakan php framework Symfony. Seberapa jauh bedanya??? beda banged.</p>
<p>Symfony dikembangkan sampe versi 1.3 . Beda ama CI yang sekarang udah ampe 1.7. Bukan berarti Symfony ga da perkembangan, ato kurang komunitasnya. Justru sejak awal dibangun, Symfony udah sangat direncanakan dengan konsep yang matang. Jadi, baik frameworknya, dokumentasinya,  dan  dukungan third party libraries-nya bisa dibilang lengkap dan stabil.</p>
<p>What next? pertamakali, cari tahu makhluk apa ini di site resminya : <a href="http://www.symfony-project.org/">http://www.symfony-project.org/</a> .  Learning curve-nya lumayan berat, so just move on, slowly but sure.</p>
<p>Fundamental things that you have to know sebelum akhirnya masuk lebih jauh ke symfony, ga perlu tau detil,  setidaknya cukup mengenal, antara lain :</p>
<p><img class="alignnone" src="http://farm1.static.flickr.com/146/382637881_0902bd880f.jpg" alt="" width="500" height="297" /></p>
<p>1. PHP 5.  Symfony dibangun diatas PHP 5. Dapat dipastikan berbau bau object, class, dsb.</p>
<p>2. OOP. Relasinya jelas dari point 1. Akan lebih sering menulis  code &#8220;tanda panah&#8221; disini <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>3. ORM (Object Relational Mapping). Singkat kata, ini merupakan metode pemetaan objek database menjadi objek class, sehingga kelak apapun database yg digunakan, ga jadi masalah. Dalam hal ini, ORM yang digunakan bisa Propel, atau Doctrine.</p>
<p>4. YAML. Semacam XML but with a much simpler syntax. Scripting language yang vital dan banyak ditemukan di symfony. Script ini nantinya akan meng&#8217;generate&#8217;/parsing menjadi script php yang gak perlu lagi dicoding oleh programmernya.</p>
<p>5. MVC Pattern. Model, View, Controller. Bla bla bla <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><img class="alignnone" src="http://ksojkotech.files.wordpress.com/2009/08/2234652286_0fd1b3bd9f1.jpg?w=500&#038;h=352#38;h=352" alt="" width="500" height="352" /></p>
<p>Ada yang bilang, framework symfony adalah awalan yang baik untuk belajar framework di PHP. Kenapa? ga tau juga, gw baru mulai. Mungkin karena saking kompleksnya framework ini, sehingga kalo ini dikuasai, maka penguasaan framework lain akan lebih mudah. Setidaknya sebelumnya gw udah buktiin kalo CI itu mudah. Lightweight banged ^^ Kita buktikan saja.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Bughuntday - Symfony Project]]></title>
<link>http://avdg.wordpress.com/2009/11/07/bughuntday-symfony-project/</link>
<pubDate>Sat, 07 Nov 2009 21:18:31 +0000</pubDate>
<dc:creator>avdg</dc:creator>
<guid>http://avdg.wordpress.com/2009/11/07/bughuntday-symfony-project/</guid>
<description><![CDATA[Intussen beginnen de 2 laatste maanden van het jaar. Exact 1 jaar geleden was er de eerste succesvol]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Intussen beginnen de 2 laatste maanden van het jaar. Exact 1 jaar geleden was er de eerste succesvolle Zend Frameworks bughuntday. Volgende week komt een vervolg aan. Deze keer wordt er niet gesleuteld aan Zend Frameworks, nee. Het is nu de beurt van Symfony. Wat mij betreft, zal het eerder een grondige kennismaking worden. Ik zou blij zijn moest ik 1 bugje oplossen <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Mensen die geïnteresseerd zijn, meer info vind je op de site van <a title="Info over bughuntday symfony op 14/11/08" href="http://www.phpbenelux.eu/en/symfonyBugHuntDay">phpbenelux</a>. Vergeet je wel <a href="http://www.phpbenelux.eu/en/bhdregistration">niet in te schrijven</a>.</p>
<p>Eventjes iets ander: eventjes terug naar mijn opleiding. Die is bijna volledig af en zelf heb ik al een deadline vooropgesteld die op eind december ligt. Een <span style="text-decoration:line-through;">ruime</span>goede deadline voor mij en tijd genoeg om optionele delen te doen. Van tijd gesproken, deze week heb ik zowat geen les. En toch ben ik bezig met 3(!) dingen tegelijkertijd bezig. Daarbovenop komt mijn simpele site (eindelijk) en ben ik bezig met mijn stage (logischerwijs begin 2010) te regelen.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[sfForm and Symfony 1.0.x]]></title>
<link>http://nibsirahsieu.wordpress.com/2009/11/06/sfform-and-symfony-1-0-x/</link>
<pubDate>Thu, 05 Nov 2009 21:19:02 +0000</pubDate>
<dc:creator>nibsirahsieu</dc:creator>
<guid>http://nibsirahsieu.wordpress.com/2009/11/06/sfform-and-symfony-1-0-x/</guid>
<description><![CDATA[sfFrom was introduced since symfony 1.1, and has been improved in symfony 1.2 &gt;. Can we use this ]]></description>
<content:encoded><![CDATA[sfFrom was introduced since symfony 1.1, and has been improved in symfony 1.2 &gt;. Can we use this ]]></content:encoded>
</item>
<item>
<title><![CDATA[Smart paging for an array of elements using sfPropelCustomJoinHelper]]></title>
<link>http://nibsirahsieu.wordpress.com/2009/11/04/smart-paging-for-an-array-of-elements-using-sfpropelcustomjoinhelper/</link>
<pubDate>Wed, 04 Nov 2009 02:28:51 +0000</pubDate>
<dc:creator>nibsirahsieu</dc:creator>
<guid>http://nibsirahsieu.wordpress.com/2009/11/04/smart-paging-for-an-array-of-elements-using-sfpropelcustomjoinhelper/</guid>
<description><![CDATA[Say, you want to create a paging from a query. For some reasons, you do not want to select all the f]]></description>
<content:encoded><![CDATA[Say, you want to create a paging from a query. For some reasons, you do not want to select all the f]]></content:encoded>
</item>
<item>
<title><![CDATA[Ruby et Rails ou bien PHP et Symfony ?]]></title>
<link>http://jeremy.wordpress.com/2009/11/03/ruby-et-rails-ou-bien-php-et-symfony/</link>
<pubDate>Tue, 03 Nov 2009 08:00:02 +0000</pubDate>
<dc:creator>Jérémy Lecour</dc:creator>
<guid>http://jeremy.wordpress.com/2009/11/03/ruby-et-rails-ou-bien-php-et-symfony/</guid>
<description><![CDATA[Dans le cadre de mon travail chez Autrement, je bosse principalement sur du développement web en Rub]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Dans le cadre de mon travail chez <a href="http://autrementleblog.com/" target="_blank"><strong>Autrement</strong></a>, je bosse principalement sur du développement web en Ruby, avec l&#8217;aide du framework <strong>Ruby on Rails</strong>.</p>
<p>Je suis focalisé sur le développement d&#8217;une appli web (encore un eu secrète pour le moment), mais là, Autrement édite par ailleurs le site web <a href="http://chambresapart.fr/" target="_blank">chambresapart.fr</a><br />
Le développement de ce site a commencé bien avant que je rejoigne l&#8217;équipe et il s&#8217;appuie sur le framework <strong>Symfony</strong>, basé sur <strong>PHP</strong>.</p>
<p>Actuellement l&#8217;équipe <strong>Chambres à Part</strong> se compose de 2,5 personnes qui sont toutes les 3 des développeurs confirmés, spécialisés sur <strong>PHP</strong> / <strong>Symfony</strong>.</p>
<p>Avant le lancement de la &#8220;version 1&#8243; de Chambres à Part, j&#8217;ai participé au développement de certaines fonctionnalités, mais principalement sur des aspects HTML, CSS, Javascript, cartographie Google + <a href="http://maptimize.com" target="_blank">Maptimize</a>, …<br />
La dernière semaine a été uniquement consacrée à du debuggage et pour ça j&#8217;ai mis un peu plus mon nez dans le code source du site et donc dans la partie &#8220;vue&#8221; (le V de <abbr title="Model-View-Controller">MVC</abbr>).</p>
<p>Je ne peux surtout pas prétendre connaître Symfony dans ce qu&#8217;il a de particulier par rapport à d&#8217;autres framework web (et MVC en particulier), mais je peux comparer ce que j&#8217;ai vu et ce que l&#8217;équipe raconte au quotidien avec ce que je connais et vis au quotidien depuis 3 ans avec Ruby et Rails.</p>
<p>De plus, j&#8217;ai développé quasi-exclusivement en PHP depuis les premiers temps du PHP3 jusqu&#8217;à PHP5, donc même si j&#8217;ai passablement oublié certains réflexes de manipulation du langage et la plupart de noms de méthodes, je pense avoir un avis assez circonstancié sur PHP.</p>
<h2>La question</h2>
<p>Pour le développement de la partie visible du projet sur lequel je suis mobilisé, d&#8217;autres personnes de l&#8217;équipe vont participer activement et durablement. Une question se pose donc inévitablement : <strong>Ruby on Rails ou bien Symfony ?</strong></p>
<p>Notre boss comprend bien quand on lui parle de technique, avec des arguments clairs, mais il ne se sent pas (à raison) en mesure de décider lui-même d&#8217;un framework ou d&#8217;un langage plutôt qu&#8217;un autre. Il nous a donc demandé de préparer une discussion sur cette question, en apportant surtout des faits et des remarques objectives afin de tout mettre sur la table et tenter en équipe de prendre la bonne décision.</p>
<p>Je suis convaincu qu&#8217;il ne s&#8217;agit pas de valider ou invalider les choix des uns et des autres, mais plutôt de faire un état des lieux et s&#8217;orienter dans la meilleure décision.</p>
<p>Comme je suis quelqu&#8217;un de passionné, et qui ne se lance dans les choses qu&#8217;avec une forte conviction, j&#8217;ai quand même envie de convaincre que mon choix de quitter le développement en PHP pour le faire en Ruby n&#8217;est pas juste &#8220;mon choix&#8221; mais un choix lucide et cohérent.</p>
<p>Alors j&#8217;ai sorti un bout de papier et un crayon (ou plutôt un document &#8220;untitled.txt&#8221; et mon beau clavier) pour pondre une liste d&#8217;arguments.</p>
<p>Et puis je me suis dit que garder tout ça pour nous, en interne, était un peu égoïste. Pourquoi ne pas partager mes observations et mon analyse. Je ne pense pas que quiconque (au delà de notre équipe et mes copains geeks) s&#8217;intéresse à <em>mon</em> avis sur la question, mais <em>un</em> avis, ça peut donner des idées, participer à une réflexion, …</p>
<h2>Présentation factuelle de Ruby et Rails</h2>
<p>Ici je ne présente que des points clés, du moins ceux auxquels j&#8217;ai pensé.<br />
Je ne détaillerai pas ces points, d&#8217;autres l&#8217;ont fait bien mieux que moi.</p>
<h3>Ruby</h3>
<ul>
<li>100% objet, pas de primitives</li>
<li>langage concis et lisible : moins de code, moins de bugs</li>
<li>langage dynamique, <a href="http://en.wikipedia.org/wiki/Strongly_typed_programming_language" target="_blank">fortement typé</a></li>
<li>imprégné des méthodes de tests <a href="http://en.wikipedia.org/wiki/Test-driven_development" target="_blank"><abbr title="Test-Driven Development">TDD</abbr></a> et <a href="http://en.wikipedia.org/wiki/Behavior_Driven_Development" target="_blank"><abbr title="Behavior-Driven Development">BDD</abbr></a> (nombreux frameworks disponibles)</li>
<li>synergie avec les méthodes agiles</li>
<li>Ruby en ligne de commande (IRB), pratique pour des essais, …</li>
<li><a href="http://en.wikipedia.org/wiki/Rubygems" target="_blank">Rubygems</a> : gestionnaire de paquets additionnels</li>
<li>vitesse d&#8217;apprentissage</li>
<li>syntaxe et idiomes riches et avancés</li>
<li>meta-programmation</li>
<li>inspiré des meilleurs langages reconnus : Smalltalk, Lisp, Python, Perl, …</li>
<li>forte implication et marques de confiance des ténors : IBM, Sun, Apple, Microsoft, SAP, …</li>
<li>de nombreux frameworks de premier plan : Rails, Sinatra, …</li>
</ul>
<p>J&#8217;invite à la lecture de la <a href="http://en.wikipedia.org/wiki/Ruby_(programming_language)" target="_blank">page de Ruby sur Wikipedia</a>, que je trouve assez complète et claire.</p>
<h3>Rails</h3>
<ul>
<li>dédié au développement d&#8217;appli web</li>
<li>architecture <a href="http://en.wikipedia.org/wiki/Model–view–controller" target="_blank"><abbr title="Model-View-Controller">MVC</abbr></a></li>
<li>naturellement <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer" target="_blank"><abbr title="REpresentational State Transfer">REST</abbr></a></li>
<li>forte incitation à <a href="http://en.wikipedia.org/wiki/DRY" target="_blank"><abbr title="Don't Repeat Yourself">DRY</abbr></a></li>
<li>convention plutôt que configuration</li>
<li>grand variété de helpers</li>
<li>des outils annexes très utiles : débuggage, déploiement, monitoring, …</li>
<li>des environnements d&#8217;exécution bien définis et cloisonnés</li>
<li>WebServices-friendly</li>
<li>système strict de migration des bases de données</li>
<li>framework complet accessible en ligne de commande</li>
<li>variété de backend pour le cache et les sessions : mémoire, fichiers, BDD, memcached, …</li>
<li>I18n</li>
<li>communauté très active</li>
<li>documentation riche (en ligne, livres, …)</li>
<li><a href="http://en.wikipedia.org/wiki/Rack_(web_server_interface)" target="_blank">Rack</a> middlewares =&#62; empilement de briques fonctionnelles dédiées et modulaires : cache, debug, auth, …</li>
<li>logging avancé et personnalisable</li>
<li>fortes opinions, mais autres choix possibles : ORM, templates, framework JS, …</li>
</ul>
<p>Pour une introduction à Rails, je vous renvoie vers le <a href="http://guides.rubyonrails.org/getting_started.html" target="_blank">le guide de démarrage pour Rails</a> ou <a href="http://rails-nutshell.labs.oreilly.com/" target="_blank">Rails in a Nutshell</a> (qui est encore en beta).</p>
<h2>Analyse subjective (mais convaincue) de Ruby &#38; Rails vs. PHP &#38; Symfony</h2>
<p>Là, je sors un peu des faits indéniables pour m&#8217;aventurer dans ma propre analyse des différences entre ces 2 frameworks (et leur langage sous-jacent respectif). Cette analyse est forcément subjective et je serai ravi d&#8217;entendre des avis contraires ou complémentaires.</p>
<h3>PHP vs. Ruby</h3>
<p>Prenons la métaphore de la caisse à outils.</p>
<p><strong>PHP</strong> est une énorme caisse, dans laquelle il y a des outils pour presque tout, tellement que ça devient difficile de tout connaître. Il n&#8217;y a qu&#8217;à voir le site de la documentation officielle où le nombre de méthodes est impressionnant, sans parler de celles des librairies standards.</p>
<p>Il y a souvent plusieurs outils ou variantes pour faire presque la même chose. C&#8217;est pas forcément facile de savoir lequel choisir.</p>
<p>Cette boîte grandi très vite, il y a régulièrement de nouveaux outils, d&#8217;autres évoluent et certains disparaissent.</p>
<p><strong>Ruby</strong> est une caisse beaucoup plus modeste, qui permet de faire tout autant de chose, mais il y a très peu de doublons ou recoupements.</p>
<p>Les outils sont robustes, stables et surtout cohérents entre eux. Le contenu de la boîte évolue peu, rarement et uniquement en cas de forte nécessité. Même entre les versions majeures (1.8 et 1.9) il y a très forte compatibilité. Au sein de la branche 1.8 il n&#8217;y a eu presqu&#8217;aucune perte de compatibilité importante depuis plus de 3 ans (sortie de la 1.8.5 en août 2006).</p>
<p>Les mises à jour de <strong>Ruby</strong>, en tant que langage, sont rares (12 à 18 mois entre chaque version stable) car il n&#8217;y a pas ou extrêmement peu de bugs, elles ne concernent que des nouveautés ou améliorations de fond. La raison de ce très faible nombre de bugs et failles de sécurité sont simples : le code est soumis à des tests systématiques et poussés (c&#8217;est dans la culture de la communauté Ruby) et le code étant simple lisible et clair, il est facile de l&#8217;auditer et le comprendre et donc d&#8217;en débusquer les failles.</p>
<p>À l&#8217;inverse, <strong>PHP</strong> est mis à jour beaucoup plus souvent (plusieurs fois par an) et contient de nombreux correctifs de bugs en plus de nouvelles fonctionnalités. Il est reconnu que les failles de sécurité importantes ou critiques sont relativement fréquentes.</p>
<p>La raison d&#8217;être de PHP n&#8217;était pas d&#8217;apporter une approche nouvelle du développement mais de répondre à un besoin simple et bien identifié : traiter les données issues d&#8217;un formulaire web. La simplicité et les fonctionnalités de ce nouveau langage l&#8217;ont rendu rapidement populaire chez les développeurs web car il n&#8217;y avait plus besoin de faire des CGI en Perl pour rendre des sites dynamiques.</p>
<p>Face à ce gain de popularité, le langage a grandi et permis de faire de plus en plus de choses assez facilement, mais rapidement on a constaté le manque de fondations solides, en particulier sur l&#8217;aspect Objet.</p>
<p>PHP rivalise alors, en terme de popularité et d&#8217;audience, avec Perl, Java, … et cherche alors à combler les manques et répondre aux critiques. Le résultat est plutôt efficace, mais les outils du début restent là et les mauvaises pratiques qui vont avec aussi.</p>
<p>Au final on a un langage riche, mais brouillon, fourre-tout, qui évolue par stratification et pas par transformation. Les fondations manquent de rigueur et de profondeur.</p>
<p>Ruby est un langage qui a été conçu avec une approche plus scientifique et globale. Son créateur voulait un langage moderne, plus proche des attentes de l&#8217;humain que de celles de la machine, mais qui reconnaisse et embrasse l&#8217;état de l&#8217;art, ce qui s&#8217;est fait de mieux. Il s&#8217;est donc contenté (si on peut dire) d&#8217;appliquer la parole des vieux sages dans un contexte moderne.</p>
<p>Ruby adopte le principe de la moindre surprise (au sens de la cohérence maximale) selon lequel le langage doit se comporter de manière à minimiser la confusion. Lorsqu&#8217;on découvre Ruby, qu&#8217;on vienne de Java, PHP ou Python, on est forcément surpris par la syntaxe, les idiomes, … mais avec le temps on adopte la &#8220;manière Ruby&#8221; et plus rien n&#8217;étonne. Dans d&#8217;autres langages, même après plusieurs années d&#8217;utilisation, on est parfois étonné ou dérouté par certains fonctionnements.</p>
<p>La syntaxe du langage est au service de son utilisateur, en favorisant la lisibilité et la concision. La simplicité des outils de base permet d&#8217;apprendre vite et de savoir rapidement lequel utiliser.</p>
<p>Ruby est bâti sur des fondations robustes et très strictes ; celles du tout Objet (il n&#8217;y a pas de primitives), de la meta-programmation, du typage dynamique mais fort, …</p>
<h3>Symfony vs. Rails</h3>
<p><strong>Ruby on Rails</strong> est issu du développement d&#8217;une application web (Basecamp). Son créateur voulait se lancer dans le développement web et a cherché le langage avec lequel il se sentait le plus à l&#8217;aise et il s&#8217;est arrêté sur Ruby. Il a ensuite échafaudé un framework dédié au web en tirant réellement parti de ce que permet Ruby.</p>
<p>La démarche partait d&#8217;un objectif/besoin connu, il fallait trouver l&#8217;outil adapté pour l&#8217;atteindre.</p>
<p><strong>Rails ne serait pas ce qu&#8217;il est sans Ruby</strong>. On ne peut pas recréer Rails sur un autre langage sans faire des tours de passe-passe et en perdre l&#8217;essence.</p>
<p><strong>Symfony</strong> est issu du manque de bon framework web en PHP. Son créateur a voulu reprendre les bonnes idées d&#8217;autres frameworks (surtout Rails) sur d&#8217;autres langages pour les adapter sur PHP.</p>
<p>La démarche semble différente et partir d&#8217;un langage connu sur lequel construire en s&#8217;inspirant de références.</p>
<p>Pour ce que j&#8217;ai pu en voir et pour que Symfony ait le succès qu&#8217;il a, son développeur principal et la communauté qu&#8217;il a agrégée ont forcément accompli quelque chose de remarquable.</p>
<p>Pour autant, j&#8217;ai le sentiment que <strong>le plus grand handicap de Symfony, c&#8217;est PHP</strong>.</p>
<h2>Conclusion</h2>
<p>Au final, on sent que j&#8217;ai les idées bien arrêtées. J&#8217;espère ne pas avoir faire preuve de mauvaise foi ni avoir dit trop de bêtises.</p>
<p>Il m&#8217;arrive de dire que telle techno ou tel produit sont nuls. Mais pour le cas de PHP (et donc de Symfony), je ne dis pas que c&#8217;est nul et bon aux orties, au contraire.</p>
<p>Je dois certainement mon parcours de développeur web à PHP et à ce que j&#8217;ai pu faire avec. J&#8217;ai juste l&#8217;intime conviction d&#8217;avoir trouvé une évolution, une suite, qui me permet d&#8217;aller plus vite, plus loin, avec plus de plaisir/passion.</p>
<p>C&#8217;est un peu comme de passer de CVS ou Subversion à Git ou Mercurial. Vu de loin c&#8217;est la même chose, mais de près, ce sont 2 générations d&#8217;outils sui marquent un véritable progrès.</p>
<p>&#160;</p>
<hr />
<p>&#160;</p>
<p><strong>Mise à jour 1</strong> : Au terme d&#8217;une longue réunion d&#8217;équipe, nous avons choisi une approche à 2 têtes. Le premier projet (<a href="http://www.chambresapart.fr/">Chambres à Part</a>) reste évidemment développé avec Symfony (donc en PHP) mais le second sera entièrement développé avec Ruby on Rails.</p>
<p>Évidemment, je pense que c&#8217;est le bon choix. Pour moi, c&#8217;est surtout le bon choix technologique, pour toutes les raisons que j&#8217;ai déjà développées plus haut.</p>
<p>Du point de vue de la stratégie d&#8217;entreprise, je trouve que la prise de risque est modérée et ça va nous mettre dans une situation de réelle fusion et enrichissement des compétences.</p>
<p>Pendant les prochains mois, ceux parmi nous qui &#8220;viennent de Symfony&#8221; vont devoir apprendre de nouvelles choses en mettant à profit leurs années d&#8217;expérience en développement et particulièrement avec un framework MVC, … Le challenge sera de tirer le plus profit de cette expérience proche tout en &#8220;embrassant&#8221; les particularités de Ruby et de Rails.</p>
<p>Quelque part, ça va me mettre en situation de formateur, ce qui est très excitant mais aussi une responsabilité forte. Mais comme je suis absolument passionné par ce que je fais et connais, je vais me régaler dans cette partie de mon boulot.</p>
<p>Par ailleurs, cette juxtaposition d&#8217;outils va me permettre de voir plus en détail l&#8217;univers de Symfony et les évolutions de PHP (depuis que je l&#8217;ai laissé de côté). Même si je ne vois pas mon avenir de ce côté là, ça me forcera à être un peu moins monocorde.</p>
<p>Enfin bon, je suis bien content que la balance ait penché, non pas de <em>mon côté</em> (ça serait une marque d&#8217;égo) mais du <em>côté que j&#8217;ai choisi.</em></p>
<p><em><strong><span style="font-style:normal;">Mise à jour 2</span></strong><span style="font-style:normal;"> : Vous trouverez sur </span><a href="http://www.ruby-lang.org/fr/documentation/ruby-from-other-languages/to-ruby-from-php/"><span style="font-style:normal;">le site de Ruby</span></a><span style="font-style:normal;"> une courte liste des similitudes et différences à quoi s&#8217;attendre en passant de PHP à Ruby.</span></em></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[PHP on IIS]]></title>
<link>http://andresvillenas.wordpress.com/2009/11/02/php-on-iis/</link>
<pubDate>Tue, 03 Nov 2009 00:00:20 +0000</pubDate>
<dc:creator>Andrés A.  Villenas</dc:creator>
<guid>http://andresvillenas.wordpress.com/2009/11/02/php-on-iis/</guid>
<description><![CDATA[Saludos amigos y amigas. Algunas personas me han preguntado si se puede instalarle directamente PHP ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Saludos amigos y amigas.</p>
<p>Algunas personas me han preguntado si se puede instalarle directamente PHP sobre el Internet Information Services, bueno, entonces me decidi en hacer un pequeño video de como se la realiza. Realmente es muy facil pero hay que tener ciertas consideraciones sobre todo en lo que ha configuración se refiere.</p>
<p>Con todo aqui se los dejo.</p>
<p><span style='text-align:center; display: block;'><object width='425' height='350'><param name='movie' value='http://www.youtube.com/v/dsIqMCBC_Hc&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;hd=0' /><param name='allowfullscreen' value='true' /><param name='wmode' value='transparent' /><embed src='http://www.youtube.com/v/dsIqMCBC_Hc&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;hd=0' type='application/x-shockwave-flash' allowfullscreen='true' width='425' height='350' wmode='transparent'></embed></object></span></p>
<p>para ciertos temas que me han interesado como  y Symfony (Php Framework), LINQ, Entity Framework. El video fue realizado en la misma máquina de mi anterior blog.</p>
<p>Andrés A. Villenas.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[How to make sfPropelCustomJoinHelper work with propel1.3?]]></title>
<link>http://nibsirahsieu.wordpress.com/2009/11/03/how-to-make-sfpropelcustomjoinhelper-work-with-propel1-3/</link>
<pubDate>Mon, 02 Nov 2009 18:31:29 +0000</pubDate>
<dc:creator>nibsirahsieu</dc:creator>
<guid>http://nibsirahsieu.wordpress.com/2009/11/03/how-to-make-sfpropelcustomjoinhelper-work-with-propel1-3/</guid>
<description><![CDATA[sfPropelCustomJoinHelper is one of my favorite classes.. It&#8217;s saved me from writing headache p]]></description>
<content:encoded><![CDATA[sfPropelCustomJoinHelper is one of my favorite classes.. It&#8217;s saved me from writing headache p]]></content:encoded>
</item>
<item>
<title><![CDATA[Ordenar cadenas de texto que contengan números en MySQL y Symfony]]></title>
<link>http://emartini.wordpress.com/2009/11/02/ordenar-cadenas-de-texto-que-contengan-numeros-en-mysql-y-symfony/</link>
<pubDate>Mon, 02 Nov 2009 16:43:59 +0000</pubDate>
<dc:creator>esteban.martini</dc:creator>
<guid>http://emartini.wordpress.com/2009/11/02/ordenar-cadenas-de-texto-que-contengan-numeros-en-mysql-y-symfony/</guid>
<description><![CDATA[En un proyecto reciente, tuve que ordenar una columna que contenía RUN, estas cadenas tienen entre 7]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p style="text-align:justify;">En un proyecto reciente, tuve que ordenar una columna que contenía <a href="http://es.wikipedia.org/wiki/Rol_Único_Nacional">RUN</a>, estas cadenas tienen entre 7 y 8 números enteros y un dígito verificador que puede ser un número entre 0-9 o una letra K, ordenar estas cadenas puede ser algo complicado pues el ordenamiento no es numérico.</p>
<p style="text-align:justify;">En este <a href="http://www.linuxweblog.com/blogs/sandip/20060126/sorting-varchar-data-mysql">sitio</a> presentan una solución bastante sencilla, básicamente es sumarle un cero a la columna por la que queremos ordenar.</p>
<pre class="brush: plain;">
mysql&#62; SELECT column FROM table_name ORDER BY column+0;
</pre>
<p>Esta idea se puede llevar a symfony simplemente añadiendo una cláusula de ordenamiento en un Criteria.</p>
<pre class="brush: php;">
$c = new Criteria();
$c-&#62;addDescendingOrderByColumn('USERNAME+0');
</pre>
<p style="text-align:justify;">Saludos!</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Using symfony and sfDomPdfPlugin to generate pdf]]></title>
<link>http://nibsirahsieu.wordpress.com/2009/11/02/using-symfony-and-sfdompdfplugin-to-generate-pdf/</link>
<pubDate>Mon, 02 Nov 2009 16:38:06 +0000</pubDate>
<dc:creator>nibsirahsieu</dc:creator>
<guid>http://nibsirahsieu.wordpress.com/2009/11/02/using-symfony-and-sfdompdfplugin-to-generate-pdf/</guid>
<description><![CDATA[One of the nice things from DOMPDF is the way it to generate PDF file from HTML content. In symfony,]]></description>
<content:encoded><![CDATA[One of the nice things from DOMPDF is the way it to generate PDF file from HTML content. In symfony,]]></content:encoded>
</item>
<item>
<title><![CDATA[Validasi No Telepon menggunakan symfony validator]]></title>
<link>http://nibsirahsieu.wordpress.com/2009/10/31/validasi-no-telepon-menggunakan-symfony-validator/</link>
<pubDate>Sat, 31 Oct 2009 19:08:19 +0000</pubDate>
<dc:creator>nibsirahsieu</dc:creator>
<guid>http://nibsirahsieu.wordpress.com/2009/10/31/validasi-no-telepon-menggunakan-symfony-validator/</guid>
<description><![CDATA[Ada artikel menarik mengenai validasi no telp, temen2 bisa baca disini. Apa sih yang perlu di valida]]></description>
<content:encoded><![CDATA[Ada artikel menarik mengenai validasi no telp, temen2 bisa baca disini. Apa sih yang perlu di valida]]></content:encoded>
</item>
<item>
<title><![CDATA[Validasi username di symfony menggunakan validator]]></title>
<link>http://nibsirahsieu.wordpress.com/2009/10/31/validasi-username-di-symfony-menggunakan-validator/</link>
<pubDate>Sat, 31 Oct 2009 07:26:48 +0000</pubDate>
<dc:creator>nibsirahsieu</dc:creator>
<guid>http://nibsirahsieu.wordpress.com/2009/10/31/validasi-username-di-symfony-menggunakan-validator/</guid>
<description><![CDATA[Awalnya sih g kepikiran juga, kalo username kudu di validasi (parah..parah.. ), tapi setelah ngeliat]]></description>
<content:encoded><![CDATA[Awalnya sih g kepikiran juga, kalo username kudu di validasi (parah..parah.. ), tapi setelah ngeliat]]></content:encoded>
</item>
<item>
<title><![CDATA[Symfony dan Ioncube]]></title>
<link>http://nibsirahsieu.wordpress.com/2009/10/30/symfony-dan-ioncube/</link>
<pubDate>Fri, 30 Oct 2009 21:17:32 +0000</pubDate>
<dc:creator>nibsirahsieu</dc:creator>
<guid>http://nibsirahsieu.wordpress.com/2009/10/30/symfony-dan-ioncube/</guid>
<description><![CDATA[In symfony, encoded classes excluded from config_autoload_yml.php. Because when symfony found the cl]]></description>
<content:encoded><![CDATA[In symfony, encoded classes excluded from config_autoload_yml.php. Because when symfony found the cl]]></content:encoded>
</item>
<item>
<title><![CDATA[Usando JSON con jQuery en Symfony ]]></title>
<link>http://emartini.wordpress.com/2009/10/30/usando-json-con-jquery-en-symfony/</link>
<pubDate>Fri, 30 Oct 2009 03:54:33 +0000</pubDate>
<dc:creator>esteban.martini</dc:creator>
<guid>http://emartini.wordpress.com/2009/10/30/usando-json-con-jquery-en-symfony/</guid>
<description><![CDATA[JSON es una forma bastante cómoda de tratar con &#8220;objetos&#8221; y si lo usamos junto con AJAX ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p style="text-align:justify;"><a title="JSON - Wikipedia.es" href="http://es.wikipedia.org/wiki/JSON" target="_blank">JSON</a> es una forma bastante cómoda de tratar con &#8220;objetos&#8221; y si lo usamos junto con AJAX puede resultar <span style="text-decoration:line-through;">muy</span> sencillo tratar con respuestas que contienen mas de un elemento, tales como una array o un objeto. En el siguiente ejemplo veremos como usar  <strong><em>jQuery</em></strong> y <em><strong>JSON</strong></em> para realizar consultas AJAX en <em><strong>symfony</strong></em> (sin helpers o similares)</p>
<p style="text-align:justify;">Voy a evitar declarar el modelo de datos, por lo que supongo que el lector ya tiene algunos conocimientos básicos de este framework.</p>
<h3>1.- El Action</h3>
<p style="text-align:justify;">Lo primero que haremos es crear un nuevo método para nuestro action, el objetivo es retornar un texto serializado con información de un usuario.</p>
<pre class="brush: php;">
public function executeAjaxDatosCorredorById(sfWebRequest $request){

  /* Asegurar que la solicitud sea AJAX */
  if (!$request-&#62;isXmlHttpRequest())
    return $this-&#62;renderText(json_encode(array('error'=&#62;'Sólo respondo consultas vía AJAX.')));

  /* si entra por POST o GET la variable sfUserId, continuar */
  if($request-&#62;getParameter('sfUserId'))
  {
     $usuario = sfGuardUserPeer::retrieveByPK($request-&#62;getParameter('sfUserId'));
     /* Crear array asociativo con los atributos del objeto $usuario */
     $datosUsuario = array(
        &#34;nombre&#34;    =&#62; $usuario-&#62;getProfile()-&#62;getNombre(),
         &#34;apellidoP&#34; =&#62; is_null($usuario-&#62;getProfile()-&#62;getApellidoP()) ? '' : $usuario-&#62;getProfile()-&#62;getApellidoP(),
         &#34;apellidoM&#34; =&#62; is_null($usuario-&#62;getProfile()-&#62;getApellidoM()) ? '' : $usuario-&#62;getProfile()-&#62;getApellidoM(),
         &#34;rut&#34;       =&#62; $usuario-&#62;getUsername()
      );

      /* retornar el arreglo en formato JSON */
      return $this-&#62;renderText(json_encode($datosUsuario));
   }
   return $this-&#62;renderText(json_encode(array('error'=&#62;'Faltan parámetros para realizar la consulta')));
}
</pre>
<p>Listo. la respuesta está lista para ser &#8220;interpretada&#8221;. Ahora vamos a ver cómo procesamos la consulta:</p>
<h3>2.- La funcion AJAX</h3>
<p>Los parámetros de esta función son:<br />
<em> sfAction</em>: es dirección http de la accion de symfony a ejecutar.<br />
<em> idTrigger</em>: Id del elemento DOM que desencadena el evento.<br />
<em> valorParametro</em>: valor que toma laa variable GET['sfUserId']</p>
<pre class="brush: jscript;">
function getDatosUsuarioById(sfAction, idTrigger, valorParametro)
{
      $.ajax(
      {
        url: sfAction,
        data: ({sfUserId: valorParametro}),
        dataType: &#34;json&#34;,
        beforeSend: function()
        {
          $(&#34;#&#34;+idTrigger).append('&#60;span id=&#34;cargando_datos&#34;&#62; Cargando datos...');
        },
        complete: function()
        {
          $(&#34;#cargando_datos&#34;).hide();
        },
        success: function (data, status)
        {
          $(&#34;#propuesta_nombre_contratante&#34;).val(data.nombre);
          $(&#34;#propuesta_apellido_p_contratante&#34;).val(data.apellidoP);
          $(&#34;#propuesta_apellido_m_contratante&#34;).val(data.apellidoM);
          /* ... etc */
        }
        error: function (data, status, e)
        {
            alert('Ocurrió un error cargando los datos solicitados:.\n'+data.error);
        }
    });
}
</pre>
<p>En la sección <em><span style="color:#339966;"><strong><span style="color:#008000;">success</span></strong></span></em> se puede ver que la respuesta, representada por  <em>data</em>,  se interpreta como si fuera un objeto.</p>
<h3>3.- La puesta en marcha</h3>
<p style="text-align:justify;">Para ver el código en funcionamiento debemos agregar el siguiente código en la <em>vista</em> o <em>template</em> en la que necesitemos la función recién implementada. En este ejemplo la función <span style="font-family:Consolas, Monaco, 'Courier New', Courier, monospace;line-height:18px;font-size:12px;white-space:pre;">getDatosUsuarioById(&#8230;) <span style="font-family:Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;line-height:19px;white-space:normal;font-size:13px;">se dispara al entrar en foco el elemento <em>DOM</em> con Id: <em><span style="color:#000000;">propuesta_nombre_contratante</span></em>. Por otra parte, nótese cómo se declara la variable <span style="color:#339966;"><em><span style="color:#000000;"><strong>sfCargaDatosUsuario</strong></span></em></span>, se utiliza el helper <em><a title="url_for - documentación oficial de symfony" href="http://www.symfony-project.org/book/1_0/09-Links-and-the-Routing-System#chapter_09_sub_using_absolute_paths" target="_blank">url_for</a></em> para crear una ruta, utilizando enrutamiento absoluto, hacia el URL del action a ejecutar.</span></span></p>
<pre class="brush: php;">
$(document).ready(function(){
  var sfCargaDatosUsuario  = &#34;&#60;?php echo url_for('propuesta/ajaxDatosUsuarioById')?&#62;&#34;;
   $(&#34;#propuesta_nombre_contratante&#34;).focus(function()
   {
        if($(&#34;#propuesta_cliente_id&#34;).val()&#62;0)
        {
            getDatosUsuarioById(
                sfCargaDatosUsuario,
                &#34;propuesta_cliente_id&#34;,
                $(&#34;#propuesta_cliente_id&#34;).val(),
            );
        }
    });
});
</pre>
<p>Eso por el momento, espero le sea de utilidad a alguien, iré puliendo esta entrada para que quede más clara.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[tips for php coding in netbeans]]></title>
<link>http://symfonyandy.wordpress.com/2009/10/30/tips-for-php-coding-in-netbeans/</link>
<pubDate>Thu, 29 Oct 2009 23:53:13 +0000</pubDate>
<dc:creator>symfonyandy</dc:creator>
<guid>http://symfonyandy.wordpress.com/2009/10/30/tips-for-php-coding-in-netbeans/</guid>
<description><![CDATA[I&#8217;ve switched from Vim to netbeans in the past 9 months or so &#8211; I&#8217;ve been using Vi]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I&#8217;ve switched from <a href="http://www.vim.org">Vim</a> to <a href="http://www.netbeans.org">netbeans</a> in the past 9 months or so &#8211; I&#8217;ve been using Vim for 5+ years before that and finding an editor to beat it wasn&#8217;t easy. Main aim was to get better code completion, plus whichever editor I used had to have &#8216;<a href="http://netbeans.dzone.com/tips/hidden-hippie">hippie search</a>&#8216;  &#8211; this speeds up coding no end. Tried <a href="http://www.eclipse.org/pdt/">eclipse</a> PDT along the way but found that too slow.</p>
<p>Ultimately netbeans persuaded me to convert. Here are some tips for using it:</p>
<h2>General tips</h2>
<ul>
<li><strong>Use at least <a title="netbeans download" href="http://netbeans.org/downloads/index.html">6.8 beta version</a> of netbeans</strong> &#8211; there are performance improvements for code completion which increase code completion a lot. If you&#8217;ve tried 6.7/6.5 &#8211; try again with the 6.8 beta+, especially with large projects.</li>
<li><strong>Enable hippie search</strong> &#8211; The default keys are ctrl+k and ctrl+shift+k &#8211; If you&#8217;re a Vim person, change these to ctrl+p and ctrl+n. The &#8216;Actions&#8217; in the keymap editor are &#8216;Next matching word&#8217; and &#8216;Previous matching word&#8217;</li>
<li><strong>I</strong><strong>nitiate code completion manually</strong> &#8211; use ctrl+space (default) I find the auto code completion popup just gets in the way. YMMV.</li>
<li><strong>Use Navigate menu</strong> &#8211; this allows you to find files/classes/functions/methods in your code almost instantly</li>
<li><strong>phpdoc your code</strong>:<strong> </strong>this allows code completion to work in places it otherwise could not</li>
</ul>
<h2>Symfony</h2>
<ul>
<li><strong>Ignore &#8216;test&#8217; directories</strong> &#8211; make sure you ignore certain dirs in symfony. This makes code completion ignore classes under those directories.  I have problems with it picking up classes not in our project e.g. sfContext can get confused with sfContextMock from the tests.</li>
<li><strong>Symfony is supported in netbeans 6.8M2+</strong> see <a href="http://blogs.sun.com/netbeansphp/entry/initial_symfony_support">http://blogs.sun.com/netbeansphp/entry/initial_symfony_support</a></li>
</ul>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Hello World]]></title>
<link>http://svipl.wordpress.com/2009/10/29/hello-world-2/</link>
<pubDate>Thu, 29 Oct 2009 05:08:17 +0000</pubDate>
<dc:creator>svipl</dc:creator>
<guid>http://svipl.wordpress.com/2009/10/29/hello-world-2/</guid>
<description><![CDATA[we are web developer and designer company]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>we are web developer and designer company</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[EmbedForm no Symfony 1.2]]></title>
<link>http://augustomorais.wordpress.com/2009/10/28/embedform-no-symfony-1-2/</link>
<pubDate>Wed, 28 Oct 2009 06:08:15 +0000</pubDate>
<dc:creator>Augusto Morais</dc:creator>
<guid>http://augustomorais.wordpress.com/2009/10/28/embedform-no-symfony-1-2/</guid>
<description><![CDATA[Olá a todos, recentemente tive um grande problema em relação ao embedforms do symfony. A tarefa era ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Olá a todos,</p>
<p>recentemente tive um grande problema em relação ao embedforms do symfony. A tarefa era simples, encapsular um formulário dentro de outro com a opção de adicionar ou não um novo registro no BD. Este blog surgiu simplesmente por conta deste problema que enfrentei e vejo que muitos já enfrentaram e vão enfrentar.</p>
<p>Fiquei exatamente 3 dias pesquisando isto e não achei nada exato na internet, algumas dicas aqui e outras ali. Comecei a fazer tudo a minha própria maneira e finalmente consegui. O exemplo a seguir é com base no doctrine. Passei a usá-lo por diversos motivos que agora não entram em questão. Vejo que minha alternativa para este problema não me parece comum e nem a mais correta, porém foi a que encontrei e gostaria muito que outros compartilhassem tal assunto comigo.</p>
<p>Bom, vamos a situação.</p>
<p>Tenho 2 tabelas, uma chamada autor e outra livros, eis aqui o schema.yml:</p>
<pre class="brush: css;">
Livro:
actAs:                  { Timestampable: ~ }
columns:
autor_id:               { type: integer   , notnull: true }
isbn:                   { type: string(50), notnull: true }
titulo:                 { type: string(50), notnull: true }
relations:
Autor: { onDelete: CASCADE, local: autor_id, foreign: id, foreignAlias: Livros }

Autor:
actAs:               { Timestampable: ~ }
columns:
nome:                { type: string(255), notnull: true }
sobrenome:           { type: string(255), notnull: true }
</pre>
<p>Simples. A nossa intenção aqui é criar um formulário semelhante a este:</p>
<div id="attachment_4" class="wp-caption alignleft" style="width: 450px"><img class="size-full wp-image-4" title="formulario" src="http://augustomorais.wordpress.com/files/2009/10/imagem1.png" alt="formulario" width="440" height="181" /><p class="wp-caption-text">formulário</p></div>
<p>Ok. Perceba no checkbox Novo Autor. É nisto que vou trabalhar neste artigo. A opção de escolher um autor já cadastrado ou adicionar um novo autor.</p>
<p>Bom, vamos lá. A primeira coisa que devemos fazer é modificar nosso LivroForm.class.php para a seguinte estrutura:</p>
<div>
<pre class="brush: php;">
class LivroForm extends BaseLivroForm
{
  public function configure()
  {
  $autorForm = new AutorForm();

  //Adicionando Checkbox &#34;adicionar novo cliente&#34;
  $this-&#62;getWidgetSchema()-&#62;offsetSet(
    'add_new_autor', new sfWidgetFormInputCheckbox(array(
      'label' =&#62; 'Novo Autor')));

  $this-&#62;embedForm('new_autor', $autorForm);

  $this-&#62;widgetSchema['autor_id']-&#62;setOption(
    'add_empty', 'Escolher Autor');
  $this-&#62;validatorSchema['autor_id']-&#62;setMessage(
    'required', 'Por favor, escolha um autor ou crie um novo.');

  $this-&#62;setValidatorSchema(
    new LivroValidatorSchema($this-&#62;validatorSchema-&#62;getFields()));

  // Inserindo campos extras (checkbox no caso)
  $this-&#62;validatorSchema-&#62;setOption('allow_extra_fields', true);
  $this-&#62;validatorSchema-&#62;setOption('filter_extra_fields', false);
  }

  public function updateObject($values = null)
  {
  parent::updateObject();

  if ($this-&#62;values['autor_id'] &#60;&#62; 0)
  {
    //Salvando nosso livro com o ID do autor Setado no template
    $livro = new Livro();
    $livro-&#62;fromArray($this-&#62;values);
    $livro-&#62;save();

    return $this-&#62;object;
  } else {
    //Salvando nosso autor criado
    $autor = new Autor();
    $autor-&#62;fromArray($this-&#62;values['new_autor']);
    $autor-&#62;save();  

    //Salvando nosso Livro com o nosso autor criado
    $this-&#62;getObject()-&#62;setAutor($autor);
    $this-&#62;getObject()-&#62;save();
    return $this-&#62;object;
  }
  }
}
</pre>
</div>
<p>Ok.  Gostaria somente de comentar aqui a linha 43: $autor-&#62;save() e 47: $this-&#62;getObject()-&#62;save(). Na linha 43 nós estamos salvando o nosso novo cliente. Após salvar, nós pegamos o objeto autor e setamos no nosso objeto Boleto(linha 46). Logo depois nós salvamos nosso boleto, linha 47.</p>
<p>Nós precisamos modificar nosso validator para aceitar os novos campos adicionados (checkbox e o formulario encapsulado, autor).</p>
<p>Crie um arquivo chamado LivroValidatorSchema.class.php em /lib/validators:</p>
<div>
<pre class="brush: php;">
class LivroValidatorSchema extends sfValidatorSchema {

  protected function doClean($values)
  {
    if (is_null($values)) {
      $values = array();
    }
    if (!is_array($values)) {
      throw new InvalidArgumentException(
        'You must pass an array parameter to the clean() method');
    }
    if (isset($values['add_new_autor'])) {
      $values['autor_id'] = '';
      $this-&#62;offsetUnset('autor_id');
    } else {
      if (isset($values['new_autor'])) {
        $values['new_autor'] = '';
        unset($values['new_autor']);
      }
    $this-&#62;offsetUnset('new_autor');
    }
  return parent::doClean($values);
  }
}
</pre>
<p>obs.: o código acima foi tirado de: http://forum.symfony-project.org/index.php/m/65120/</p>
<p>Agora está quase tudo pronto. Falta agora modificar nosso actions:</p>
<div>
<pre class="brush: php;">
protected function processForm(sfWebRequest $request, sfForm $form)
{
  $form-&#62;bind($request-&#62;getParameter($form-&#62;getName()));
  if ($form-&#62;isValid()) {
    $form-&#62;updateObject();
    //$livro = $form-&#62;save();
    //$this-&#62;redirect('livro/edit?id='.$livro-&#62;getId());
    $this-&#62;redirect('livro/index');
  }
}
</pre>
</div>
<p>Perceba que a linha 6 está comentada: $livro = $form-&#62;save(); Está linha deve ser comentada mesmo pois quem vai salvar nosso objeto é o metodo updateObject. Caso você salve aqui você perceberá que os registros serão duplicados e está não é nossa intenção. </p>
<p>Agora você precisa adaptar seu form lá em templates para ter a mesma estrutura apresentada no inicio do artigo.</p>
<p>Este artigo foi criado rapidamente e sem preocupação com organização. Num próximo momento faço isto descentemente.</p>
<p>Aguardo comentários de todos.</p>
<p>Abraços</p>
<p>Augusto Morais</p>
</div>]]></content:encoded>
</item>

</channel>
</rss>
