<?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>Olivier Balais &#187; symfony</title>
	<atom:link href="http://blog.overnetcity.com/categorie/symfony/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.overnetcity.com</link>
	<description>OvernetCity, blog d&#039;un auto-entrepreneur passionné par le développement Web et les NTIC</description>
	<lastBuildDate>Thu, 26 Jan 2012 13:08:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com"/><atom:link rel="hub" href="http://superfeedr.com/hubbub"/>		<item>
		<title>sfForms et valeurs par défaut. Pourquoi est-ce que getDefault me renvoie null ?</title>
		<link>http://blog.overnetcity.com/11-05-2011/sfforms-et-valeurs-par-defaut-pourquoi-est-ce-que-getdefault-me-renvoie-null/</link>
		<comments>http://blog.overnetcity.com/11-05-2011/sfforms-et-valeurs-par-defaut-pourquoi-est-ce-que-getdefault-me-renvoie-null/#comments</comments>
		<pubDate>Wed, 11 May 2011 16:15:32 +0000</pubDate>
		<dc:creator>Olivier Balais</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[bug symfony]]></category>
		<category><![CDATA[default values]]></category>
		<category><![CDATA[null]]></category>
		<category><![CDATA[sfForms]]></category>

		<guid isPermaLink="false">http://blog.overnetcity.com/?p=353</guid>
		<description><![CDATA[Les formulaires de symfony ont quelquefois des comportements surprenants pour le développeur. Tout le monde pense immédiatement aux embed forms mais ce n&#8217;est pas de ces derniers dont je vais parler ici. Je suis tombé sur le problème suivant : pourquoi après avoir passé une valeur par défaut à un des widgets de mon formulaire, [...]]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F11-05-2011%2Fsfforms-et-valeurs-par-defaut-pourquoi-est-ce-que-getdefault-me-renvoie-null%2F' data-shr_title='sfForms+et+valeurs+par+d%C3%A9faut.+Pourquoi+est-ce+que+getDefault+me+renvoie+null+%3F'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F11-05-2011%2Fsfforms-et-valeurs-par-defaut-pourquoi-est-ce-que-getdefault-me-renvoie-null%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F11-05-2011%2Fsfforms-et-valeurs-par-defaut-pourquoi-est-ce-que-getdefault-me-renvoie-null%2F' data-shr_title='sfForms+et+valeurs+par+d%C3%A9faut.+Pourquoi+est-ce+que+getDefault+me+renvoie+null+%3F'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetTop Automatic --><p>Les formulaires de symfony ont quelquefois des comportements surprenants pour le développeur. Tout le monde pense immédiatement aux <strong>embed forms </strong>mais ce n&#8217;est pas de ces derniers dont je vais parler ici.</p>
<p>Je suis tombé sur le problème suivant : pourquoi après avoir passé une valeur par défaut à un des widgets de mon formulaire, je ne parviens pas à la récupérer dans mon action ou dans mon template ? L&#8217;appel à la méthode getDefault du sfForm me renvoie <em>null,</em> tout simplement.</p>
<p>Cas typique :</p>
<pre class="brush: php; ">

// Dans le code de mon formulaire :
$this-&gt;setWidgets(array(
  ...
  &#039;my_field&#039; =&gt; new sfMyWidget(array(&#039;default&#039; =&gt; &#039;my_value&#039;)),
));

// Dans le code de mon action :
if ($my_form-&gt;getDefault(&#039;my_field&#039;) == &#039;some_value&#039;)
{
  ...
}
</pre>
<p>Dans ce cas, la méthode getDefault() appelée sur mon formulaire me renvoie null alors que j&#8217;ai explicitement donné une valeur par défaut à mon widget. Pourtant, en lisant la doc de symfony sur le sujet je retiens ceci :</p>
<blockquote><p>The setDefault(), getDefault(), setDefaults(), and getDefaults() methods manages the default values for the embedded widgets. <span style="text-decoration: underline;">They are proxy methods </span>for the getDefault() and setDefault() widget methods.</p></blockquote>
<p>Les méthodes setDefault() et getDefault() au niveau de la classe sfForm sont censées êtres des raccourcis pour les méthodes setDefault() et getDefault() de la classe sfWidgetForm().</p>
<p>En fait il s&#8217;avère que ce n&#8217;est absolument pas le cas et que la méthode getDefault() du formulaire ne fait jamais appel à la méthode getDefault() du widget associé.</p>
<p>L&#8217;appel à <strong>$my_form-&gt;getDefault(&#8216;my_field&#8217;)</strong> n&#8217;est donc pas équivalent à <strong>$my_form['my_field']-&gt;getWidget()-&gt;getDefault()</strong>.</p>
<p>Par conséquent, il est important de bien comprendre quelle méthode appeler et dans quel cas.</p>
<p>A savoir, <strong>$my_form-&gt;getDefault(&#8216;my_field&#8217;)</strong> quand le setDefault a été utilisé<strong> au niveau du formulaire</strong>. Exemple :</p>
<pre class="brush: php; ">

// Valeurs passées dans mon formulaire :
$this-&gt;setWidgets(array(
  ...
  &#039;my_field&#039; =&gt; new sfMyWidget(),
));
$this-&gt;setDefault(&#039;my_field&#039;, &#039;my_value&#039;);

// Ou alors valeurs passées dans mon action :
$my_form = new myFormClass(array(
  ...
  &#039;my_field&#039; =&gt; &#039;my_value&#039;,
));
</pre>
<p>Et, <strong>$my_form['my_field']-&gt;getWidget()-&gt;getDefault()</strong> quand le setDefault() a été utilisé <strong>au niveau du widget</strong>. Exemple :</p>
<pre class="brush: php; ">

// Dans le code de mon formulaire :
$this-&gt;setWidgets(array(
  ...
  &#039;my_field&#039; =&gt; new sfMyWidget(array(&#039;default&#039; =&gt; &#039;my_value&#039;)),
));
</pre>
<p>Voilà, désormais vous êtes prévenus&#8230;</p>
<div class="shr-publisher-353"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F11-05-2011%2Fsfforms-et-valeurs-par-defaut-pourquoi-est-ce-que-getdefault-me-renvoie-null%2F' data-shr_title='sfForms+et+valeurs+par+d%C3%A9faut.+Pourquoi+est-ce+que+getDefault+me+renvoie+null+%3F'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F11-05-2011%2Fsfforms-et-valeurs-par-defaut-pourquoi-est-ce-que-getdefault-me-renvoie-null%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F11-05-2011%2Fsfforms-et-valeurs-par-defaut-pourquoi-est-ce-que-getdefault-me-renvoie-null%2F' data-shr_title='sfForms+et+valeurs+par+d%C3%A9faut.+Pourquoi+est-ce+que+getDefault+me+renvoie+null+%3F'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://blog.overnetcity.com/11-05-2011/sfforms-et-valeurs-par-defaut-pourquoi-est-ce-que-getdefault-me-renvoie-null/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Les ressources utiles du mois de Juillet</title>
		<link>http://blog.overnetcity.com/31-07-2010/les-ressources-utiles-du-mois-de-juillet/</link>
		<comments>http://blog.overnetcity.com/31-07-2010/les-ressources-utiles-du-mois-de-juillet/#comments</comments>
		<pubDate>Sat, 31 Jul 2010 07:30:56 +0000</pubDate>
		<dc:creator>Olivier Balais</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Ressources Utiles]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[gallery]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[microdata]]></category>
		<category><![CDATA[microformats]]></category>
		<category><![CDATA[rdfa]]></category>
		<category><![CDATA[realtime]]></category>
		<category><![CDATA[slideshow]]></category>
		<category><![CDATA[temps réel]]></category>
		<category><![CDATA[tuto]]></category>
		<category><![CDATA[tutoriel]]></category>
		<category><![CDATA[xmpp]]></category>

		<guid isPermaLink="false">http://blog.overnetcity.com/?p=256</guid>
		<description><![CDATA[C&#8217;est une pratique assez récurrente chez les développeurs Web ou chez les web designers qui bloguent. Alors moi aussi je vais régulièrement (chaque mois) poster un article regroupant les ressources utiles sur lesquelles je suis tombé. Deux intérêts à cette démarche : D&#8217;une part pouvoir les retrouver le jour où j&#8217;en aurai besoin / re-besoin [...]]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F31-07-2010%2Fles-ressources-utiles-du-mois-de-juillet%2F' data-shr_title='Les+ressources+utiles+du+mois+de+Juillet'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F31-07-2010%2Fles-ressources-utiles-du-mois-de-juillet%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F31-07-2010%2Fles-ressources-utiles-du-mois-de-juillet%2F' data-shr_title='Les+ressources+utiles+du+mois+de+Juillet'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetTop Automatic --><p>C&#8217;est une pratique assez récurrente chez les développeurs Web ou chez les web designers qui bloguent. Alors moi aussi je vais régulièrement (chaque mois) poster un article regroupant les ressources utiles sur lesquelles je suis tombé. Deux intérêts à cette démarche :</p>
<ul>
<li>D&#8217;une part pouvoir les retrouver le jour où j&#8217;en aurai besoin / re-besoin</li>
<li>D&#8217;autre part, les partager avec vous amis lecteurs</li>
</ul>
<p>Je crée donc pour l&#8217;occasion une nouvelle catégorie d&#8217;articles sur OvernetCity intitulée sobrement : &#8220;Ressources Utiles&#8221;.</p>
<p>Pour ce mois de Juillet, un peu de jQuery, un peu de symfony et un peu de développement iPhone sont au programme. D&#8217;ailleurs, cela risque d&#8217;être souvent le cas&#8230;</p>
<h2>Interactive Photo Desk with jQuery and CSS3</h2>
<p><img class="alignnone size-medium wp-image-258" title="Photo Desk" src="http://blog.overnetcity.com/wp-content/uploads/2010/07/photodesk-300x162.jpg" alt="" width="300" height="162" /></p>
<p>Les démonstrations concernant CSS 3 et HTML 5 ont le vent en poupe depuis quelques mois. Il ne se passe pas une journée sans qu&#8217;un tuto complet soit posté sur un des nombreux blogs que je suis, montrant à quel point l&#8217;arrivée de ces deux langages et leur support par l&#8217;ensemble des navigateurs modernes va changer notre façon d&#8217;interagir avec une application Web.</p>
<p>Ici, c&#8217;est l&#8217;alliance du CSS 3 et de jQuery qui permet de réaliser un chouette bureau sur lequel s&#8217;entassent quelques photos. L&#8217;utilisateur peut les déplacer avec un résultat d&#8217;une fluidité étonnante.</p>
<p>A consulter avec un navigateur moderne évidemment.</p>
<p><a href="http://tympanus.net/codrops/2010/07/01/interactive-photo-desk/">http://tympanus.net/codrops/2010/07/01/interactive-photo-desk/</a></p>
<h2>Minimalistic Slideshow Gallery with jQuery</h2>
<p><img class="alignnone size-medium wp-image-257" title="Minimalistic Slideshow Gallery" src="http://blog.overnetcity.com/wp-content/uploads/2010/07/MinimalisticSlideshowGallery-300x162.jpg" alt="" width="300" height="162" /></p>
<p>Encore un tuto expliquant comment réaliser une mini gallerie pour afficher quelques photos. Celui-ci a le mérite d&#8217;être très clair et d&#8217;avoir un rendu vraiment pro.</p>
<p>Très facile à intégrer au sein d&#8217;une page existante !</p>
<p><a href="http://tympanus.net/codrops/2010/07/05/minimalistic-slideshow-gallery/">http://tympanus.net/codrops/2010/07/05/minimalistic-slideshow-gallery/</a></p>
<h2>Symfony 1.4 &#8211; Tri sur les colonnes étrangères dans l&#8217;admin generator</h2>
<p>L&#8217;admin generator de symfony est un outil merveilleusement pratique qui permet de créer en quelques minutes un backend parfaitement fonctionnel et adapté aux besoins du client.</p>
<p>Néanmoins, je me suis souvent demandé pourquoi il est impossible sans mettre les mains dans le cambouis de faire un tri sur les colonnes persos dans la liste générée par le Framework. Chaque colonne est par défaut cliquable ce qui entraine un tri ascendant ou descendant de la liste en fonction de cette colonne mais ce comportement est indisponible dès que la colonne en question n&#8217;est pas une colonne native en base et fait, par exemple, référence à l&#8217;attribut name d&#8217;un objet récupéré via une relation.</p>
<p>Les développeurs experts symfony de l&#8217;agence Elao nous montrent comment modifier le comportement de l&#8217;admin generator pour que, justement, ce tri soit possible sur les colonnes non natives. Très utile !</p>
<p><a href="http://www.elao.org/symfony/symfony-1-4-admin-generator-tris-sur-les-colonnes-etrangeres.html">http://www.elao.org/symfony/symfony-1-4-admin-generator-tris-sur-les-colonnes-etrangeres.html</a></p>
<h2>Introduction aux Métadonnées RDFa, Microdata et Microformats</h2>
<p><img class="alignnone size-medium wp-image-262" title="microdata-image1" src="http://blog.overnetcity.com/wp-content/uploads/2010/07/microdata-image1-300x99.jpg" alt="" width="300" height="99" /></p>
<p>Je connais la technique depuis un moment mais n&#8217;ai pas encore eu l&#8217;occasion de la mettre en pratique au sein d&#8217;un projet. Ces métadonnées à destination des moteurs de recherche permettent de stocker de modifier la présentation d&#8217;une page au sein d&#8217;un moteur de recherche pour apporter de la valeur ajoutée à l&#8217;utilisateur. Les sites référençant des restaurants, par exemple, peuvent profiter de ces métadonnées pour afficher, directement au sein des résultats d&#8217;un moteur de recherche, la note associée à un restaurant sous forme d&#8217;étoiles.</p>
<p>Ces données sont de plus en plus utilisées et de mieux en mieux exploitées. Elles méritent donc qu&#8217;on s&#8217;y attarde un tout petit peu de manière à optimiser le référencement naturel d&#8217;une application web.</p>
<p>Cet article présente quelques exemples concrets d&#8217;utilisation de ces métadonnées et référence quelques liens utiles pour le développeur.</p>
<p><a href="http://spyrestudios.com/real-world-microformats-rdfa-microformats-and-microdata-practical-examples/">http://spyrestudios.com/real-world-microformats-rdfa-microformats-and-microdata-practical-examples/</a></p>
<h2>Tutoriel complet sur les Microdata de HTML5</h2>
<p><img class="alignnone size-full wp-image-269" title="nettuts_microdata" src="http://blog.overnetcity.com/wp-content/uploads/2010/07/nettuts_microdata.png" alt="" width="200" height="200" /></p>
<p>Quand on pense à l&#8217;HTML 5, on ne pense pas forcément immédiatement à Microdata. Et pourtant c&#8217;est également une des grandes nouveauté que ce nouveau langage nous apporte et à laquelle tout bon développeur se doit de s&#8217;intéresser. Ce tutoriel très complet permet d&#8217;aller plus loin que l&#8217;article précédent en se basant sur un exemple concret.</p>
<p><a href="http://net.tutsplus.com/tutorials/html-css-techniques/html5-microdata-welcome-to-the-machine/">http://net.tutsplus.com/tutorials/html-css-techniques/html5-microdata-welcome-to-the-machine/</a></p>
<h2>Comment intégrer Google Analytics dans son application iPhone en 7 minutes ?</h2>
<p>Intégrer un script de tracking des visiteurs dans une application Web est aujourd&#8217;hui presque un réflexe pour le développeur. On peut faire la même chose pour une application lourde sur iPhone puisque l&#8217;API de Google est compatible avec plusieurs terminaux mobiles dont ce dernier.</p>
<p>Quel est l&#8217;intérêt ? Comment est-ce que ça marche ? Quels sont les pré-requis ? Autant de questions qui trouveront leurs réponses dans ce tutoriel très complet de iCodeBlog.</p>
<p><a href="http://icodeblog.com/2010/04/22/how-to-integrate-google-analytics-tracking-into-your-apps-in-7-minutes/">http://icodeblog.com/2010/04/22/how-to-integrate-google-analytics-tracking-into-your-apps-in-7-minutes/</a></p>
<h2>Premiers pas avec iPhone Core Data</h2>
<p><img class="alignnone size-full wp-image-273" title="Into_to_coredata_preview2" src="http://blog.overnetcity.com/wp-content/uploads/2010/07/Into_to_coredata_preview2.jpg" alt="" width="200" height="200" /></p>
<p>Ce tutoriel est une belle introduction au Framework Core Data de l&#8217;iPhone OS qui n&#8217;est pas très bien couvert par les livres que j&#8217;ai pu lire lors de ma formation au développement iPhone.</p>
<p>A parcourir pour comprendre quelles sont les possibilités offertes par ce Framework et surtout comment les mettre en oeuvre.</p>
<p><a href="http://mobile.tutsplus.com/tutorials/iphone/iphone-core-data/">http://mobile.tutsplus.com/tutorials/iphone/iphone-core-data/</a></p>
<h2>Afficher un flux RSS en temps réel avec XMPP</h2>
<p>Comment fait Google avec son GTalk pour afficher les messages envoyés en temps réel sur sa page web, sans sacrifier les ressources serveurs avec des requêtes Ajax envoyée chaque seconde ?</p>
<p>C&#8217;est une question que je me suis souvent posé et à laquelle j&#8217;ai trouvé une réponse aujourd&#8217;hui grâce à un tutoriel très complet posté sur le site d&#8217;IBM. GMail, Gtalk, Google Wave font tous usage du langage XMPP dédié à la notification en quasi temps réel pour les applications web. A lire d&#8217;urgence si le sujet vous intéresse&#8230;</p>
<p><a href="http://www.ibm.com/developerworks/xml/tutorials/x-realtimeXMPPtut/index.html">http://www.ibm.com/developerworks/xml/tutorials/x-realtimeXMPPtut/index.html</a></p>
<div class="shr-publisher-256"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F31-07-2010%2Fles-ressources-utiles-du-mois-de-juillet%2F' data-shr_title='Les+ressources+utiles+du+mois+de+Juillet'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F31-07-2010%2Fles-ressources-utiles-du-mois-de-juillet%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F31-07-2010%2Fles-ressources-utiles-du-mois-de-juillet%2F' data-shr_title='Les+ressources+utiles+du+mois+de+Juillet'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://blog.overnetcity.com/31-07-2010/les-ressources-utiles-du-mois-de-juillet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Comment créer un sprite pour optimiser le chargement de ses images ?</title>
		<link>http://blog.overnetcity.com/10-07-2010/comment-creer-un-sprite-pour-optimiser-le-chargement-de-ses-images/</link>
		<comments>http://blog.overnetcity.com/10-07-2010/comment-creer-un-sprite-pour-optimiser-le-chargement-de-ses-images/#comments</comments>
		<pubDate>Sat, 10 Jul 2010 08:34:33 +0000</pubDate>
		<dc:creator>Olivier Balais</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://blog.overnetcity.com/?p=108</guid>
		<description><![CDATA[Je m&#8217;occupe actuellement du développement du site myBonjour.fr qui permet le recensement et l&#8217;affichage de tous les blogs du type Bonjour Madame et Bonjour Poney. Pour optimiser la vitesse de chargement des pages, je me suis intéressé à la technique aujourd&#8217;hui très populaire des Sprites CSS. Un Sprite, qu&#8217;est-ce que c&#8217;est ? C&#8217;est une grande [...]]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F10-07-2010%2Fcomment-creer-un-sprite-pour-optimiser-le-chargement-de-ses-images%2F' data-shr_title='Comment+cr%C3%A9er+un+sprite+pour+optimiser+le+chargement+de+ses+images+%3F'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F10-07-2010%2Fcomment-creer-un-sprite-pour-optimiser-le-chargement-de-ses-images%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F10-07-2010%2Fcomment-creer-un-sprite-pour-optimiser-le-chargement-de-ses-images%2F' data-shr_title='Comment+cr%C3%A9er+un+sprite+pour+optimiser+le+chargement+de+ses+images+%3F'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetTop Automatic --><p>Je m&#8217;occupe actuellement du développement du site <a href="http://www.mybonjour.fr">myBonjour.fr</a> qui permet le recensement et l&#8217;affichage de tous les blogs du type Bonjour Madame et Bonjour Poney.</p>
<p>Pour optimiser la vitesse de chargement des pages, je me suis intéressé à la technique aujourd&#8217;hui très populaire des Sprites CSS.</p>
<p>Un Sprite, qu&#8217;est-ce que c&#8217;est ? C&#8217;est une grande image qui contient plusieurs petites images utilisées au sein de votre application web, via les feuilles de style. En utilisant la propriété background CSS, il est assez facile de dire quelle partie du sprite doit être affichée en image de fond.<br />
L&#8217;avantage de regrouper plusieurs petites images au sein d&#8217;un sprite est double. D&#8217;une part, l&#8217;image ainsi formée est souvent moins lourde que l&#8217;ensemble des petites images additionnées et, d&#8217;autre part, le nombre de requête HTTP pour charger les images est réduit à un. C&#8217;est ce dernier point qui est le plus important et le plus significatif en terme de gain de performances.</p>
<p>Voici un exemple de sprite :</p>
<p><img src="http://blog.overnetcity.com/wp-content/uploads/2010/07/buttons.gif" alt="Sprite de boutons" title="Sprite de boutons" width="121" height="14" class="alignnone size-full wp-image-109" /></p>
<p>De nombreuses applications Web apportent une aide intéressante pour la création de Sprite à partir d&#8217;un site existant non optimisé.<br />
J&#8217;ai retenu tout particulièrement le site http://spriteme.org qui offre un bouton à glisser dans sa barre de favoris et qui ouvre une popup en Javascript qui permet de créer un sprite à la volée et même de générer le CSS correspondant à partir du CSS existant.</p>
<p><a href="http://blog.overnetcity.com/wp-content/uploads/2010/07/Capture.jpg"><img src="http://blog.overnetcity.com/wp-content/uploads/2010/07/Capture-300x189.jpg" alt="Exemple avec SpriteMe" title="Exemple avec SpriteMe" width="300" height="189" class="alignnone size-medium wp-image-110" /></a></p>
<p>Maintenant, comment générer un Sprite soit même, directement dans son code symfony ? Vous allez voir ci-dessous le code que j&#8217;ai utilisé pour <a href="http://www.mybonjour.fr">myBonjour.fr</a>.</p>
<p>Pour cela, j&#8217;ai ajouté dans un premier temps une méthode privée dans mon modèle, s&#8217;occupant de générer le Sprite en question :</p>
<pre class="brush: php; ">

  private function makeSpriteForFavicons()
  {
    $items = Doctrine_Core::getTable(&#039;MyBonjourItem&#039;)-&amp;gt;getAllActiveItems();

    $width = 25;
    $height = 16;
    $space = 14;

    // On crée l&#039;image vide
    $image = imagecreatetruecolor($width, ($height+$space) * count($items));
    $background = imagecolorallocatealpha($image, 255, 255, 255, 127);
    imagefill($image, 0, 0, $background);
    imagealphablending($image, false);
    imagesavealpha($image, true);

    // Ajout de tous les favicons à l&#039;image
    $pos = 7;
    foreach($items as $item)
    {
      $tmp = imagecreatefrompng($item-&amp;gt;getItemFilePath());
      imagecopy($image, $tmp, 0, $pos, 0, 0, $width, $height);
      $pos += $height + $space;
      imagedestroy($tmp);
    }

    imagepng($image, sfConfig::get(&#039;sf_web_dir&#039;).&#039;/images/items_icons.png&#039;);
  }
</pre>
<p>Il suffit ensuite d&#8217;appeler cette méthode, quand la colonne correspondant à l&#8217;image est modifiée. Pour cela, on implémente la méthode save du modèle :</p>
<pre class="brush: php; ">

  public function save(Doctrine_Connection $conn = null)
  {
    if(in_array(&#039;favicon_url&#039;, array_keys($this-&amp;gt;getModified())))
    {
      $return = parent::save($conn);
      $this-&amp;gt;makeSpriteForFavicons();
    }
    else
      $return = parent::save($conn);

    return $return;
  }
</pre>
<p>Et enfin, on génère la partie correspondante dans le fichier CSS, à la volée :</p>
<pre class="brush: php; ">

// makeCSSSuccess.php
&amp;lt;?php $pos = 0; foreach($items as $item): ?&amp;gt;
div#&amp;lt;?php echo $item-&amp;gt;getSlug() ?&amp;gt; &amp;gt; h3{
  background: url(&amp;quot;/images/items_icons.png&amp;quot;) no-repeat scroll 5px -&amp;lt;?php echo $pos*$width ?&amp;gt;px;
}
&amp;lt;?php $pos++; endforeach; ?&amp;gt;
</pre>
<p>Le fichier CSS généré par une action symfony doit être mis en cache pour éviter toute chute des performances. Il suffit de déclencher ensuite une regénération du cache lorsqu&#8217;un item est ajouté en base.<br />
Sur myBonjour, j&#8217;ai ainsi supprimé le chargement de 60 requêtes HTTP, correspondant aux différents bonjours présents dans la liste.</p>
<div class="shr-publisher-108"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F10-07-2010%2Fcomment-creer-un-sprite-pour-optimiser-le-chargement-de-ses-images%2F' data-shr_title='Comment+cr%C3%A9er+un+sprite+pour+optimiser+le+chargement+de+ses+images+%3F'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F10-07-2010%2Fcomment-creer-un-sprite-pour-optimiser-le-chargement-de-ses-images%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F10-07-2010%2Fcomment-creer-un-sprite-pour-optimiser-le-chargement-de-ses-images%2F' data-shr_title='Comment+cr%C3%A9er+un+sprite+pour+optimiser+le+chargement+de+ses+images+%3F'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://blog.overnetcity.com/10-07-2010/comment-creer-un-sprite-pour-optimiser-le-chargement-de-ses-images/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Lancer une tâche symfony depuis une action</title>
		<link>http://blog.overnetcity.com/02-07-2010/lancer-une-tache-symfony-depuis-une-action/</link>
		<comments>http://blog.overnetcity.com/02-07-2010/lancer-une-tache-symfony-depuis-une-action/#comments</comments>
		<pubDate>Fri, 02 Jul 2010 07:24:02 +0000</pubDate>
		<dc:creator>Olivier Balais</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[tâche]]></category>
		<category><![CDATA[task]]></category>

		<guid isPermaLink="false">http://blog.overnetcity.com/?p=88</guid>
		<description><![CDATA[How to launch a symfony task from action code? Ou comment appeler une tâche symfony depuis une action, sans passer par le CLI ? Symfony permet depuis la version 1.3 / 1.4 d&#8217;appeler une tâche directement depuis une autre tâche via le code suivant : $this-&#62;runTask(&#039;mydomain:mytask&#039;); On peut par exemple très facilement créer une tâche [...]]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F02-07-2010%2Flancer-une-tache-symfony-depuis-une-action%2F' data-shr_title='Lancer+une+t%C3%A2che+symfony+depuis+une+action'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F02-07-2010%2Flancer-une-tache-symfony-depuis-une-action%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F02-07-2010%2Flancer-une-tache-symfony-depuis-une-action%2F' data-shr_title='Lancer+une+t%C3%A2che+symfony+depuis+une+action'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetTop Automatic --><p>How to launch a symfony task from action code? Ou comment appeler une tâche symfony depuis une action, sans passer par le CLI ?</p>
<p>Symfony permet depuis la version 1.3 / 1.4 d&#8217;appeler une tâche directement depuis une autre tâche via le code suivant :</p>
<pre class="brush: php; ">

$this-&gt;runTask(&#039;mydomain:mytask&#039;);
</pre>
<p>On peut par exemple très facilement créer une tâche au cours de laquelle un appel à symfony cc sera déclenché :</p>
<pre class="brush: php; ">

&lt;?php

class testTask extends sfBaseTask
{
  protected function configure()
  {
    // // add your own arguments here
    // $this-&gt;addArguments(array(
    //   new sfCommandArgument(&#039;my_arg&#039;, sfCommandArgument::REQUIRED, &#039;My argument&#039;),
    // ));
    $this-&gt;addOptions(array(
    new sfCommandOption(&#039;application&#039;, null, sfCommandOption::PARAMETER_REQUIRED, &#039;The application name&#039;),
    new sfCommandOption(&#039;env&#039;, null, sfCommandOption::PARAMETER_REQUIRED, &#039;The environment&#039;, &#039;dev&#039;),
    new sfCommandOption(&#039;connection&#039;, null, sfCommandOption::PARAMETER_REQUIRED, &#039;The connection name&#039;, &#039;doctrine&#039;),
    // add your own options here
    ));
    $this-&gt;namespace        = &#039;&#039;;
    $this-&gt;name             = &#039;test&#039;;
    $this-&gt;briefDescription = &#039;&#039;;
    $this-&gt;detailedDescription = &lt;&lt;
The [test|INFO] task does things.
Call it with:
[php 1=&quot;test|INFO&quot; language=&quot;symfony&quot;][/php][/php]
EOF;
  }
  protected function execute($arguments = array(), $options = array())
  {
    // initialize the database connection
    $databaseManager = new sfDatabaseManager($this-&gt;configuration);
    $connection = $databaseManager-&gt;getDatabase($options[&#039;connection&#039;])-&gt;getConnection();
    // here is our code
    // we do something
    // and we clear cache
    $this-&gt;runTask(&#039;cc&#039;);
  }
}
</pre>
<p>En revanche, rien n&#8217;est actuellement prévu pour appeler cette même tâche depuis une action. Il est pourtant très utile de pouvoir appeler la tâche d&#8217;envoi des emails directement depuis une action de son backend. Ou même de vider le cache sans avoir à passer par la ligne de commandes.<br />
Le plugin <a href="http://www.symfony-project.org/plugins/ybRunTaskPlugin">ybRunTaskPlugin</a> a été développé justement pour palier à ce manque. Une fois le plugin installé, il est possible d&#8217;appeler directement au sein de son action une tâche symfony, de la même manière qu&#8217;on pouvait le faire en standard au sein d&#8217;une autre tâche :</p>
<pre class="brush: php; ">

class myActions extends sfActions
{
  public function executeRuntask(sfWebRequest $request)
  {
    $ret = $this-&gt;runTask(&#039;myDomain:myTask&#039;, &#039;myArguments&#039;);
    if(null != $ret)
    {
      $this-&gt;msg = $ret-&gt;getMessage();
    }
    else
    {
      $this-&gt;msg = &#039;everything went OK&#039;;
    }
  }
}
</pre>
<p>Malheureusement, le plugin ne gère actuellement pas l&#8217;affichage des logs ou d&#8217;une quelconque valeur de retour si l&#8217;exécution s&#8217;est passé correctement. Peut-être dans une prochaine version ?<br />
En attendant, vous pouvez réaliser un petit hack du plugin en fonction de vos besoins&#8230;</p>
<div class="shr-publisher-88"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F02-07-2010%2Flancer-une-tache-symfony-depuis-une-action%2F' data-shr_title='Lancer+une+t%C3%A2che+symfony+depuis+une+action'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F02-07-2010%2Flancer-une-tache-symfony-depuis-une-action%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F02-07-2010%2Flancer-une-tache-symfony-depuis-une-action%2F' data-shr_title='Lancer+une+t%C3%A2che+symfony+depuis+une+action'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://blog.overnetcity.com/02-07-2010/lancer-une-tache-symfony-depuis-une-action/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Comment lister les derniers articles WordPress sur un site en PHP ?</title>
		<link>http://blog.overnetcity.com/31-03-2010/comment-lister-les-derniers-articles-wordpress-sur-un-site-en-php/</link>
		<comments>http://blog.overnetcity.com/31-03-2010/comment-lister-les-derniers-articles-wordpress-sur-un-site-en-php/#comments</comments>
		<pubDate>Wed, 31 Mar 2010 11:29:19 +0000</pubDate>
		<dc:creator>Olivier Balais</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://blog.overnetcity.com/?p=43</guid>
		<description><![CDATA[De plus en plus de développeurs font le choix d&#8217;utiliser la plateforme WordPress pour développer l&#8217;ensemble d&#8217;un site internet et non pas seulement le blog. Cette démarche a l&#8217;intérêt de préserver très facilement une cohérence globale sur le site. Une seule gestion des utilisateurs, une seule gestion des commentaires, un seul routing&#8230; Pour ma part, [...]]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F31-03-2010%2Fcomment-lister-les-derniers-articles-wordpress-sur-un-site-en-php%2F' data-shr_title='Comment+lister+les+derniers+articles+Wordpress+sur+un+site+en+PHP+%3F'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F31-03-2010%2Fcomment-lister-les-derniers-articles-wordpress-sur-un-site-en-php%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F31-03-2010%2Fcomment-lister-les-derniers-articles-wordpress-sur-un-site-en-php%2F' data-shr_title='Comment+lister+les+derniers+articles+Wordpress+sur+un+site+en+PHP+%3F'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetTop Automatic --><p style="text-align: justify;">De plus en plus de développeurs font le choix d&#8217;utiliser la plateforme WordPress pour développer l&#8217;ensemble d&#8217;un site internet et non pas seulement le blog. Cette démarche a l&#8217;intérêt de préserver très facilement une cohérence globale sur le site. Une seule gestion des utilisateurs, une seule gestion des commentaires, un seul routing&#8230;</p>
<p style="text-align: justify;">Pour ma part, je préfère garder séparée la plateforme de blog WP du reste de mon site. Mais j&#8217;ai pourtant envie d&#8217;afficher la liste des derniers articles postés sur mon blog directement sur mon site. Comment faire ?</p>
<h1 style="text-align: justify;">Les solutions</h1>
<h2 style="text-align: justify;">Le flux RSS</h2>
<p style="text-align: justify;">Une des solutions qui semble la plus retenue par les développeurs est la récupération et le parsing du flux RSS généré automatiquement par WordPress. Ce choix présente de nombreux avantages comme la possibilité de choisir le flux adapté à son besoin : tri par tag, par auteur, par catégorie&#8230;</p>
<p style="text-align: justify;">En revanche, le parsing peut être un peu compliqué et semble moins performant qu&#8217;un accès direct en base. J&#8217;ai donc choisi d&#8217;utiliser une classe PHP qui récupère directement dans ma base de données WordPress les articles et informations associées. Si toutefois vous préférez la solution &#8220;Flux RSS&#8221;, sachez que de très nombreux exemples pourront être dénichés sur les forums francophones dédiés à WordPress ou sur Google en général.</p>
<h2 style="text-align: justify;">Récupération en base</h2>
<p style="text-align: justify;">La deuxième solution consiste donc à se connecter directement à la base de données de WordPress pour y récupérer à la demande les derniers articles et les informations associées.</p>
<p style="text-align: justify;">En cherchant sur Google je suis tombé sur un projet de <strong>Peter Upfold</strong> dédié à ce sujet. Développé en PHP, cette classe permet après configuration de générer automatiquement le code HTML permettant de lister les derniers articles de son blog. Si vous cherchez une solution clé en main, je vous invite à consulter directement son site :</p>
<p style="text-align: justify;"><a href="http://peter.upfold.org.uk/projects/wpget">http://peter.upfold.org.uk/projects/wpget</a></p>
<p style="text-align: justify;">Vous trouverez même à cette adresse un script permettant de générer automatiquement le fichier de configuration adapté à votre serveur (adresse base de données, nom d&#8217;utilisateurs, password&#8230;) :</p>
<p style="text-align: justify;"><a href="http://peter.upfold.org.uk/projects/wpget/installer">http://peter.upfold.org.uk/projects/wpget/installer</a></p>
<p style="text-align: justify;"><a href="http://blog.overnetcity.com/wp-content/uploads/2010/03/wpget3.jpg"><img class="alignnone size-full wp-image-47" title="WPGet Installer" src="http://blog.overnetcity.com/wp-content/uploads/2010/03/wpget3.jpg" alt="WPGet Installer" width="563" height="277" /></a></p>
<p style="text-align: justify;">Une fois le fichier wpget.php configuré, vous n&#8217;aurez plus qu&#8217;à écrire dans le code un bout de script semblable à celui ci-dessous pour insérer la liste de vos derniers articles correctement formatée en HTML :</p>
<pre class="brush: php; ">

&lt;?php include_once(&quot;./wpget.php&quot;);
$wpget = new wpGet;
$wpget-&gt;dateformat = &quot;d/m/Y H:i&quot;;
$wpget-&gt;showcredit = false;
$wpget-&gt;getWordpressEntries(2, 200, true, true, true); ?&gt;
</pre>
<p style="text-align: justify;">Pour ma part, je cherchais une classe plus simple que je pourrai utiliser dans mon application symfony et qui me laisserai gérer la partie présentation manuellement. J&#8217;ai donc réécrit entièrement la classe de <strong>Peter Upfold</strong> pour finalement obtenir deux petites classes PHP 5 (tant qu&#8217;à faire !). La première gère la récupération des données en base et la deuxième représente de manière simple un article WordPress avec les getters et setters associés.</p>
<p style="text-align: justify;">Je vous livre le code tel quel ci-dessous :</p>
<pre class="brush: php; ">

&lt;?php

/*
Réécriture de la classe PHP de Peter Upfold (http://peter.upfold.org.uk)
pour récupérer la liste des derniers articles postés sur un blog WordPress.

@author: Olivier Balais (http://blog.overnetcity.com)
*/
class WPEntries
{
  protected $dbUser;
  protected $dbPwd;
  protected $dbHost;
  protected $dbName;
  protected $dbTablesPrefix;

  protected $connection;

  // Fonction trouvée à l&#039;origine sur http://uk2.php.net/manual/en/function.substr.php#59719
  private static function html_substr($posttext, $minimum_length = 200, $length_offset = 20, $cut_words = false, $dots = true)
  {
    // $minimum_length:
    // The approximate length you want the concatenated text to be

    // $length_offset:
    // The variation in how long the text can be in this example text
    // length will be between 200 and 200-20=180 characters and the
    // character where the last tag ends

    // Reset tag counter &amp;amp;amp; quote checker
    $tag_counter = 0;
    $quotes_on = false;
    // Check if the text is too long
    if (strlen($posttext) &gt; $minimum_length) {
      // Reset the tag_counter and pass through (part of) the entire text
      $c = 0;
      for ($i = 0; $i &lt; strlen($posttext); $i++) {
        // Load the current character and the next one
        // if the string has not arrived at the last character
        $current_char = substr($posttext,$i,1);
        if ($i &lt; strlen($posttext) - 1) {
          $next_char = substr($posttext,$i + 1,1);
        }
        else {
          $next_char = &quot;&quot;;
        }
        // First check if quotes are on
        if (!$quotes_on) {
          // Check if it&#039;s a tag
          // On a &quot;&lt;&quot; add 3 if it&#039;s an opening tag (like &lt;a href...)
          // or add only 1 if it&#039;s an ending tag (like &lt;/a&gt;)
          if ($current_char == &#039;&lt;&#039;) {
            if ($next_char == &#039;/&#039;) {
              $tag_counter += 1;
            }
            else {
              $tag_counter += 3;
            }
          }
          // Slash signifies an ending (like &lt;/a&gt; or ... /&gt;)
          // substract 2
          if ($current_char == &#039;/&#039; &amp;amp;amp;&amp;amp;amp; $tag_counter &lt;&gt; 0) $tag_counter -= 2;
          // On a &quot;&gt;&quot; substract 1
          if ($current_char == &#039;&gt;&#039;) $tag_counter -= 1;
          // If quotes are encountered, start ignoring the tags
          // (for directory slashes)
          if ($current_char == &#039;&quot;&#039;) $quotes_on = true;
        }
        else {
          // IF quotes are encountered again, turn it back off
          if ($current_char == &#039;&quot;&#039;) $quotes_on = false;
        }

        // Count only the chars outside html tags
        if($tag_counter == 2 || $tag_counter == 0){
          $c++;
        }

        // Check if the counter has reached the minimum length yet,
        // then wait for the tag_counter to become 0, and chop the string there
        if ($c &gt; $minimum_length - $length_offset &amp;amp;amp;&amp;amp;amp; $tag_counter == 0 &amp;amp;amp;&amp;amp;amp; ($next_char == &#039; &#039; || $cut_words == true)) {
          $posttext = substr($posttext,0,$i + 1);
          if($dots){
            $posttext .= &#039;...&#039;;
          }
          return $posttext;
        }
      }
    }
    return $posttext;
  }

  private static function convert_smart_quotes($string) // not mine either - thanks to Chris Shiflett at http://shiflett.org/archive/165
  {
    $search = array(chr(145),
    chr(146),
    chr(147),
    chr(148),
    chr(151));

    $replace = array(&#039;‘&#039;,
    &#039;’&#039;,
    &#039;“&#039;,
    &#039;”&#039;,
    &#039;—&#039;);

    return str_replace($search, $replace, $string);
  }

  public function __construct($dbUser = &quot;&quot;, $dbPwd = &quot;&quot;, $dbHost = &quot;localhost&quot;, $dbName = &quot;wordpress&quot;, $dbTablesPrefix = &quot;wp_&quot;)
  {
    $this-&gt;dbUser         = $dbUser;
    $this-&gt;dbPwd          = $dbPwd;
    $this-&gt;dbHost         = $dbHost;
    $this-&gt;dbName         = $dbName;
    $this-&gt;dbTablesPrefix = $dbTablesPrefix;

  }

  public function getLastEntries($number = 2, $limit = null, $stripJavascript = true, $stripImages = true, $stripEmbed = true)
  {
    // Connexion à la base de données
    try
    {
      $connection = new PDO(&#039;mysql:host=&#039;.$this-&gt;dbHost.&#039;;dbname=&#039;.$this-&gt;dbName, $this-&gt;dbUser, $this-&gt;dbPwd);
    }
    catch(Exception $e)
    {
      echo $e-&gt;getMessage();
      die();
    }

    // Préparation de la requête
    $request = $connection-&gt;prepare(&quot;SELECT `post_content`, `post_date`, `post_title`, `display_name`, `comment_count`, `guid`
    FROM `&quot;.$this-&gt;dbTablesPrefix.&quot;posts` as posts
    INNER JOIN `&quot;.$this-&gt;dbTablesPrefix.&quot;users` as users ON users.ID = posts.post_author
    WHERE posts.`post_status` = &#039;publish&#039; AND posts.`post_type` = &#039;post&#039;
    ORDER BY `post_date` DESC LIMIT &quot;.$number.&quot;;&quot;);

    // Récupération des articles
    $articles = array();

    try
    {
      $request-&gt;execute(array());
    }
    catch(Exception $e)
    {
      echo $e-&gt;getMessage();
      die();
    }

    while ($result = $request-&gt;fetch(PDO::FETCH_OBJ))
      {
      $content = $result-&gt;post_content;

      if ($limit &gt; 0)
      {
        $content = stripslashes(self::html_substr($content, $limit, 20));
        $content = self::convert_smart_quotes($content);
      }
      else
      {
        $content = self::convert_smart_quotes($content);
      }

      if ($stripJavascript)
        $content = ereg_replace(&quot;&lt;script.*&lt;/script&gt;&quot;, &quot;&quot;, $content);

      if ($stripImages)
        $content = ereg_replace(&quot;&lt;img.*/&gt;&quot;, &quot;&quot;, $content);

      if ($stripEmbed)
        $content = ereg_replace(&quot;&lt;embed.*&lt;/embed&gt;&quot;, &quot;&quot;, $content);

      $article =
        new WordPressArticle($content,
        $result-&gt;post_date,
        $result-&gt;post_title,
        $result-&gt;display_name,
        $result-&gt;comment_count,
        $result-&gt;guid);

      $articles[] = $article; // Ajout de l&#039;élément à la liste à retourner
    }

    return $articles;
  }
}

class WordPressArticle
{
  protected $content;
  protected $postDate;
  protected $postTitle;
  protected $authorName;
  protected $commentsCount;
  protected $link;

  public function __construct($content = &quot;&quot;, $postDate = &quot;&quot;, $postTitle = &quot;&quot;, $authorName = &quot;&quot;, $commentsCount = &quot;&quot;, $link = &quot;&quot;)
  {
    $this-&gt;content = $content;
    $this-&gt;postDate = $postDate;
    $this-&gt;postTitle = $postTitle;
    $this-&gt;authorName = $authorName;
    $this-&gt;commentsCount = $commentsCount;
    $this-&gt;link = $link;
  }

  public function setContent($content)
  {
    $this-&gt;content = $content;
  }

  public function getContent()
  {
    return nl2br($this-&gt;content);
  }

  public function setPostDate($postDate)
  {
    $this-&gt;postDate = $postDate;
  }

  public function getPostDate()
  {
    return $this-&gt;postDate;
  }

  public function setPostTitle($postTitle)
  {
    $this-&gt;postTitle = $postTitle;
  }

  public function getPostTitle()
  {
    return $this-&gt;postTitle;
  }

  public function setAuthorName($authorName)
  {
    $this-&gt;authorName = $authorName;
  }

  public function getAuthorName()
  {
    return $this-&gt;authorName;
  }

  public function setCommentsCount($commentsCount)
  {
    $this-&gt;commentsCount = $commentsCount;
  }

  public function getCommentsCount()
  {
    return $this-&gt;commentsCount;
  }

  public function setLink($link)
  {
    $this-&gt;link = $link;
  }

  public function getLink()
  {
    return $this-&gt;link;
  }
}
</pre>
<p style="text-align: justify;">Ci-dessous, un exemple de fonctionnement simplissime dans une application symfony.</p>
<p style="text-align: justify;">Dans l&#8217;action :</p>
<pre class="brush: php; ">

/**
* Executes index action
*
*/
public function executeIndex()
{
  $wpEntries= new WPEntries(&quot;db_user&quot;, &quot;db_pwd&quot;, &quot;localhost&quot;, &quot;wordpress&quot;, &quot;wp_&quot;);
  $this-&gt;entries = $wpEntries-&gt;getLastEntries();
}
</pre>
<p style="text-align: justify;">Dans la vue :</p>
<pre class="brush: php; ">

&lt;ul&gt;
 &lt;?php foreach($entries as $entry): ?&gt;
 &lt;li&gt;&lt;?php echo $entry-&gt;getPostTitle() ?&gt;&lt;/li&gt;
 &lt;?php endforeach ?&gt;
/ul&gt;
</pre>
<p>Tout simplement !<br />
N&#8217;hésitez pas à utiliser ce bout de code et à me faire un retour le cas échéant.</p>
<div class="shr-publisher-43"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F31-03-2010%2Fcomment-lister-les-derniers-articles-wordpress-sur-un-site-en-php%2F' data-shr_title='Comment+lister+les+derniers+articles+Wordpress+sur+un+site+en+PHP+%3F'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F31-03-2010%2Fcomment-lister-les-derniers-articles-wordpress-sur-un-site-en-php%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F31-03-2010%2Fcomment-lister-les-derniers-articles-wordpress-sur-un-site-en-php%2F' data-shr_title='Comment+lister+les+derniers+articles+Wordpress+sur+un+site+en+PHP+%3F'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://blog.overnetcity.com/31-03-2010/comment-lister-les-derniers-articles-wordpress-sur-un-site-en-php/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

