<?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>Thu, 03 May 2012 14:37:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Partage de gros fichiers par mail</title>
		<link>http://blog.luxifer.fr/2012/05/03/partage-de-gros-fichiers-par-mail/</link>
		<comments>http://blog.luxifer.fr/2012/05/03/partage-de-gros-fichiers-par-mail/#comments</comments>
		<pubDate>Thu, 03 May 2012 14:36:16 +0000</pubDate>
		<dc:creator>LuXiFeR</dc:creator>
				<category><![CDATA[Dev]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[dev]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[fichier]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[gros]]></category>
		<category><![CDATA[partage]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://blog.luxifer.fr/?p=364</guid>
		<description><![CDATA[Bonjour, Aujourd&#8217;hui je viens de publier en open-source (licence GPLv3) un petit service de partage de gros fichiers par email. La problèmatique était la suivante, comment partager par mail et de façon sécurisée des gros fichiers sachant que la plupart des fournisseurs (gmail, hotmail, etc) limitent la taille des pièces jointes. Le but était aussi [...]]]></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/05/Capture-du-2012-05-03-163146.png" width="240" />
		</p><p>Bonjour,</p>
<p>Aujourd&#8217;hui je viens de publier en open-source (licence GPLv3) un petit service de partage de gros fichiers par email. La problèmatique était la suivante, comment partager par mail et de façon sécurisée des gros fichiers sachant que la plupart des fournisseurs (gmail, hotmail, etc) limitent la taille des pièces jointes. Le but était aussi de s&#8217;affranchir d&#8217;un éditeur de service qui possèderait les fichiers partagés. Avec un collègue de travail nous avons donc commencer ce projet.</p>
<p>Développé sur une base Symfony 2. Avec le minimum de bundles nécessaires. Le but était de rendre le service le plus léger possible et l&#8217;interface la plus simple. Le code source est disponible sur <a href="https://github.com/wanadev/sendbox" target="_blank">github</a>. Une version commerciale viendra dans un second temps.</p>
<p>Bon fork!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.luxifer.fr/2012/05/03/partage-de-gros-fichiers-par-mail/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Déployer un projet Symfony 2 avec Capifony</title>
		<link>http://blog.luxifer.fr/2012/04/25/deployer-un-projet-symfony-2-avec-capifony/</link>
		<comments>http://blog.luxifer.fr/2012/04/25/deployer-un-projet-symfony-2-avec-capifony/#comments</comments>
		<pubDate>Wed, 25 Apr 2012 11:46:09 +0000</pubDate>
		<dc:creator>LuXiFeR</dc:creator>
				<category><![CDATA[Dev]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[capifony]]></category>
		<category><![CDATA[capistrano]]></category>
		<category><![CDATA[déploiement]]></category>
		<category><![CDATA[déploy]]></category>
		<category><![CDATA[déployer]]></category>
		<category><![CDATA[gem]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[scm]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://blog.luxifer.fr/?p=350</guid>
		<description><![CDATA[Bonjour à tous! Aujourd&#8217;hui j&#8217;ai voulu tester capifony. C&#8217;est un petit programme basé sur capistrano qui permet de déployer facilement un projet symfony 1.4 ou 2 sur un serveur de production. Ce programme permet de gérer les releases de votre projet, de faire des rollback, de revenir sur unr version anciennement déployée, etc. Il est [...]]]></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/04/Capture-du-2012-04-25-161150.png" width="240" />
		</p><p>Bonjour à tous!</p>
<p>Aujourd&#8217;hui j&#8217;ai voulu tester <a href="http://capifony.org/" target="_blank">capifony</a>. C&#8217;est un petit programme basé sur <a href="https://github.com/capistrano/capistrano" target="_blank">capistrano</a> qui permet de déployer facilement un projet symfony 1.4 ou 2 sur un serveur de production. Ce programme permet de gérer les releases de votre projet, de faire des rollback, de revenir sur unr version anciennement déployée, etc. Il est écrit en ruby par un développeur de l&#8217;agence web <a href="http://knplabs.fr/" target="_blank">KnpLabs</a>.</p>
<p>Tout d&#8217;abord il faut installer la gem ruby :</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="bash"><pre class="de1">gem <span class="kw2">install</span> ruby</pre></div></div></div></div></div></div></div>


<p>Ensuite il faut se rendre dans le répertoire de son projet pour initialiser capifony.</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="bash"><pre class="de1"><span class="kw3">export</span> <span class="re2">PATH</span>=<span class="re1">$PATH</span>:~<span class="sy0">/</span>.gem<span class="sy0">/</span>ruby<span class="sy0">/</span>version<span class="sy0">/</span>bin
<span class="kw3">cd</span> <span class="sy0">/</span>path<span class="sy0">/</span>of<span class="sy0">/</span>project
capifony .</pre></div></div></div></div></div></div></div>


<p>Cette commande va créer un fichier <em>Capfile</em> à la racine de votre projet et un fichier <em>deploy.rb</em> dans le dossier <em>app/config/</em>, ou dans le dossier <em>config/</em> pour un projet symfony 1.4.</p>
<p>Ensuite il faut configurer le fichier deploy.rb afin de spécifier tous les paramètres nécessaires au déploiement.</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="ruby"><pre class="de1">set <span class="re3">:application</span>, <span class="st0">&quot;&quot;</span> <span class="co1"># nom de l'application</span>
set <span class="re3">:domain</span>, <span class="st0">&quot;&quot;</span> <span class="co1"># adresse du serveur de production</span>
set <span class="re3">:deploy_to</span>, <span class="st0">&quot;&quot;</span> <span class="co1"># répertoire ou déployer</span>
set <span class="re3">:app_path</span>, <span class="st0">&quot;app&quot;</span>
&nbsp;
set <span class="re3">:repository</span>, <span class="st0">&quot;&quot;</span> <span class="co1"># adresse du scm</span>
set <span class="re3">:scm</span>, <span class="re3">:git</span>
<span class="co1"># Or: `accurev`, `bzr`, `cvs`, `darcs`, `subversion`, `mercurial`, `perforce`, `subversion` or `none`</span>
set <span class="re3">:deploy_via</span>, <span class="re3">:copy</span>
&nbsp;
set <span class="re3">:model_manager</span>, <span class="st0">&quot;doctrine&quot;</span>
<span class="co1"># Or: `propel`</span>
&nbsp;
role <span class="re3">:web</span>, domain <span class="co1"># Your HTTP server, Apache/etc</span>
role <span class="re3">:app</span>, domain <span class="co1"># This may be the same as your `Web` server</span>
role <span class="re3">:db</span>, domain, <span class="re3">:primary</span> <span class="sy0">=&gt;</span> <span class="kw2">true</span> <span class="co1"># This is where Rails migrations will run</span>
&nbsp;
set <span class="re3">:use_sudo</span>, <span class="kw2">false</span>
set <span class="re3">:use_composer</span>, <span class="kw2">false</span>
set <span class="re3">:keep_releases</span>, <span class="nu0">3</span></pre></div></div></div></div></div></div></div>


<p>Il est possible de définit une option en plus si l&#8217;utilisateur sur le serveur de production est différent de celui de la machine locale :</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="ruby"><pre class="de1">set <span class="re3">:user</span>, <span class="st0">&quot;&quot;</span> <span class="co1"># utilisateur distant</span></pre></div></div></div></div></div></div></div>


<p>Pour un projet Symfony 2 il peut être utile d&#8217;ajouter ces options la, pour partager le dossier <em>vendors/</em> et <em>logs/</em>  entre toutes les releases et le fichier <em>parameters.ini</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="ruby"><pre class="de1">set <span class="re3">:shared_files</span>,      <span class="br0">&#91;</span><span class="st0">&quot;app/config/parameters.ini&quot;</span><span class="br0">&#93;</span>
set <span class="re3">:shared_children</span>,     <span class="br0">&#91;</span>app_path <span class="sy0">+</span> <span class="st0">&quot;/logs&quot;</span>, web_path <span class="sy0">+</span> <span class="st0">&quot;/uploads&quot;</span>, <span class="st0">&quot;vendor&quot;</span><span class="br0">&#93;</span>
set <span class="re3">:update_vendors</span>, <span class="kw2">true</span></pre></div></div></div></div></div></div></div>


<p>Si votre projet utilise Composer comme gestionnaire de dépendances il faut aussi rajouter cette option :</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="ruby"><pre class="de1">set <span class="re3">:use_composer</span>, <span class="kw2">true</span></pre></div></div></div></div></div></div></div>


<p>Une fois ce fichier modifié, il faut initialiser la structure des dossiers sur le serveur de production en tapant cette commande :</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="bash"><pre class="de1">cap deploy:setup</pre></div></div></div></div></div></div></div>


<p>Il faut maintenant configurer sur le serveur de production le fichier <em>parameters.ini</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="bash"><pre class="de1"><span class="kw2">ssh</span> production_server
<span class="kw3">cd</span> <span class="sy0">/</span>path<span class="sy0">/</span>to<span class="sy0">/</span>project<span class="sy0">/</span>shared
<span class="kw2">mkdir</span> <span class="re5">-p</span> app<span class="sy0">/</span>config
<span class="kw2">vim</span> app<span class="sy0">/</span>config<span class="sy0">/</span>parameters.ini</pre></div></div></div></div></div></div></div>


<p>Et une fois toutes ces étapes finies avec succès, il suffit juste de lancer la commande :</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="bash"><pre class="de1">cap deploy</pre></div></div></div></div></div></div></div>


<p>Cette commande va créer un nouveau dossier dans <em>/path/to/project/releases</em> et faire pointer le dossier <em>current/</em> vers cette dernière release. Ensuite installer les vendors si c&#8217;est un projet Symfony 2, publier les assets, vider le cache et lancer tous les hooks lié au scm.</p>
<p>Une fois les projet déployé, il suffit juste de faire pointer son domaine vers le dossier <em>current/</em> du projet.<br />
Pour les autres commandes disponibles je vous laisse vous référer à la page de <a href="http://capifony.org/" target="_blank">capifony</a>.</p>
<p>Bon déploiement !</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.luxifer.fr/2012/04/25/deployer-un-projet-symfony-2-avec-capifony/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Il était une fois Florent Viel</title>
		<link>http://blog.luxifer.fr/2012/03/24/il-etait-une-fois-florent-viel/</link>
		<comments>http://blog.luxifer.fr/2012/03/24/il-etait-une-fois-florent-viel/#comments</comments>
		<pubDate>Sat, 24 Mar 2012 13:16:40 +0000</pubDate>
		<dc:creator>LuXiFeR</dc:creator>
				<category><![CDATA[Vie quotidienne]]></category>

		<guid isPermaLink="false">http://blog.luxifer.fr/?p=327</guid>
		<description><![CDATA[Bonjour, Petit article sur moi aujourd&#8217;hui. En ce moment ça ne va pas très fort même si je peux compter sur ma copine et ma famille. J&#8217;ai pas mal de soucis en tête dont mon ex colocation qui n&#8217;est pas encore terminée. Je suis dans le dernier mois de préavis mais j&#8217;en prend plein la [...]]]></description>
			<content:encoded><![CDATA[<p>Bonjour,</p>
<p>Petit article sur moi aujourd&#8217;hui. En ce moment ça ne va pas très fort même si je peux compter sur ma copine et ma famille. J&#8217;ai pas mal de soucis en tête dont mon ex colocation qui n&#8217;est pas encore terminée. Je suis dans le dernier mois de préavis mais j&#8217;en prend plein la gueule. Je ne suis pas tout blanc dans cette histoire et ce n&#8217;est pas l&#8217;endroit pour étaler tous les détails. Mais parfois il serait bon pour certaines personnes de grandir&#8230; On est plus en maternelle ni au pays des bisounours. Chaque acte, chaque mot qu&#8217;on dit a des conséquences. Et bien souvent on en a pas conscience&#8230;</p>
<p>On essaye de soutenir ses amis quand ça ne va pas, d&#8217;être gentil avec les autres mais au final tout ce qu&#8217;on récolte c&#8217;est d&#8217;être pris pour la bonne poire. En ce moment j&#8217;ai vraiment l&#8217;impression d&#8217;être le bouc émissaire pour une tripotée de personnes et franchement ça me casse les couilles. Je sais que ça fait clicher d&#8217;étaler sa vie et ses problèmes sur Internet mais des fois ça fait du bien. Ça permet de relâcher la pression.</p>
<p>Mais le pire dans tout ça c&#8217;est quand même d&#8217;avoir soutenu quelqu&#8217;un pendant 3 ans, avoir été là dans le moments difficiles, essayer de comprendre à chaque fois ce qui n&#8217;allait pas pour qu&#8217;au final, maintenant que je suis bien avec ma copine, en recherche d&#8217;appartement, cette personne essaye de me garder seulement pour elle. J&#8217;ai été vraiment déçu. Et quand t&#8217;essaye de mettre au clair la situation la personne part en faisant sa victime et oublie que pendant ces trois dernières années tu étais là c&#8217;est un coup dur.</p>
<p>Enfin ce que j&#8217;en conclue c&#8217;est qu&#8217;il faut bien choisir ses amis, ses relations et de ne pas accorder sa confiance facilement. C&#8217;est dur mais c&#8217;est la vie.</p>
<p>Sur ce j&#8217;en ai fini d&#8217;épiloguer sur ma vie. Life&#8217;s going on <img src='http://blog.luxifer.fr/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.luxifer.fr/2012/03/24/il-etait-une-fois-florent-viel/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<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>
	</channel>
</rss>

