<?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>Blog de Florent Viel</title>
	<atom:link href="http://blog.luxifer.fr/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.luxifer.fr</link>
	<description>Ma vie, mes délires</description>
	<lastBuildDate>Tue, 07 Feb 2012 15:34:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Minification des javascript a la volée dans symfony 1.4</title>
		<link>http://blog.luxifer.fr/2012/02/07/minification-des-javascript-a-la-volee-dans-symfony-1-4/</link>
		<comments>http://blog.luxifer.fr/2012/02/07/minification-des-javascript-a-la-volee-dans-symfony-1-4/#comments</comments>
		<pubDate>Tue, 07 Feb 2012 12:55:19 +0000</pubDate>
		<dc:creator>LuXiFeR</dc:creator>
				<category><![CDATA[Dev]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[compilation]]></category>
		<category><![CDATA[compression]]></category>
		<category><![CDATA[minification]]></category>
		<category><![CDATA[optimisation]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[serveur]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://blog.luxifer.fr/?p=252</guid>
		<description><![CDATA[Salut à tous! Ajourd&#8217;hui on va parler webperf et notamment temps de chargement des pages. Quand on développe en javascript on utilise souvent jQuery comme framework qui assure la compatibilité de son application sur presque tous les navigateurs. Qui simplifie certains fonctionnement, etc. Et souvent quand on utilise ce framework on ne prend pas la [...]]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://blog.luxifer.fr/wp-content/uploads/2012/02/2378867408_5d2ac25d2f_o.jpg" width="240" />
		</p><p>Salut à tous! Ajourd&#8217;hui on va parler webperf et notamment temps de chargement des pages. Quand on développe en javascript on utilise souvent jQuery comme framework qui assure la compatibilité de son application sur presque tous les navigateurs. Qui simplifie certains fonctionnement, etc. Et souvent quand on utilise ce framework on ne prend pas la peine de redévelopper l&#8217;existant, on va chercher un plugin. Et forcément au final on se retrouve avec l&#8217;inclusion de 15 javascripts par page ce qui ralenti considérablement le temps de chargement. Je fais la passe sur la configuration du serveur web, on va considéré que de ce côté là la durée d&#8217;expiration est précisée, la compression activée, etc. Reste que même si la requête est faite sur le cache du navigateur, ça fait quand même une requête.</p>
<p>Deuxième point, la plupart du temps les plugins fournis ne sont pas minifiés, c&#8217;est à dire que le code est lisible et compréhensible. Une minification simple consiste a raccourcir les noms de variable et supprimer les espaces blancs et sauts de ligne. De ce fait on peu avoir un gain non négligeable sur la taille du javascript.</p>
<p>Le problème qui se pose c&#8217;est le passage en production du site. Quelles sont les posibilités  avec symfony 1.4 pour minifier et compresser les javascripts de façon automatique ? Le plus simple serait de passer par un service ou un programme et de minifier à la main chaque javascript avant de déployer. Pour peu que les mises en production soient régulières, ce processus devient vite barbant. Le fait est aussi qu&#8217;il y aura toujours autant de requêtes de faites pour récupérer les javascripts au chargement de la page. Et le plus long n&#8217;est pas le téléchargement de la ressource mais l&#8217;attente de la réponse du serveur. Je me suis donc sit qu&#8217;il fallait minifier et commpresser tous les javascripts dans un seul fichier. Le problème c&#8217;est que pour un gros site, suivant les pages, il n&#8217;y aura pas les mêmes javascripts d&#8217;appelés. Et donc comment faire pour parcourir toutes les pages différentes du site de façon automatique ? Le plus simple c&#8217;est de laisser cette tâche à l&#8217;utilisateur. Comprenez au premier affichage d&#8217;une page on va lancer une tâche de minification des javascripts et mettre un fallback avec les javascripts non minifiés pour que le site fonctionne toujours correctement. Une fois cette tâche terminée le prochain affichage de cette même page va appeler l&#8217;unique javascript minifié.</p>
<p>La se pose plusieurs problèmes. Comment savoir qu&#8217;une page ne contient pas les mêmes javascripts qu&#8217;une autre ? On va calculer un hash MD5 de tous les javascripts de la page qui est demandée, lancer le processus et stocker le résultat avec comme nom de fichier le hash calculé précédemment.</p>
<p>Deuxième problème, comment savoir qu&#8217;il n&#8217;y a pas déjà une tâche de lancée ? Il y a plusieurs possibilités, mais après avoir essayé <em>flock() </em>ou d&#8217;autres technique plutôt propres, je n&#8217;ai pas eu d&#8217;autres choix que de faire mon propre système de lock. C&#8217;est à dire, au lancement de la tâche, je vérifie que le fichier de lock avec le hash n&#8217;existe pas, s&#8217;il n&#8217;est pas présent je le crée et je commence la tâche de minification. Sinon le processus se termine. Avec cette technique on est sûr qu&#8217;un seul processus va essayer d&#8217;ouvrir le fichier pour y stocker le résultat de la minification. Si le site a pas mal de visite, la génération de tous les javascripts devrait se faire assez vite pour les différentes pages.</p>
<p>Le dernier point à aborder, c&#8217;est la mise a jour de ces javascripts minifiés. Si on modifie un javascript, au prochain déploiement vu que les javascripts minifiés existent déjà, il ne sera pas pris en compte. Il suppit juste de passer une petite tâche des javascripts minifiés à chaque déploiement et c&#8217;est réglé.</p>
<p>Pour le code, voici les différents fichier :<br />
Tout d&#8217;abord le <em>AssetHelper.php</em></p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="kw2">function</span> get_javascripts<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
  <span class="re0">$response</span> <span class="sy0">=</span> sfContext<span class="sy0">::</span><span class="me2">getInstance</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">getResponse</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="re0">$host</span> <span class="sy0">=</span> sfContext<span class="sy0">::</span><span class="me2">getInstance</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">getRequest</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">getHost</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
  sfConfig<span class="sy0">::</span><span class="me2">set</span><span class="br0">&#40;</span><span class="st_h">'symfony.asset.javascripts_included'</span><span class="sy0">,</span> <span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
  <span class="re0">$params</span> <span class="sy0">=</span> <span class="st_h">''</span><span class="sy0">;</span>
  <span class="re0">$absolute</span> <span class="sy0">=</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="re0">$html</span> <span class="sy0">=</span> <span class="st_h">''</span><span class="sy0">;</span>
  <span class="re0">$fallback</span> <span class="sy0">=</span> <span class="st_h">''</span><span class="sy0">;</span>
  <span class="kw1">foreach</span> <span class="br0">&#40;</span><span class="re0">$response</span><span class="sy0">-&gt;</span><span class="me1">getJavascripts</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="kw1">as</span> <span class="re0">$file</span> <span class="sy0">=&gt;</span> <span class="re0">$options</span><span class="br0">&#41;</span>
  <span class="br0">&#123;</span>
    <span class="re0">$absolute</span><span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="sy0">=</span> javascript_path<span class="br0">&#40;</span><span class="re0">$file</span><span class="sy0">,</span> <span class="kw4">false</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="re0">$params</span> <span class="sy0">.=</span> <span class="st_h">'&amp;code_url=http://'</span><span class="sy0">.</span><span class="re0">$host</span><span class="sy0">.</span>javascript_path<span class="br0">&#40;</span><span class="re0">$file</span><span class="sy0">,</span> <span class="kw4">false</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="re0">$fallback</span> <span class="sy0">.=</span> javascript_include_tag<span class="br0">&#40;</span><span class="re0">$file</span><span class="sy0">,</span> <span class="re0">$options</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span>
  <span class="kw3">sort</span><span class="br0">&#40;</span><span class="re0">$absolute</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="re0">$absolute</span> <span class="sy0">=</span> <span class="kw3">http_build_query</span><span class="br0">&#40;</span><span class="re0">$absolute</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="re0">$md5</span> <span class="sy0">=</span> <span class="kw3">md5</span><span class="br0">&#40;</span><span class="re0">$absolute</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="re0">$path</span> <span class="sy0">=</span> <span class="st_h">'/uploads/min.'</span><span class="sy0">.</span><span class="re0">$md5</span><span class="sy0">.</span><span class="st_h">'.js'</span><span class="sy0">;</span>
  <span class="re0">$generate</span> <span class="sy0">=</span> <span class="kw3">file_exists</span><span class="br0">&#40;</span><span class="kw3">getcwd</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">.</span><span class="re0">$path</span><span class="br0">&#41;</span> ? <span class="kw4">false</span> <span class="sy0">:</span> <span class="kw4">true</span><span class="sy0">;</span>
&nbsp;
  <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$generate</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="re0">$param_array</span> <span class="sy0">=</span> <span class="kw3">array</span><span class="br0">&#40;</span>
      <span class="st_h">'output_format'</span> <span class="sy0">=&gt;</span> <span class="st_h">'json'</span><span class="sy0">,</span>
      <span class="st_h">'compilation_level'</span> <span class="sy0">=&gt;</span> <span class="st_h">'SIMPLE_OPTIMIZATIONS'</span><span class="sy0">,</span>
      <span class="st_h">'output_info'</span> <span class="sy0">=&gt;</span> <span class="st_h">'compiled_code'</span>
    <span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="re0">$params</span> <span class="sy0">=</span> <span class="kw3">http_build_query</span><span class="br0">&#40;</span><span class="re0">$param_array</span><span class="br0">&#41;</span><span class="sy0">.</span><span class="re0">$params</span><span class="sy0">;</span>
    <span class="re0">$exec</span> <span class="sy0">=</span> <span class="st_h">'/usr/bin/php -f '</span><span class="sy0">.</span><span class="kw3">getcwd</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">.</span><span class="st_h">'/../lib/genMinifiedJs.php &quot;'</span><span class="sy0">.</span><span class="re0">$params</span><span class="sy0">.</span><span class="st_h">'&quot; &quot;'</span><span class="sy0">.</span><span class="kw3">getcwd</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">.</span><span class="re0">$path</span><span class="sy0">.</span><span class="st_h">'&quot; 2&amp;&gt; /dev/null &amp;'</span><span class="sy0">;</span>
    <span class="kw3">popen</span><span class="br0">&#40;</span><span class="re0">$exec</span><span class="sy0">,</span> <span class="st_h">'r'</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="re0">$html</span> <span class="sy0">=</span> <span class="re0">$fallback</span><span class="sy0">;</span>
  <span class="br0">&#125;</span>
  <span class="kw1">else</span> <span class="br0">&#123;</span>
    <span class="re0">$html</span> <span class="sy0">=</span> javascript_include_tag<span class="br0">&#40;</span><span class="re0">$path</span><span class="sy0">,</span> <span class="re0">$options</span><span class="br0">&#41;</span><span class="sy0">.</span><span class="re0">$html</span><span class="sy0">;</span>
  <span class="br0">&#125;</span>
&nbsp;
  <span class="kw1">return</span> <span class="re0">$html</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div></div></div></div></div></div>


<p>Ensuite la tâche de minification <em>genMinifiedJs.php</em> à placer à la racine du répertoire lib du projet symfony</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1">#!/usr/bin/env php
<span class="kw2">&lt;?php</span>
&nbsp;
<span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$argc</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
  <span class="re0">$params</span> <span class="sy0">=</span> <span class="re0">$argv</span><span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="sy0">;</span>
  <span class="re0">$path</span> <span class="sy0">=</span> <span class="re0">$argv</span><span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span><span class="sy0">;</span>
&nbsp;
  <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="kw3">file_exists</span><span class="br0">&#40;</span><span class="re0">$path</span><span class="sy0">.</span><span class="st_h">'.lock'</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw3">touch</span><span class="br0">&#40;</span><span class="re0">$path</span><span class="sy0">.</span><span class="st_h">'.lock'</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">//Création d'un fichier de lock pour empecher toute autre instance de travailler en meme temps</span>
&nbsp;
    <span class="re0">$ch</span> <span class="sy0">=</span> <span class="kw3">curl_init</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="kw3">curl_setopt</span><span class="br0">&#40;</span><span class="re0">$ch</span><span class="sy0">,</span> CURLOPT_URL<span class="sy0">,</span> <span class="st_h">'http://closure-compiler.appspot.com/compile'</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="kw3">curl_setopt</span><span class="br0">&#40;</span><span class="re0">$ch</span><span class="sy0">,</span> CURLOPT_HEADER<span class="sy0">,</span> <span class="kw4">false</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="kw3">curl_setopt</span><span class="br0">&#40;</span><span class="re0">$ch</span><span class="sy0">,</span> CURLOPT_POST<span class="sy0">,</span> <span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="kw3">curl_setopt</span><span class="br0">&#40;</span><span class="re0">$ch</span><span class="sy0">,</span> CURLOPT_POSTFIELDS<span class="sy0">,</span> <span class="re0">$params</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="kw3">curl_setopt</span><span class="br0">&#40;</span><span class="re0">$ch</span><span class="sy0">,</span> CURLOPT_RETURNTRANSFER<span class="sy0">,</span> <span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="re0">$retour</span> <span class="sy0">=</span> <span class="kw3">curl_exec</span><span class="br0">&#40;</span><span class="re0">$ch</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="kw3">curl_close</span><span class="br0">&#40;</span><span class="re0">$ch</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    <span class="re0">$retour</span> <span class="sy0">=</span> <span class="kw3">json_decode</span><span class="br0">&#40;</span><span class="re0">$retour</span><span class="sy0">,</span> <span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw3">array_key_exists</span><span class="br0">&#40;</span><span class="st_h">'compiledCode'</span><span class="sy0">,</span> <span class="re0">$retour</span><span class="br0">&#41;</span> <span class="sy0">&amp;&amp;</span> <span class="sy0">!</span><span class="kw3">empty</span><span class="br0">&#40;</span><span class="re0">$retour</span><span class="br0">&#91;</span><span class="st_h">'compiledCode'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="co1">//Vérification du retour de google closure compiler</span>
      <span class="re0">$fp</span> <span class="sy0">=</span> <span class="kw3">fopen</span><span class="br0">&#40;</span><span class="re0">$path</span><span class="sy0">,</span> <span class="st_h">'a'</span><span class="br0">&#41;</span><span class="sy0">;</span>
      <span class="kw3">fwrite</span><span class="br0">&#40;</span><span class="re0">$fp</span><span class="sy0">,</span> <span class="re0">$retour</span><span class="br0">&#91;</span><span class="st_h">'compiledCode'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span>
      <span class="kw3">fclose</span><span class="br0">&#40;</span><span class="re0">$fp</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
    <span class="kw1">else</span> <span class="br0">&#123;</span>
      <span class="kw3">unlink</span><span class="br0">&#40;</span><span class="re0">$path</span><span class="sy0">.</span><span class="st_h">'.lock'</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">//Suppression du fichier de lock en cas d'échec de compilation pour autoriser une nouvelle génération</span>
    <span class="br0">&#125;</span>
  <span class="br0">&#125;</span>
  <span class="kw1">else</span> <span class="br0">&#123;</span>
    <span class="kw3">die</span><span class="sy0">;</span> <span class="co1">//Une instance existe déja, on quitte le navire</span>
  <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre></div></div></div></div></div></div></div>


<p>Et voilà, maintenant, à chaque page un seule javascript sera chargé et une fois qu&#8217;il sera mis en cache par le navigateur, le temps de chargement du site sera bien réduit.</p>
<p>Dernier point technique, j&#8217;ai utilisé l&#8217;API REST <a href="http://code.google.com/closure/compiler/">Google Closure Compiler</a> pour minifier mes javascripts. Je vous laisse voir la <a href="http://code.google.com/closure/compiler/docs/api-ref.html">documentation</a> pour modifier les paramètres a envoyer. Il y a aussi la possibilité de télécharger le compiler en java et d&#8217;utiliser celui-ci pour la génération, mais pour des questions techniques et pour alléger le serveur je préfère faire une requête externe plutôt que de charger du java&#8230;</p>
<p>Faites en bon usage !!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.luxifer.fr/2012/02/07/minification-des-javascript-a-la-volee-dans-symfony-1-4/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Retours Startup Weekend Lyon</title>
		<link>http://blog.luxifer.fr/2012/01/26/retours-startup-weekend-lyon/</link>
		<comments>http://blog.luxifer.fr/2012/01/26/retours-startup-weekend-lyon/#comments</comments>
		<pubDate>Thu, 26 Jan 2012 13:04:01 +0000</pubDate>
		<dc:creator>LuXiFeR</dc:creator>
				<category><![CDATA[Party]]></category>
		<category><![CDATA[startup]]></category>
		<category><![CDATA[entreprenership]]></category>
		<category><![CDATA[entrepreneur]]></category>
		<category><![CDATA[lyon]]></category>
		<category><![CDATA[pitch]]></category>
		<category><![CDATA[projet]]></category>
		<category><![CDATA[week end]]></category>

		<guid isPermaLink="false">http://blog.luxifer.fr/?p=234</guid>
		<description><![CDATA[Salut à tous ! Certes il est un peu tard pour faire un compte-rendu du startup week-end de lyon du 7-8-9 octobre 2011, mais je tiens quand même à partager certains points de ce week-end qui fût très intéressant et très enrichissant. Tout d&#8217;abord l&#8217;événement comment le vendredi soir à partir de 19h pour un [...]]]></description>
			<content:encoded><![CDATA[<p>Salut à tous !</p>
<p>Certes il est un peu tard pour faire un compte-rendu du startup week-end de lyon du 7-8-9 octobre 2011, mais je tiens quand même à partager certains points de ce week-end qui fût très intéressant et très enrichissant.</p>
<p>Tout d&#8217;abord l&#8217;événement comment le vendredi soir à partir de 19h pour un petit pitch des organisateurs sur le déroulement du week-end et des retours de personnes ayant participé à la précédente édition. Petit point sympa durant ce pitch, sur la projection du vidéo on voyait défilé les derniers tweets postés comportant le hashtag #swlyon avec des effets de transition plutôt sympa. Deuxième étape du soir, le pitch par projet. Le but est symple, chaque personne qui a une idée passe sur scène et la présente en une minute top chrono en essayant d&#8217;intéresser le plus de monde possible pour qu&#8217;elle soit retenue par les organisateurs et pouvoir trouver des partenaires pour travailler sur le projet.</p>
<p>Nous étions environ 36 à pitcher, pour 13 projets à retenir au maximum. C&#8217;est la que commence la troisième étape. Munis de 3 &laquo;&nbsp;billets&nbsp;&raquo; nous permettant &laquo;&nbsp;d&#8217;investir&nbsp;&raquo; dans les idées qui nous ont plus durant les pitchs, il faut alors savoir attiré les investisseurs pour que son projet soit retenu et la c&#8217;est litéralement la guerre. Toutes les techniques sont bonnes pour récolter le plus de billets possible. Si on a déjà une équipe c&#8217;est assez facile, les membres de l&#8217;équipe investissent sur la personne qui a pitcher et les chances d&#8217;être sélectionné sont déjà plus élevées.</p>
<p>Cette bataille a duré a peu près une demi heure. Après ça, chaque personne qui a pitché ramène dans une enveloppe le total de billet qu&#8217;elle a récolté et les organisateurs procèdent ensuite a un vote en interne. Après l&#8217;annonce des 13 projets retenus, c&#8217;est l&#8217;heure de former les équipes. Soit durant la phase de sélection on a trouvé une idée intéressante, soit on continue de chercher et de se renseigner sur les projets qui ont été retenus.</p>
<p>Une fois les équipes formées on peut commencer à travailler sur le projet, sachant qu&#8217;à la fin du week-end, il faut présenter son projet devant des investisseurs et des professionnels. Mon idée de départ n&#8217;ayant pas été sélectionnée, j&#8217;ai rejoint le projet Citizens. L&#8217;idée de base c&#8217;est les sites institutionnels des villes sont moches, n&#8217;ont aucune ergonimie et souvent il manque des informations. Et donc la volonté c&#8217;est de fournir un portail standardisé pour les villes leur permettant de mettre en ligne du contenu facilement par rubriques tout en agrégeant différents flux comme twitter, yelp ou foursquare basé sur la géolocalisation.</p>
<p>Dans l&#8217;équipe qui s&#8217;est formée nous sommes étions donc 2 développeurs, 2 étudiants en marketing et un étudiant en dernière année de master en management, initiateur du projet. Commence donc le travail autour du projet, essayer de mettre à plat les idées, trouver un business model, etc. La soirée du vendredi se termine à 22h, direction la maison pour une courte nuit de repos avant re rattaquer le samedi matin à 8h.</p>
<p>Donc debout 6h tapante pour prendre le bus, arrivé trop tôt à Perrache, vient de temps de faire quelques provisions pour le week-end. Même si les repas sont compris dans l&#8217;inscription, le café, et autres besoins pour 48 sans dormir sont à la charge des participants. Donc j&#8217;arrive à Charpennes et là, pas moyen de trouver une épicerie ouverte à 6h30 du matin&#8230; Enfin après 10 minutes à tourner en rond je tombe sur un Casino ouvert. Miracle <img src='http://blog.luxifer.fr/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Donc 2kg de café et de quoi grignoter, direction l&#8217;INSA pour reprendre le projet. Je ne vais pas décrire le déroulement du week-end à partir d&#8217;ici mais plutôt les annecdotes vécues.</p>
<p>Point intéressant, plusieurs entrepreneurs sont là pour faire le tour des projets et répondre aux différentes questions et problèmatiques des participants. C&#8217;est vraiment sympa car quand tu viens de passer 2h sur une problèmatique en ne trouvant aucune solution, un point de vue extérieur avec de l&#8217;expérience dans la création d&#8217;entreprise fait gagner beaucoup de temps. Mais ça pose un autre problème, quand plusieurs entrepreneurs viennent répondre à la même problématique successivement, on récolte plusieurs points de vue différents dont certains contradictoires. Enfin c&#8217;est le risque mais au moins ça donne matière à réfléchir.</p>
<p>La journée se déroule en musique, les organisateurs ont créé une playlist spotify ouverte ou chaque participant peut y ajouter ses morceaux. Ca motive et ça permet de resté éveillé. Arrive 20h, ça fait maintenant 12h qu&#8217;on planche sur le projet et que les cerveaux fument de tous les côtés, il est temps de faire une petite pause. Direction le bar pour relâcher la pression et penser à autre chose une heure ou 2. Retour vers minuit à l&#8217;INSA pour reprendre le projet et commencer la partie intéressante, le développement ! Quelques heures pour mettre en place un mini portail fonctionnel pour la ville de Lyon, greffer différents flux de données, mettre en place l&#8217;édition de contenu, &#8230;</p>
<p>Durant ce week-end se livrait une petite bataille sur twitter avec l&#8217;édition de Nantes la semaine passée. A savoir le nombre de tweets comportant le hashtag #swlyon ou #swna Merci à Camille Roux pour son comparateur <a href="http://hashtagbattle.com/#battle/a/%23swlyon/%23swna">HashtagBattle</a>. Tout au long des deux jours le score de Lyon n&#8217;a pas beaucoup augmenté, par contre le soir des présentations, étant donné qu&#8217;il y avait un <a href="http://twitterfall.com/">mur des tweets</a>, le score s&#8217;est envolé.</p>
<p>La nuit fût longue, malgré le café, j&#8217;ai quand même dormi 2h sur des chaises entre 4 et 6h du matin. Le dimanche fût assez dur étant donné que le projet n&#8217;avait pas beaucoup avancé mais qu&#8217;il fallait quand même montré qualque chose. On a donc décidé de se focaliser sur le concept plutôt que d&#8217;essayer de faire une démo fonctionnelle. En bossant un maximum la présentation, en fournissant différents slides de l&#8217;interface du site et un business model qui tient la route.</p>
<p>Arrive 18h, l&#8217;heure de rendre les présentations, de faire les essais sur le projecteur et de manger un bout avant de présenter. Durant les présentation on peut voir les commentaires en direct sur le mur de tweet et ça clash sévère sur la moindre petite erreur. A commencer par Julie, la mascotte de la première équipe qui a présenté son projet. Qui a été reprise par les projets suivants, mais en la torturant et en faisant des jeux de mots plus ou moins douteux à son sujet. Enfin après 54 heures sans dormir ou presuqe, c&#8217;est compréhensible. Donc chaque équipe dispose de 20 minutes pour présenter et ensuite 10 minutes de questions. A la fin des présentations, tout le monde est bien fatigué et à envie de rentrer chez lui, mais il reste la délibération du jury pour choisir les 3 meilleurs projets. Jury composé de business angels, d&#8217;investisseurs, d&#8217;entrepreneurs et d&#8217;organisateurs de l&#8217;événement. Il est presque 21h quand les résultats sont annoncés. Le meilleur projet repartait avec de l&#8217;argent pour des formations, un article pour le lancement de son projet dans 2 magazines du groupe Lagardère et des livres sur l&#8217;entreprenariat.</p>
<p>Quoiqu&#8217;il en soit, tous les participants repartaient avec une Poke the Box de Seth Godin et un passe pour le salon Innorobo, salon sur la robotique qui se déroulera prochainement sur Lyon.</p>
<p>Bref ce week end fût intense, beaucoup de rencontres, beaucoup de données à engrange. Le monde de l&#8217;entreprenariat est vraiment génial, et le simple fait de partir d&#8217;une idée pour en arrivé à une startup en 54 heures est génial. Il m&#8217;aura fallu a peu près une semaine pour revenir à un rythme de vie a peu près normal, mais toujours des projets en tête que je compte mener à bien maintenant que je vais avoir un peu plus de temps pour moi.</p>
<p>Sur ce, bonne après midi <img src='http://blog.luxifer.fr/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.luxifer.fr/2012/01/26/retours-startup-weekend-lyon/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Direction la ville</title>
		<link>http://blog.luxifer.fr/2012/01/24/direction-la-ville/</link>
		<comments>http://blog.luxifer.fr/2012/01/24/direction-la-ville/#comments</comments>
		<pubDate>Tue, 24 Jan 2012 11:44:42 +0000</pubDate>
		<dc:creator>LuXiFeR</dc:creator>
				<category><![CDATA[Misc]]></category>
		<category><![CDATA[Vie quotidienne]]></category>

		<guid isPermaLink="false">http://blog.luxifer.fr/?p=231</guid>
		<description><![CDATA[Salut à tous ! Après plusieurs années à la &#171;&#160;campagne&#160;&#187; limitrophe de Lyon, chez mes parents ou en colocation. Je vais enfin habiter en ville !! Il était temps. C&#8217;est vrai que la demi heure de transport matin et soir qui me sépare de mon lieu de travail ne me dérange pas, mais pouvoir se [...]]]></description>
			<content:encoded><![CDATA[<p>Salut à tous !</p>
<p>Après plusieurs années à la &laquo;&nbsp;campagne&nbsp;&raquo; limitrophe de Lyon, chez mes parents ou en colocation. Je vais enfin habiter en ville !! Il était temps. C&#8217;est vrai que la demi heure de transport matin et soir qui me sépare de mon lieu de travail ne me dérange pas, mais pouvoir se lever à 8h pour commencer à 9h ça sera quand même apréciable. Je ne vais pas emménager seul puisque je prend cet appartement avec ma copine.</p>
<p>Pour la description, c&#8217;est un petit 50m2 dans le huitième arrondissement de Lyon vers la mairie. Dans un immeuble assez ancien mais tout l&#8217;intérieur est refait à neuf. Très grand sous plafond, salon avec bar, grande cuisine avec de grands plans de travail. La chambre donne sur la rue avec le tram, mais d&#8217;après les dires des anciens locataires, après une semaine d&#8217;adaptation on ne l&#8217;entend plus. Et la cerise sur le gâteau qui n&#8217;était pas sur l&#8217;annonce c&#8217;est une véranda et un jardin pour les 6 locataires de l&#8217;immeuble. Le tout pour 570€ par mois avec 30€ de charges, je trouve ça plutôt honnête pour cette taille en ville.</p>
<p>Bref, le déménagement se passe normalement la semaine prochaine, des photos à venir sur la décoration.<br />
PS: j&#8217;aurai sûrement besoin de mains pour le déménagement, faites signe dans les commentaires <img src='http://blog.luxifer.fr/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.luxifer.fr/2012/01/24/direction-la-ville/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Upload depuis le navigateur sur iOS</title>
		<link>http://blog.luxifer.fr/2012/01/17/upload-depuis-le-navigateur-sur-ios/</link>
		<comments>http://blog.luxifer.fr/2012/01/17/upload-depuis-le-navigateur-sur-ios/#comments</comments>
		<pubDate>Tue, 17 Jan 2012 12:32:55 +0000</pubDate>
		<dc:creator>LuXiFeR</dc:creator>
				<category><![CDATA[Dev]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[ipad]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[ipod]]></category>
		<category><![CDATA[navigateur]]></category>
		<category><![CDATA[photos]]></category>
		<category><![CDATA[pictures]]></category>
		<category><![CDATA[safari]]></category>
		<category><![CDATA[upload]]></category>

		<guid isPermaLink="false">http://blog.luxifer.fr/?p=210</guid>
		<description><![CDATA[Bonjour à tous, aujourd&#8217;hui je vais écrire un article plutôt incendiaire sur les différents choix faits par Apple concernant iOS. Je ne parlerai que d&#8217;un seul point car mon but n&#8217;est pas de créer un troll mais de partager la solution que j&#8217;ai trouvé pour pallier à ce problème. Je ne sais pas si vous [...]]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://blog.luxifer.fr/wp-content/uploads/2012/01/picup-app1.png" width="240" />
		</p><p><a href="http://blog.luxifer.fr/2012/01/17/upload-depuis-le-navigateur-sur-ios/picup-app/" rel="attachment wp-att-212"><img class="alignnone size-full wp-image-212" title="picup-app" src="http://blog.luxifer.fr/wp-content/uploads/2012/01/picup-app.png" alt="" width="320" height="480" /></a></p>
<p>Bonjour à tous, aujourd&#8217;hui je vais écrire un article plutôt incendiaire sur les différents choix faits par Apple concernant iOS. Je ne parlerai que d&#8217;un seul point car mon but n&#8217;est pas de créer un troll mais de partager la solution que j&#8217;ai trouvé pour pallier à ce problème.</p>
<p>Je ne sais pas si vous le savez, mais sur iPhone, iPod et iPad il est impossible de cliquer sur le bouton parcourir d&#8217;un formulaire sur une pag web pour joindre un fichier. Celui-ci est tout simplement grisé&#8230; On ne peut pas accéder a son arborescence de fichier depuis le navigateur safari sur iOS. Ceci est du au fait que ce système d&#8217;exploitation, chaque application possède son propre système de fichier et ne peut pas accéder au contenu d&#8217;une autre application. Je ne comprend pas le choix des développeurs Apple sur ce point là. Pourquoi brider l&#8217;expérience web mobile et de forcer à passer à des applications tierces pour pallier à ce problème.</p>
<p>Enfin arrêtons de &laquo;&nbsp;troller&nbsp;&raquo; mais j&#8217;ai trouvé une solution pour pouvoir contourner le bridage de Apple. Il s&#8217;agit de <a href="http://picupapp.com/index.html">Picup</a>. Cette application va transformer les champs <em>&lt;input type=&nbsp;&raquo;file&nbsp;&raquo;&gt;</em> en lien <em>fileupload://</em> qui va ensuite faire appel a l&#8217;appli installée sur le périphérique. Pour intégrer cette appli a son site internet il suffit d&#8217;ajouter le fichier javascript téléchargeable <a href="https://castle.so/dl/5tt6l+s" target="_blank">ici</a> sur la page contenant le formulaire. Et ensuite il suffit d&#8217;utiliser le helper pour générer l&#8217;url à passer a l&#8217;appli pour traiter le fichier.</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="javascript"><pre class="de1">$<span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
  Picup.<span class="me1">convertFileInput</span><span class="br0">&#40;</span><span class="st0">'input'</span><span class="sy0">,</span><span class="br0">&#123;</span>
    <span class="st0">'referername'</span><span class="sy0">:</span> escape<span class="br0">&#40;</span><span class="st0">'referer'</span><span class="br0">&#41;</span><span class="sy0">,</span>
    <span class="st0">'callbackurl'</span><span class="sy0">:</span> escape<span class="br0">&#40;</span><span class="st0">'url de callback'</span><span class="br0">&#41;</span><span class="sy0">,</span>
    <span class="st0">'postimageparam'</span><span class="sy0">:</span> <span class="st0">'file'</span><span class="sy0">,</span>
    <span class="st0">'posturl'</span><span class="sy0">:</span> escape<span class="br0">&#40;</span><span class="st0">'url de post'</span><span class="br0">&#41;</span><span class="sy0">,</span>
    <span class="st0">'postvalues'</span><span class="sy0">:</span> escape<span class="br0">&#40;</span><span class="st0">'paramètres additionnels a envoyer avec la requete POST'</span><span class="br0">&#41;</span><span class="sy0">,</span>
    <span class="st0">'purpose'</span><span class="sy0">:</span> escape<span class="br0">&#40;</span><span class="st0">'texte a afficher en dessous de l application'</span><span class="br0">&#41;</span><span class="sy0">,</span>
    <span class="st0">'referrerfavicon'</span><span class="sy0">:</span> escape<span class="br0">&#40;</span><span class="st0">'icone a afficher dans l application'</span><span class="br0">&#41;</span>
  <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>


<p>Ne pas oublier de faire de la détection de navigateur ajant d&#8217;ajouter ce script, car sur le navigateur natif android l&#8217;upload marche. Sur la page indiquée en callback, il peut être utile de créer une fonction de callback avec le helper picup pour faire un traitement supplémentaire sur les fichiers uploadés avec l&#8217;application.</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="javascript"><pre class="de1">Picup.<span class="me1">callbackHandler</span> <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">&#40;</span>params<span class="br0">&#41;</span><span class="br0">&#123;</span>
  <span class="kw1">for</span><span class="br0">&#40;</span><span class="kw2">var</span> key <span class="kw1">in</span> params<span class="br0">&#41;</span><span class="br0">&#123;</span>
    <span class="kw3">alert</span><span class="br0">&#40;</span>key<span class="sy0">+</span><span class="st0">' == '</span><span class="sy0">+</span>params<span class="br0">&#91;</span>key<span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre></div></div></div></div></div></div></div>


<p>Pour voir le résultat il y a une démo sur le site de l&#8217;application, avec un <a href="http://picupapp.com/scratchpad.html">scratchpad</a> qui permet de modifier les paramètres de la requête afin de faire les tests directement sur son serveur.</p>
<p>Voilà pour le côter javascript, il reste a écrire côter serveur la méthode qui va traiter la requête POST qui va être faite par picup et l&#8217;intégration est terminée. Le rendu est un bouton à la place du champ <em>&lt;input type=&nbsp;&raquo;file&nbsp;&raquo;&gt;</em> qui va ouvrir l&#8217;application et permettre à l&#8217;utilisateur de choisir une image parmis sa galerie.</p>
<p>Il y a quand même deux limites à cette technique, impossible de choisir plusieurs fichiers en même temps, et il est seulement possible de parcourir sa galerie. Donc impossible d&#8217;ajouter un pdf, un document ou tout autre type de fichier.</p>
<p>Voilà voilà <img src='http://blog.luxifer.fr/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Edit:</p>
<p>J&#8217;ai modifié le fichier javascript a inclure à son site, en utilisant le helper de la même manière, si l&#8217;application Picup n&#8217;est pas installée le visiteur est dirigé vers l&#8217;appstore.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.luxifer.fr/2012/01/17/upload-depuis-le-navigateur-sur-ios/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Intégrer Akismet dans Symfony 1.4</title>
		<link>http://blog.luxifer.fr/2012/01/10/integrer-akismet-dans-symfony-1-4/</link>
		<comments>http://blog.luxifer.fr/2012/01/10/integrer-akismet-dans-symfony-1-4/#comments</comments>
		<pubDate>Tue, 10 Jan 2012 12:57:56 +0000</pubDate>
		<dc:creator>LuXiFeR</dc:creator>
				<category><![CDATA[Dev]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[akismet]]></category>
		<category><![CDATA[spam]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://blog.luxifer.fr/?p=197</guid>
		<description><![CDATA[Bonjour à tous! Aujourd&#8217;hui je vais parler de l&#8217;intégration de Akismet dans Symfony 1.4 afin de réduire le spam sur ses commentaires. Si vous avez un blog wordpress vous devez sûrement savoir ce qu&#8217;est Akismet, sinon je vous invite à visiter le site officiel ici. Tout d&#8217;abord, il va falloir créer un compte pour récupérer [...]]]></description>
			<content:encoded><![CDATA[<p>Bonjour à tous!</p>
<p>Aujourd&#8217;hui je vais parler de l&#8217;intégration de Akismet dans Symfony 1.4 afin de réduire le spam sur ses commentaires. Si vous avez un blog wordpress vous devez sûrement savoir ce qu&#8217;est Akismet, sinon je vous invite à visiter le site officiel <a href="http://akismet.com/">ici</a>.</p>
<p>Tout d&#8217;abord, il va falloir créer un compte pour récupérer une clé d&#8217;API. Pour le développement j&#8217;ai choisi le plan &laquo;&nbsp;Personal&nbsp;&raquo; à 0€, mais si votre site fait du profit ou si vous faites la promotion d&#8217;un produit dessus vous devrez souscrire à une offre payante.</p>
<p>Une fois votre compte créé, vous recevez un mail avec votre clé API et vos informations personnelles. Conservez bien cette clé. Maintenant, on va passer à l&#8217;intégration dans symfony. C&#8217;est assez simple, vu qu&#8217;il y a déjà un plugin de disponible à cette <a href="http://plugins.symfony-project.org/get/drAkismetPlugin/drAkismetPlugin-0.3.3.tgz">adresse</a>. Donc je vous laisse télécharger le plugin et l&#8217;extraire dans le répertoire<em> plugins/</em> de votre projet symfony. Et ensuite bien renommer le dossier du plugin en &laquo;&nbsp;drAkismetPlugin&nbsp;&raquo;.</p>
<p>On va d&#8217;abord commencer par la configuration, donc ouvrez le fichier <em>akismet.yml.example</em> dans le sous-répertoire <em>config/</em> du plugin et enregistrez le en <em>akismet.yml</em>.</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="yaml"><pre class="de1"><span class="co4">akismet</span>:<span class="co4">
  user_agent</span>:<span class="co4">
    application</span>:<span class="co3">
      name</span><span class="sy2">: </span>drAkismetPlugin<span class="co3">
      version</span><span class="sy2">: </span>0.3.2<span class="co4">
    plugin</span>:<span class="co3">
      name</span><span class="sy2">: </span>Akismet<span class="co3">
      version</span><span class="sy2">: </span><span class="nu0">1.1</span>
<span class="co4">
  api_keys</span>:<span class="co3">
    www.example.com</span><span class="sy2">: </span><span class="co1">############</span><span class="co3">
    localhost</span><span class="sy2">: </span><span class="co1">#host utilisé pour le dev</span><span class="co3">
      host</span><span class="sy2">: </span>www.example.com<span class="co3">
      key</span><span class="sy2">: </span><span class="co1">############</span></pre></div></div></div></div></div></div></div>


<p>Maintenant le plugin configuré, il faut activé le plugin dans le fichier <em>config/projectConfiguration.class.php</em>.</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">enablePlugins</span><span class="br0">&#40;</span><span class="st_h">'drAkismetPlugin'</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>


<p>Maintenant que le plugin est activé et disponible, il faut se poser la question de comment on va l&#8217;intégrer à notre application. Pour ça il y a plusieurs possibilité, la plus simple c&#8217;est d&#8217;utiliser le <em>sfValidator</em> fourni avec le plugin. Il y a d&#8217;autres possibilité, mais je vais décrire l&#8217;intégration avec le validateur. Nous verrons les autres pour signaler à Akismet un Spam ou un Ham dans l&#8217;administration.</p>
<p>Donc pour utiliser le validateur, rien de plus simple, il s&#8217;utilise comme un validateur symfony classique. Ouvrez le <em>form</em> de votre projet et allez dans la méthode <em>configure()</em>.</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">validatorSchema</span><span class="br0">&#91;</span><span class="st_h">'text'</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="kw2">new</span> sfValidatorAnd<span class="br0">&#40;</span><span class="kw3">array</span><span class="br0">&#40;</span> <span class="co1">//text est le contenu du commentaire, adaptez à votre modèle</span>
  <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">validatorSchema</span><span class="br0">&#91;</span><span class="st_h">'text'</span><span class="br0">&#93;</span><span class="sy0">,</span>
  <span class="kw2">new</span> drAkismetValidatorSpam<span class="br0">&#40;</span><span class="kw3">array</span><span class="br0">&#40;</span>
    <span class="st_h">'blog'</span> <span class="sy0">=&gt;</span> <span class="st_h">'http://www.example.com'</span><span class="sy0">,</span>
    <span class="st_h">'user_ip'</span> <span class="sy0">=&gt;</span> <span class="re0">$_SERVER</span><span class="br0">&#91;</span><span class="st_h">'REMOTE_ADDR'</span><span class="br0">&#93;</span><span class="sy0">,</span>
    <span class="st_h">'referrer'</span> <span class="sy0">=&gt;</span> <span class="br0">&#40;</span><span class="kw3">array_key_exists</span><span class="br0">&#40;</span><span class="st_h">'HTTP_REFERER'</span><span class="sy0">,</span> <span class="re0">$_SERVER</span><span class="br0">&#41;</span> ? sfContext<span class="sy0">::</span><span class="me2">getInstance</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">getRequest</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">getReferer</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">:</span> sfContext<span class="sy0">::</span><span class="me2">getInstance</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">getRequest</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">getUri</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">,</span>
    <span class="st_h">'comment_author'</span> <span class="sy0">=&gt;</span> <span class="st_h">'John Doe'</span><span class="sy0">,</span> <span class="co1">//Nom de l'auteur du commentaire</span>
    <span class="st_h">'comment_author_email'</span> <span class="sy0">=&gt;</span> <span class="st_h">'john.doe@example.com'</span><span class="sy0">,</span> <span class="co1">//Email de l'auteur du commentaire</span>
    <span class="st_h">'comment_content'</span> <span class="sy0">=&gt;</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">getValue</span><span class="br0">&#40;</span><span class="st_h">'text'</span><span class="br0">&#41;</span>
  <span class="br0">&#41;</span><span class="br0">&#41;</span>
<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>


<p>Et voilà, maintenant dès que vous posterez un commentaire, si Akismet le déclare comme spam, le formulaire ne sera pas valide et le commentaire ne sera pas sauvegardé.</p>
<p>Maintenant on peut se dire qu&#8217;on a besoin de faire un peu plus que ne pas sauvegarder le commentaire. C&#8217;est possible, on peut écouter la requête avant qu&#8217;elle soit envoyée à Akismet et récupérer la réponse avant qu&#8217;elle ne soit traitée par le validateur. Pour ça j&#8217;ai du faire une petite modification du plugin pour qu&#8217;il récupère le dispatcher d&#8217;événement de l&#8217;application au lieux d&#8217;en créer un nouveau. Ouvrez le fichier <em>lib/api/connection/drAkismetApiSocketConnection.class.php</em> et remplacez le contenu du constructeur pa ça :</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="re0">$this</span><span class="sy0">-&gt;</span>_dispatcher <span class="sy0">=</span> sfContext<span class="sy0">::</span><span class="me2">getInstance</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">getEventDispatcher</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>


<p>Donc maintenant le dispatcher est connecté à symfony, il faut ensuite récupérer l&#8217;événement pour indiquer quelle méthode va l&#8217;écouter :</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">dispatcher</span><span class="sy0">-&gt;</span><span class="me1">connect</span><span class="br0">&#40;</span><span class="st_h">'akismet.pre_request'</span><span class="sy0">,</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'listenToPreRequest'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">dispatcher</span><span class="sy0">-&gt;</span><span class="me1">connect</span><span class="br0">&#40;</span><span class="st_h">'akismet.raw_response'</span><span class="sy0">,</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'listenToRawResponse'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>


<p>Maintenant qu&#8217;on écoute les événements et qu&#8217;on a défini les méthodes qui vont les traiter voici quelques méthodes utiles pour <em>parser</em> la réponser qu renvoit le serveur.</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="kw2">public</span> static <span class="kw2">function</span> listenToRawResponse<span class="br0">&#40;</span>sfEvent <span class="re0">$event</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
  <span class="re0">$rawResponse</span> <span class="sy0">=</span> <span class="kw2">new</span> drAkismetApiResponse<span class="br0">&#40;</span><span class="re0">$event</span><span class="br0">&#91;</span><span class="st_h">'response'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div></div></div></div></div></div>


<p>Voilà voilà, à votre tour d&#8217;intégrer Akismet à votre projet Symfony. Si vous avez des retours, n&#8217;hésitez pas à utiliser les commentaires.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.luxifer.fr/2012/01/10/integrer-akismet-dans-symfony-1-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

