<?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/"
	>

<channel>
	<title>Pims Labs &#187; Tutoriels</title>
	<atom:link href="http://labs.pimsworld.org/category/tutoriels/feed/" rel="self" type="application/rss+xml" />
	<link>http://labs.pimsworld.org</link>
	<description>Les labs de Pims World</description>
	<pubDate>Thu, 28 May 2009 08:15:39 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Firefox Native Content Aware Image Resizing</title>
		<link>http://labs.pimsworld.org/2009/04/firefox-native-content-aware-image-resizing/</link>
		<comments>http://labs.pimsworld.org/2009/04/firefox-native-content-aware-image-resizing/#comments</comments>
		<pubDate>Mon, 06 Apr 2009 16:40:52 +0000</pubDate>
		<dc:creator>Stéphane Roucheray</dc:creator>
		
		<category><![CDATA[Ergonomie]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Tutoriels]]></category>

		<category><![CDATA[canvas]]></category>

		<category><![CDATA[convolution]]></category>

		<category><![CDATA[filter]]></category>

		<category><![CDATA[Firefox]]></category>

		<category><![CDATA[HTML5]]></category>

		<category><![CDATA[image processing]]></category>

		<category><![CDATA[liquid rescale]]></category>

		<category><![CDATA[seam carving]]></category>

		<guid isPermaLink="false">http://labs.pimsworld.org/?p=442</guid>
		<description><![CDATA[This article is about a pure JavaScript implementation of the famous image resizing algorithm known under the names of Content Aware Image Resizing, Seam Carving or Liquid Rescale. A live demo is available here (Fireox 3.1/3.5 required : download it here).
Update : since this post the demo has been improved and a new post has [...]]]></description>
			<content:encoded><![CDATA[<p>This article is about a <strong>pure JavaScript</strong> implementation of the famous image resizing algorithm known under the names of <strong>Content Aware Image Resizing</strong>, <strong>Seam Carving</strong> or <strong>Liquid Rescale</strong>.<span id="more-442"></span> <a href="http://labs.pimsworld.org/wp-content/uploads/2009/04/demo-content-aware-image-resizing/index.html"><strong>A live demo is available here</strong></a> (Fireox 3.1/3.5 required : <a href="http://www.mozilla.com/en-US/firefox/all-beta.html">download it here</a>).<br />
<strong style="background: #555; color: white; padding: 2px 10px">Update : since this post the demo has been improved and a new post has been written : <a href="http://labs.pimsworld.org/2009/05/a-javascript-implementation-of-the-content-aware-image-resizing-algorithm/">A JavaScript implementation of the content aware image resizing algorithm</a></strong></p>
<h3>Short story</h3>
<p>Last year an incredible buzz around the new image resizing algorithm exposed by <a href="http://www.shaiavidan.org/">Shai Avidan</a> and <a href="http://www.faculty.idc.ac.il/arik/site/index.asp">Ariel Shamir</a> happened.</p>
<p>For those on vacation in 2008 I suggest to give a look at this demo : <a href="http://www.seamcarving.com/">http://www.seamcarving.com/</a>.</p>
<p>As I saw it I started to think about implementations. There are already some <a href="http://liquidrescale.wikidot.com/">here</a> and <a href="http://rsizr.com/">there</a>. Some are fairly fast, some are plugins, some are web based. None of them (from what I saw) are browser native.</p>
<h3>Next gen browsers and HTML5</h3>
<p>I started some work with Flash and ActionsScript 3 and then&#8230; several demos of the new HTML5 native features of next Firefox release (<a href="http://fr.www.mozilla.com/fr/firefox/all-beta.html">3.5 formerly 3.1</a>) by Paul Rouget (<a href="http://blog.mozbox.org/post/2009/02/25/video-canvas%3A-special-effects">video canvas special effects</a> and <a href="http://blog.mozbox.org/post/2009/03/10/video-tag-and-subtitles">video tag and subtitles</a>) and some great articles by <a href="http://blog.vlad1.com/">Vladimir Vukićević</a> arose.</p>
<p>I decided to try to implement the algorithm in pure JavaScript, and this article presents the early results.  The <em>C</em> based <a href="http://brain.recall.googlepages.com/cair">CAIR</a> implementation, and associated article, was really helpful to fully understand the algorithm thus I used the same photo from the NASA, downscaled though, for performance reason.</p>
<h3>JavaScript - Content Aware Image Resizing Algorithm</h3>
<p>Below you can see three pictures :</p>
<ol>
<li>First is the original, its size is 256px / 170px</li>
<li>Second is resized using Content Aware Image Resizing algorithm, its size is 206px / 170px</li>
<li>Third is resized with CSS, I put it here as a reference and its size is also 206px / 170px</li>
</ol>
<div style="margin: 0pt auto; width: 256px;">
<div id="attachment_447" class="wp-caption aligncenter" style="width: 266px"><img class="size-full wp-image-447" title="Original picture" src="http://labs.pimsworld.org/wp-content/uploads/2009/04/original.jpg" alt="Original picture without resize" width="256" height="170" /><p class="wp-caption-text">Original picture</p></div>
<div id="attachment_445" class="wp-caption aligncenter" style="width: 215px"><img class="size-full wp-image-445" title="cair-resized" src="http://labs.pimsworld.org/wp-content/uploads/2009/04/cair-resized.png" alt="Content Aware 50px Resized" width="205" height="170" /><p class="wp-caption-text">50px resized - Content Aware Image Resizing algorithm </p></div>
<div id="attachment_448" class="wp-caption aligncenter" style="width: 216px"><img class="size-full wp-image-448" title="css-resized" src="http://labs.pimsworld.org/wp-content/uploads/2009/04/css-resized.jpg" alt="50px CSS resized " width="206" height="170" /><p class="wp-caption-text">50px resized - CSS Resizing reference</p></div>
</div>
<p>Compare how the angles and the cosmonauts are reproduced on both resized images. Content Aware Image Resizing algorithm manage to get rid of parts of the image with less energy (short for : less important parts of the image) and leave intact the most important parts.</p>
<h3>A JavaScript implementation</h3>
<p>The current implementation I made is really a first shout. It only makes use of JavaScript and the HTML5 &lt;canvas /&gt; tag. It uses the <a href="http://fr.wikipedia.org/wiki/Algorithme_de_Sobel">Sobel convolution filter</a> for edge detection. You&#8217;ll need Firefox 3.1/3.5 to run it (merely tested). The code is still a bit awful and I may refactor and optimize it when I have time.</p>
<p>Next steps could be :</p>
<ul>
<li> Add expansion capabilities</li>
<li> Add vertical reduction and expansion</li>
<li> Test some other edge detection filters</li>
<li> Add some features as image portion removing</li>
<li> Improve performances in order to make it real time on page resizing (is it useful ?)</li>
<li> Improve performances just for the beauty of art</li>
<li> Include it in a JavaScript image manipulation widget from any toolkit like <a href="http://www.pixastic.com/">Pixstatic</a>.</li>
</ul>
<p>Any comments are welcome !</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.pimsworld.org/2009/04/firefox-native-content-aware-image-resizing/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Créer un environnement de développement LAMP en local</title>
		<link>http://labs.pimsworld.org/2009/01/creer-un-environnement-de-developpement-lamp-en-local/</link>
		<comments>http://labs.pimsworld.org/2009/01/creer-un-environnement-de-developpement-lamp-en-local/#comments</comments>
		<pubDate>Thu, 29 Jan 2009 16:09:53 +0000</pubDate>
		<dc:creator>Adrien</dc:creator>
		
		<category><![CDATA[Administration]]></category>

		<category><![CDATA[Tutoriels]]></category>

		<category><![CDATA[apache]]></category>

		<category><![CDATA[développement]]></category>

		<category><![CDATA[environnement]]></category>

		<category><![CDATA[lamp]]></category>

		<category><![CDATA[vhost]]></category>

		<guid isPermaLink="false">http://labs.pimsworld.org/?p=301</guid>
		<description><![CDATA[J&#8217;ai trouvé un article intéressant avec un toturiel permettant de créer rapidement un domaine sur sa machine Linux dont les sous-domaines sont les projets utilisés : voir l&#8217;article
D&#8217;ailleurs le blog en lui-même est aussi intéressant.
]]></description>
			<content:encoded><![CDATA[<p>J&#8217;ai trouvé un article intéressant avec un toturiel permettant de créer rapidement un domaine sur sa machine Linux dont les sous-domaines sont les projets utilisés : <a title="Accéder à l'article" href="http://blog.gaetan-grigis.eu/systeme/se-monter-un-environnement-de-developpement-lamp-rapidement/" target="_blank">voir l&#8217;article</a></p>
<p>D&#8217;ailleurs le blog en lui-même est aussi intéressant.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.pimsworld.org/2009/01/creer-un-environnement-de-developpement-lamp-en-local/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Xoad et le Zend Framework</title>
		<link>http://labs.pimsworld.org/2009/01/xoad-et-le-zend-framework/</link>
		<comments>http://labs.pimsworld.org/2009/01/xoad-et-le-zend-framework/#comments</comments>
		<pubDate>Tue, 27 Jan 2009 17:53:24 +0000</pubDate>
		<dc:creator>jrm</dc:creator>
		
		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Tutoriels]]></category>

		<category><![CDATA[Xoad]]></category>

		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://labs.pimsworld.org/?p=162</guid>
		<description><![CDATA[Dans cet article vous allez découvrir comment XOAD permet d&#8217;exporter des classes PHP vers du code Javascript par l&#8217;intermédiaire du Zend Framework.

Ce qu&#8217;il faut savoir pour comprendre cet article :

Avoir de bonnes bases en javascript, PHP.
Comprendre le  design pattern MVC.
Savoir créer le bootstrap d&#8217;une application avec le Zend Framework.

Xoad
Xoad permet d&#8217;exporter des objets du [...]]]></description>
			<content:encoded><![CDATA[<p>Dans cet article vous allez découvrir comment XOAD permet d&#8217;exporter des classes PHP vers du code Javascript par l&#8217;intermédiaire du Zend Framework.</p>
<p><span id="more-162"></span></p>
<p><strong>Ce qu&#8217;il faut savoir pour comprendre cet article </strong>:</p>
<ul>
<li>Avoir de bonnes bases en javascript, PHP.</li>
<li>Comprendre le  design pattern MVC.</li>
<li>Savoir créer le bootstrap d&#8217;une application avec le Zend Framework.</li>
</ul>
<h2>Xoad</h2>
<p>Xoad permet d&#8217;exporter des objets du côté serveur vers le côté client. Xoad est un environnement basé sur un ORB. Un ORB (Object Request Broker) est un ensemble de fonctions qui implément un bus logiciel par lequel des objets envoient et reçoivent des requêtes et des réponses, de manière transparente et portable.</p>
<h2>Zend Framework</h2>
<p>Le Zend Framework est un <a title="Framework" href="http://fr.wikipedia.org/wiki/Framework">framework</a> pour <a title="PHP: Hypertext Preprocessor" href="http://fr.wikipedia.org/wiki/PHP:_Hypertext_Preprocessor">PHP 5</a> créé par <a title="Zend (informatique)" href="http://fr.wikipedia.org/wiki/Zend_%28informatique%29">Zend</a>. Il est distribué sous la <a title="Licence BSD" href="http://fr.wikipedia.org/wiki/Licence_BSD">New BSD license</a>. Le Zend Framework, aussi nommé ZF, a été développé dans le but de simplifier le développement Web tout en recommandant les bonnes pratiques et la <a title="Programmation orientée objet" href="http://fr.wikipedia.org/wiki/Programmation_orient%C3%A9e_objet">conception orientée objets</a> en offrant des outils puissants aux développeurs. ZF permet aussi d&#8217;utiliser nativement le principe de MVC (Modèle-Vue-Contrôleur) mais ne l&#8217;oblige pas.</p>
<h2>Préalable</h2>
<h3>Configuration du Zend-Framework :</h3>
<p>Si vous êtes débutant avec le ZF vous pouvez vous reporter à l&#8217;arcticle suivant :<a href="http://julien-pauli.developpez.com/tutoriels/zend-framework/presentation/"> Premier pas avec le ZF</a> .</p>
<h3>Considérons l&#8217;arborescence suivante :</h3>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:540px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="sy0">/</span>application<span class="sy0">/</span><br />
&nbsp; Lab<span class="sy0">/</span><br />
&nbsp; &nbsp; controllers<span class="sy0">/</span><br />
&nbsp; &nbsp; &nbsp; LabController.php<br />
&nbsp; &nbsp; views<span class="sy0">/</span><br />
&nbsp; &nbsp; &nbsp; scripts<span class="sy0">/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; lab<span class="sy0">/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;xoad.phtml<br />
&nbsp; &nbsp; Xoad.php<br />
<span class="sy0">/</span>deploy<span class="sy0">/</span><br />
&nbsp; index.php <span class="br0">&#40;</span>bootstrap<span class="br0">&#41;</span><br />
<span class="sy0">/</span>lib<span class="sy0">/</span><br />
&nbsp; Zend<span class="sy0">/</span><br />
&nbsp; xoad<span class="sy0">/</span></div></div>
<p>Vous pouvez télécharger la librairie XOAD  <a href="http://sourceforge.net/projects/xoad">ici</a>. <br />
Nous allons créer une vue qui va nous permettre d&#8217;afficher le traditionnel &#8220;Hello world&#8221; lors du clique sur un bouton.</p>
<h3>xoad.phtml</h3>
<div class="codecolorer-container html4strict " style="overflow:auto;white-space:nowrap;width:540px"><div class="html4strict codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="sc0">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;</span><br />
<span class="sc2">&lt;<a href="http://december.com/html/4/element/html.html"><span class="kw2">html</span></a> xmlns<span class="sy0">=</span><span class="st0">&quot;http://www.w3.org/1999/xhtml&quot;</span> xml:<span class="kw3">lang</span><span class="sy0">=</span><span class="st0">&quot;fr&quot;</span> <span class="kw3">lang</span><span class="sy0">=</span><span class="st0">&quot;fr&quot;</span>&gt;</span><br />
&nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/head.html"><span class="kw2">head</span></a>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/title.html"><span class="kw2">title</span></a>&gt;</span>Zend <span class="sc1">&amp; XOAD tutorial&lt;/title&gt;</span><br />
<span class="sc1"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;application/xhtml+xml;</span> charset=utf-8&quot; /&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/base.html"><span class="kw2">base</span></a> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;http://localhost/earl/deploy/&quot;</span><span class="sy0">/</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/script.html"><span class="kw2">script</span></a> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;text/javascript&quot;</span> <span class="kw3">src</span><span class="sy0">=</span><span class="st0">&quot;public/lab/xoad_optimized.js&quot;</span>&gt;&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/script.html"><span class="kw2">script</span></a>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/script.html"><span class="kw2">script</span></a> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;text/javascript&quot;</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var Lab_Xoad = <span class="sc2">&lt;?php echo $this-&gt;</span>jsObject ?&gt;;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/script.html"><span class="kw2">script</span></a>&gt;</span><br />
&nbsp; &nbsp; <span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/head.html"><span class="kw2">head</span></a>&gt;</span><br />
<span class="sc2">&lt;<a href="http://december.com/html/4/element/body.html"><span class="kw2">body</span></a>&gt;</span><br />
<span class="sc2">&lt;<a href="http://december.com/html/4/element/input.html"><span class="kw2">input</span></a> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;button&quot;</span> <span class="kw3">id</span><span class="sy0">=</span><span class="st0">&quot;hello-world&quot;</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">&quot;Hello World !&quot;</span>&gt;</span><br />
<span class="sc2">&lt;<a href="http://december.com/html/4/element/script.html"><span class="kw2">script</span></a> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;text/javascript&quot;</span>&gt;</span><br />
document.getElementById('hello-world').onclick = function ()<br />
{<br />
&nbsp; &nbsp; alert(Lab_Xoad.test());<br />
};<br />
<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/script.html"><span class="kw2">script</span></a>&gt;</span><br />
<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/body.html"><span class="kw2">body</span></a>&gt;</span><br />
<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/html.html"><span class="kw2">html</span></a>&gt;</span></div></div>
<p>Dans cette vue, rien d&#8217;extraordinaire :<br />
- inclusion de la librairie javascript xoad (optimisée)<br />
- affichage de l&#8217;objet javascript généré côté serveur  et passé à la vue.</p>
<div class="codecolorer-container php " style="overflow:auto;white-space:nowrap;width:540px"><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace">var Lab_Xoad = <span class="kw2">&lt;?php</span> <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">jsObject</span> <span class="sy1">?&gt;</span>;</div></div>
<p>- ajout d&#8217;un évènement sur le onclick d&#8217;un bouton qui va nous permettre d&#8217;afficher la réponse générée par xoad.</p>
<h3>LabController.php</h3>
<div class="codecolorer-container php " style="overflow:auto;white-space:nowrap;width:540px"><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">&lt;?php</span><br />
<span class="kw2">class</span> Lab_LabController <span class="kw2">extends</span> Zend_Controller_Action <br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <br />
&nbsp; <span class="co4">/**<br />
&nbsp; &nbsp; &nbsp;* Specific view<br />
&nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp;* @var Zend_view<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw2">private</span> <span class="re0">$_view</span> <span class="sy0">=</span> <span class="kw2">null</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <br />
&nbsp; <span class="co4">/**<br />
&nbsp; &nbsp; &nbsp;* Init zend view.<br />
&nbsp; &nbsp; &nbsp;* <br />
&nbsp; &nbsp; &nbsp;* @return void <br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> init<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span><span class="sy0">-&gt;</span>_view &nbsp;<span class="sy0">=</span> <span class="kw2">new</span> Zend_View<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span><span class="sy0">-&gt;</span>_view<span class="sy0">-&gt;</span><span class="me1">setScriptPath</span><span class="br0">&#40;</span><a href="http://www.php.net/dirname"><span class="kw3">dirname</span></a><span class="br0">&#40;</span><a href="http://www.php.net/dirname"><span class="kw3">dirname</span></a><span class="br0">&#40;</span><span class="kw2">__FILE__</span><span class="br0">&#41;</span><span class="br0">&#41;</span> &nbsp;<span class="sy0">.</span> <span class="st_h">'/views/scripts/'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; <span class="co4">/**<br />
&nbsp; &nbsp; &nbsp;* Xoad tutorial action.<br />
&nbsp; &nbsp; &nbsp;* <br />
&nbsp; &nbsp; &nbsp;* @return void<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> xoadAction<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Zend_Loader<span class="sy0">::</span><span class="me2">loadClass</span><span class="br0">&#40;</span><span class="st_h">'Lab_Xoad'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/define"><span class="kw3">define</span></a><span class="br0">&#40;</span><span class="st_h">'XOAD_AUTOHANDLE'</span><span class="sy0">,</span> <span class="kw2">true</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">require_once</span> <span class="st_h">'xoad/xoad.php'</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span><span class="sy0">-&gt;</span>_view<span class="sy0">-&gt;</span><span class="me1">jsObject</span> <span class="sy0">=</span> XOAD_Client<span class="sy0">::</span><span class="me2">register</span><span class="br0">&#40;</span><span class="kw2">new</span> Lab_Xoad<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">,</span><span class="st_h">'lab/lab/xoad'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Render content</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$this</span><span class="sy0">-&gt;</span>_view<span class="sy0">-&gt;</span><span class="me1">render</span><span class="br0">&#40;</span><span class="st_h">'lab/xoad.phtml'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div></div>
<p>Ce controller va nous permettre d&#8217;effectuer le rendu de notre vue décrite plus haut.<br />
La méthode init nous permet de créer une vue personnalisée.<br />
La méthode xoadAction va permettre à Xoad d&#8217;interagir avec le Zend Framework.<br />
<strong>Particularités</strong> :<br />
- On force le chargement de la class Lab_Xoad avec le Zend_Loader.<br />
- On inclut la librairie xoad (située dans le repertoire lib)<br />
- On génère l&#8217;objet javascript à partir de la méthode statique &#8220;register&#8221; en lui passant en premier paramètre la classe et en second l&#8217;url de callback utilisée par xoad <br />
- Le fait de définir à true la constante XOAD_AUTOHANDLE permet à xoad de déterminer si l&#8217;action du controller a été appelé lors d&#8217;une requête ajax ou non, dans le cas d&#8217;une requête Ajax le script s&#8217;arrête après le require_once de la librairie xoad, le format de retour est alors du json qui servira comme outil de communication à notre objet js. </p>
<h3>Xoad.php</h3>
<div class="codecolorer-container php " style="overflow:auto;white-space:nowrap;width:540px"><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">&lt;?php</span><br />
<span class="kw2">class</span> Lab_Xoad<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> test<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="st_h">'Hello world !'</span><span class="sy0">;</span> &nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div></div>
<p>C&#8217;est là que ça commence à devenir interessant !<br /> <br />
En effet, cette class va pouvoir être utilisée directement en javascript sans avoir à le modifier.<br />
Toutes ses méthodes et ses attributs sont directement disponibles en javascript.<br />
<strong>Vous n&#8217;avez plus à vous soucier d&#8217;écrire le code Javascript qui va se charger d&#8217;effectuer des requêtes Ajax et d&#8217;en traiter le retour.</strong><br />
Exemple, dans notre vue nous appelons directement la méthode suivante :</p>
<div class="codecolorer-container javascript " style="overflow:auto;white-space:nowrap;width:540px"><div class="javascript codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw3">alert</span><span class="br0">&#40;</span>Lab_Xoad.<span class="me1">test</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></div>
<p>Cet appel Javascript va nous retourner &#8220;Hello World&#8221;, les aller-retours serveur nécessaires vont se faire en backend.</p>
<p>Alors convaincu ?</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.pimsworld.org/2009/01/xoad-et-le-zend-framework/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Tests unitaires avec Zend Studio</title>
		<link>http://labs.pimsworld.org/2009/01/tests-unitaires-avec-zend-studio/</link>
		<comments>http://labs.pimsworld.org/2009/01/tests-unitaires-avec-zend-studio/#comments</comments>
		<pubDate>Mon, 19 Jan 2009 18:09:02 +0000</pubDate>
		<dc:creator>Kal</dc:creator>
		
		<category><![CDATA[Open Source]]></category>

		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Tests Unitaires]]></category>

		<category><![CDATA[Tutoriels]]></category>

		<category><![CDATA[PHPUnit]]></category>

		<category><![CDATA[tests unitaires]]></category>

		<category><![CDATA[Zend Studio]]></category>

		<guid isPermaLink="false">http://labs.pimsworld.org/?p=10</guid>
		<description><![CDATA[Si vous êtes persuadés de l'intérêt des tests unitaires pour vos développements PHP mais que vous n'avez jamais osé franchir le pas, ce tutoriel est fait pour vous. Afin de migrer en douceur vers les préceptes sacrés de l'eXtreme Programming je vous propose un exemple concret de mise en place des tests unitaires sous l'environnement Zend Studio.]]></description>
			<content:encoded><![CDATA[<p>Si vous êtes persuadés de l&#8217;intérêt des tests unitaires pour vos développements PHP mais que vous n&#8217;avez jamais osé franchir le pas, ce tutoriel est fait pour vous. Afin de migrer en douceur vers les préceptes sacrés de l&#8217;eXtreme Programming je vous propose un exemple concret de mise en place des tests unitaires sous l&#8217;environnement Zend Studio.</p>
<p><span id="more-10"></span></p>
<p>Pour ce faire, nous allons implémenter une bonne vieille <strong>pile LIFO</strong> en PHP.</p>
<p>Après avoir crée un projet avec Zend Studio et une classe <strong>Unit_Stack</strong>, on commence par écrire le squelette de cette classe :</p>
<div class="codecolorer-container php " style="overflow:auto;white-space:nowrap;width:540px"><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="co4">/**<br />
* A LIFO Stack<br />
*/</span><br />
<span class="kw2">class</span> Unit_Stack<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="co4">/**<br />
&nbsp; &nbsp; * Push an item.<br />
&nbsp; &nbsp; *<br />
&nbsp; &nbsp; * @param mixed $item<br />
&nbsp; &nbsp; *<br />
&nbsp; &nbsp; * @return void<br />
&nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> push<span class="br0">&#40;</span><span class="re0">$item</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="co4">/**<br />
&nbsp; &nbsp; * Pop an item.<br />
&nbsp; &nbsp; *<br />
&nbsp; &nbsp; * @return mixed<br />
&nbsp; &nbsp; * @throws Exception if stack is empty.<br />
&nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> pop<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="co4">/**<br />
&nbsp; &nbsp; * Count items of stack.<br />
&nbsp; &nbsp; *<br />
&nbsp; &nbsp; * @return int<br />
&nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> <a href="http://www.php.net/count"><span class="kw3">count</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="co4">/**<br />
&nbsp; &nbsp; * Tells if stack is empty.<br />
&nbsp; &nbsp; *<br />
&nbsp; &nbsp; * @return boolean<br />
&nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> isEmpty<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="co4">/**<br />
&nbsp; &nbsp; * Removes all items of stack.<br />
&nbsp; &nbsp; *<br />
&nbsp; &nbsp; * @return void<br />
&nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> <a href="http://www.php.net/reset"><span class="kw3">reset</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div></div>
<p>Les commentaires devraient suffire à expliquer ce qu&#8217;est sensée faire cette classe.</p>
<p>L&#8217;étape suivante consiste à créer la classe de tests unitaires ou <strong>Test Case</strong>. Dans l&#8217;arborescence <em>tests/unit/Unit/</em>, faire click droit puis <strong>new -&gt; PHPUnit Test Case</strong>.</p>
<p>Il suffit alors de choisir la classe à tester via le bouton <strong>Browse</strong> en face de<strong> &#8216;Element to Test&#8217;</strong>, puis de corriger le nom de la classe de Test générée dans le champ <strong>&#8216;Test File Name&#8217;</strong> en virant le préfixe Unit_&#8217;. Cela devrait ressembler à ça :</p>
<div id="attachment_143" class="wp-caption aligncenter" style="width: 532px"><img class="size-full wp-image-143" src="http://labs.pimsworld.org/wp-content/uploads/2009/01/unit1.png" alt="Création d'un Test Case" width="522" height="497" /><p class="wp-caption-text">Création d&#39;un Test Case</p></div>
<p>Le <strong>Test Case</strong> généré devrait comprendre :</p>
<ul>
<li>une méthode setUp : lancée avant chaque test.</li>
<li>une méthode tearDown : lancée après chaque test.</li>
<li>un constructeur : pas vraiment utile.</li>
<li>une méthode de test par méthode publique de la classe à tester.</li>
</ul>
<p>Dans le cadre de cet exemple, je vous invite à supprimer le constructeur ainsi que les méthodes setUp et tearDown.</p>
<p>Nous rentrons maintenant dans le vif du sujet, il s&#8217;agit :</p>
<ol>
<li>d&#8217;écrire un test</li>
<li>de lancer le Test Case afin de vérifier (oh surprise) qu&#8217;il échoue</li>
<li>d&#8217;implémenter la fonctionnalité</li>
<li>de relancer le test et éventuellement corriger jusqu&#8217;à ce que le test passe !</li>
</ol>
<h2>Écriture du test</h2>
<p>Nous proposons pour la méthode <strong>isEmpty</strong> l&#8217;écriture du test suivant :</p>
<div class="codecolorer-container php " style="overflow:auto;white-space:nowrap;width:540px"><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">public</span> <span class="kw2">function</span> testIsEmpty <span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="re0">$stack</span> <span class="sy0">=</span> <span class="kw2">new</span> Unit_Stack<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; <span class="co1">// a new stack is empty !</span><br />
&nbsp; &nbsp; <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">assertTrue</span><span class="br0">&#40;</span><span class="re0">$stack</span><span class="sy0">-&gt;</span><span class="me1">isEmpty</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></div></div>
<h2>Lancer le Test Case</h2>
<p>Il suffit d&#8217;un click droit sur le fichier du <strong>Test Case</strong> puis de choisir <strong>Run as -&gt; PHPUnit Test</strong></p>
<p>Si tout se passe bien, le test devrait apparaître en erreur et les autres en non implémentés.</p>
<h2>
<p><div id="attachment_146" class="wp-caption aligncenter" style="width: 458px"><img class="size-full wp-image-146" src="http://labs.pimsworld.org/wp-content/uploads/2009/01/unit11.png" alt="Résultats test case" width="448" height="173" /><p class="wp-caption-text">Résultats test case</p></div></h2>
<h2>Implémenter la fonctionnalité</h2>
<div class="codecolorer-container php " style="overflow:auto;white-space:nowrap;width:540px"><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">public</span> <span class="kw2">function</span> isEmpty<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> <a href="http://www.php.net/empty"><span class="kw3">empty</span></a><span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span>_array<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></div></div>
<p>Trop facile &#8230;</p>
<h2>Relancer le test et corriger</h2>
<p>Même procédure que le lancement précédent, cette fois le test devrait apparaître comme réussi.</p>
<h2>Ensuite&#8230;.</h2>
<p>Il suffit de refaire la même procédure itérativement pour chaque fonctionnalité. A mesure que les nouvelles fonctionnalités sont implémentées, de nouveaux tests peuvent être écrits en plus de ceux générés par Zend Studio. Il suffit de créer une méthode publique dont le nom commence par <strong>test</strong>.</p>
<p>Si votre application contient plusieurs classes et donc plusieurs Test Case (ce qui est souvent le cas !), il peut être fastidieux de lancer les tests cases un par un, il est alors intéressant d&#8217;utiliser les <strong>Tests Suites</strong>. Il suffit de faire un click droit dans Zend studio sur le répertoire <em>test/unit/</em> puis <strong>New -&gt; PHPUnit Test Suite</strong>.</p>
<p>On sélectionne alors les Tests Case à lancer puis finish. Une Suite se lance alors de le même façon qu&#8217;un Test Case.</p>
<p>Liens :</p>
<ul>
<li>Les sources de <a href="http://labs.pimsworld.org/download/test.zip" target="_blank">l&#8217;exemple</a></li>
<li>Le site de <a href="http://www.phpunit.de/" target="_blank">PhpUnit </a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://labs.pimsworld.org/2009/01/tests-unitaires-avec-zend-studio/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Installation d&#8217;un crossdomain</title>
		<link>http://labs.pimsworld.org/2009/01/installation-dun-crossdomain/</link>
		<comments>http://labs.pimsworld.org/2009/01/installation-dun-crossdomain/#comments</comments>
		<pubDate>Thu, 15 Jan 2009 09:08:09 +0000</pubDate>
		<dc:creator>cponcin</dc:creator>
		
		<category><![CDATA[Tutoriels]]></category>

		<category><![CDATA[crossdomain.xml]]></category>

		<category><![CDATA[Flash]]></category>

		<category><![CDATA[swf]]></category>

		<guid isPermaLink="false">http://labs.pimsworld.org/?p=107</guid>
		<description><![CDATA[Pour des raisons de sécurité flash ne permet pas l&#8217;exécution et le chargement de fichiers provenant d&#8217;un domaine différent de celui qui l&#8217;appel.
Flash a créé des règles d&#8217;autorisations interdomaines. Ces règles sont écrites dans un fichier appelé crossdomain.xml.  Ce fichier s&#8217;installe à la racine du serveur sur lequel se trouve les fichiers à charger.

Ecriture [...]]]></description>
			<content:encoded><![CDATA[<p>Pour des raisons de sécurité flash ne permet pas l&#8217;exécution et le chargement de fichiers provenant d&#8217;un domaine différent de celui qui l&#8217;appel.<br />
Flash a créé des règles d&#8217;autorisations interdomaines. Ces règles sont écrites dans un fichier appelé crossdomain.xml.  Ce fichier <strong>s&#8217;installe à la racine</strong> du serveur sur lequel se trouve les fichiers à charger.<br />
<strong><br />
Ecriture du crossdomain.xml</strong></p>
<div class="codecolorer-container xml " style="overflow:auto;white-space:nowrap;width:540px"><div class="xml codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="sc3"><span class="re1">&lt;?xml</span> <span class="re0">version</span>=<span class="st0">&quot;1.0&quot;</span> <span class="re0">encoding</span>=<span class="st0">&quot;UTF-8&quot;</span><span class="re2">?&gt;</span></span><br />
<span class="sc0">&lt;!DOCTYPE cross-domain-policy </span><br />
<span class="sc0">&nbsp; &nbsp; SYSTEM &quot;http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd&quot;&gt;</span><br />
<span class="sc3"><span class="re1">&lt;cross-domain-policy<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;allow-access-from</span> <span class="re0">domain</span>=<span class="st0">&quot;*&quot;</span> <span class="re2">&gt;</span></span><br />
<span class="sc3"><span class="re1">&lt;/cross-domain-policy<span class="re2">&gt;</span></span></span></div></div>
<p><strong>Pour autoriser tous les domaines</strong></p>
<div class="codecolorer-container xml " style="overflow:auto;white-space:nowrap;width:540px"><div class="xml codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="sc3"><span class="re1">&lt;?xml</span> <span class="re0">version</span>=<span class="st0">&quot;1.0&quot;</span><span class="re2">?&gt;</span></span><br />
<span class="sc0">&lt;!DOCTYPE cross-domain-policy</span><br />
<span class="sc0">&nbsp; &nbsp; SYSTEM &quot;http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd&quot;&gt;</span><br />
<span class="sc3"><span class="re1">&lt;cross-domain-policy<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;allow-access-from</span> <span class="re0">domain</span>=<span class="st0">&quot;*&quot;</span> <span class="re2">/&gt;</span></span><br />
<span class="sc3"><span class="re1">&lt;/cross-domain-policy<span class="re2">&gt;</span></span></span></div></div>
<p><strong>Pour autoriser tous les domaines en .com ou .fr</strong></p>
<div class="codecolorer-container xml " style="overflow:auto;white-space:nowrap;width:540px"><div class="xml codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="sc3"><span class="re1">&lt;?xml</span> <span class="re0">version</span>=<span class="st0">&quot;1.0&quot;</span><span class="re2">?&gt;</span></span><br />
<span class="sc0">&lt;!DOCTYPE cross-domain-policy </span><br />
<span class="sc0">&nbsp; &nbsp; SYSTEM &quot;http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd&quot;&gt;</span><br />
<span class="sc3"><span class="re1">&lt;cross-domain-policy<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;allow-access-from</span> <span class="re0">domain</span>=<span class="st0">&quot;*.fr&quot;</span> <span class="re2">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;allow-access-from</span> <span class="re0">domain</span>=<span class="st0">&quot;*.com&quot;</span> <span class="re2">/&gt;</span></span><br />
<span class="sc3"><span class="re1">&lt;/cross-domain-policy<span class="re2">&gt;</span></span></span></div></div>
]]></content:encoded>
			<wfw:commentRss>http://labs.pimsworld.org/2009/01/installation-dun-crossdomain/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Phing automatise les opérations répétitives des développements PHP</title>
		<link>http://labs.pimsworld.org/2009/01/phing-automatise-les-operations-repetitives-des-developpements-php/</link>
		<comments>http://labs.pimsworld.org/2009/01/phing-automatise-les-operations-repetitives-des-developpements-php/#comments</comments>
		<pubDate>Wed, 14 Jan 2009 11:09:18 +0000</pubDate>
		<dc:creator>Stéphane Roucheray</dc:creator>
		
		<category><![CDATA[Intégration Continue]]></category>

		<category><![CDATA[Open Source]]></category>

		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Tutoriels]]></category>

		<category><![CDATA[automatisation]]></category>

		<category><![CDATA[ligne de commande]]></category>

		<category><![CDATA[svn]]></category>

		<category><![CDATA[tests unitaires]]></category>

		<category><![CDATA[Ubuntu]]></category>

		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://labs.pimsworld.org/?p=74</guid>
		<description><![CDATA[Phing est un outil Open Source d'automatisation des tâches répétitives pour les projets de développement PHP. Ce tutoriel rapide sur l'utilisation et l'installation de Phing vous permettra de créer rapidement vos premières tâches avec Phing. ]]></description>
			<content:encoded><![CDATA[<p>L&#8217;automatisation des opérations répétitives dans un projet de développement peut être résolue de multiples manières allant du simple script lancé à la main au système d&#8217;intégration continue.</p>
<p>La plupart des langages ont standardisé leurs outils, <a href="http://fr.wikipedia.org/wiki/Make">make</a> pour C, <a href="http://fr.wikipedia.org/wiki/Apache_Ant">Ant</a> pour Java&#8230; PHP bénéficie lui aussi d&#8217;un tel outil : <a href="http://phing.info">Phing</a>.</p>
<p>Phing est un projet Open Source très inspiré de Ant. Le concept est assez simple. Un fichier XML décrit une série d&#8217;actions possibles pouvant ou non être dépendantes les unes des autres et une ligne de commande permet de déclencher ces actions.</p>
<h2>Utilisation de Phing</h2>
<p>Un exemple rapide. Nous voulons vérifier que la syntaxe des fichiers PHP de notre projet est bien respectée, qu&#8217;aucune erreur ne s&#8217;y est glissée, le fichier XML ressemble alors à ça :</p>
<p><strong>Fichier build.xml</strong></p>
<div class="codecolorer-container xml " style="overflow:auto;white-space:nowrap;width:540px"><div class="xml codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="sc3"><span class="re1">&lt;?xml</span> <span class="re0">version</span>=<span class="st0">&quot;1.0&quot;</span> <span class="re0">encoding</span>=<span class="st0">&quot;UTF-8&quot;</span><span class="re2">?&gt;</span></span><br />
<span class="sc3"><span class="re1">&lt;project</span> <span class="re0">name</span>=<span class="st0">&quot;premier_projet&quot;</span> <span class="re0">default</span>=<span class="st0">&quot;lint&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;target</span> <span class="re0">name</span>=<span class="st0">&quot;lint&quot;</span> <span class="re0">description</span>=<span class="st0">&quot;Vérifie la syntaxe PHP&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;phplint<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;fileset</span> <span class="re0">dir</span>=<span class="st0">&quot;/home/mon_projet/src/&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;include</span> <span class="re0">name</span>=<span class="st0">&quot;**/*.php&quot;</span><span class="re2">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;exclude</span> <span class="re0">name</span>=<span class="st0">&quot;lib/Zend/**/*.php&quot;</span><span class="re2">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/fileset<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/phplint<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/target<span class="re2">&gt;</span></span></span><br />
<span class="sc3"><span class="re1">&lt;/project<span class="re2">&gt;</span></span></span></div></div>
<p>Enregistrez ce fichier avec le nom build.xml (le fichier par défaut utilisé par phing) dans le dossier build de votre projet, par exemple</p>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:540px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="sy0">/</span>home<span class="sy0">/</span>mon_projet<span class="sy0">/</span>build<span class="sy0">/</span></div></div>
<p>Ouvrez une console et lancez ensuite la commande phing depuis le dossier du fichier build.xml</p>
<p><strong>Commande</strong></p>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:540px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw3">cd</span> <span class="sy0">/</span>home<span class="sy0">/</span>mon_projet<span class="sy0">/</span>build<span class="sy0">/</span><br />
phing</div></div>
<p>Le fichier build.xml est très explicite, cette commande va donc vérifier, pour tous les fichiers PHP de mon dossier source a l&#8217;exclusion de ceux de la bibliothèque Zend, que leur syntaxe est bien respectée.</p>
<p>Autre exemple, pour générer automatiquement la documentation de classes PHP.</p>
<p><strong>Fichier build.xml</strong></p>
<div class="codecolorer-container xml " style="overflow:auto;white-space:nowrap;width:540px"><div class="xml codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="sc3"><span class="re1">&lt;?xml</span> <span class="re0">version</span>=<span class="st0">&quot;1.0&quot;</span> <span class="re0">encoding</span>=<span class="st0">&quot;UTF-8&quot;</span><span class="re2">?&gt;</span></span><br />
<span class="sc3"><span class="re1">&lt;project</span> <span class="re0">name</span>=<span class="st0">&quot;premier_projet&quot;</span> <span class="re0">default</span>=<span class="st0">&quot;doc&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;target</span> <span class="re0">name</span>=<span class="st0">&quot;doc&quot;</span> <span class="re0">description</span>=<span class="st0">&quot;Génère la documentation&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;phpdoc</span> <span class="re0">title</span>=<span class="st0">&quot;API Documentation&quot;</span></span><br />
<span class="sc3">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">destdir</span>=<span class="st0">&quot;/home/mon_projet/api&quot;</span></span><br />
<span class="sc3">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">sourcecode</span>=<span class="st0">&quot;no&quot;</span> <span class="re0">output</span>=<span class="st0">&quot;HTML:Smarty:PHP&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;fileset</span> <span class="re0">dir</span>=<span class="st0">&quot;/home/mon_projet/src/&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;include</span> <span class="re0">name</span>=<span class="st0">&quot;**/*.php&quot;</span><span class="re2">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;exclude</span> <span class="re0">name</span>=<span class="st0">&quot;lib/Zend/**/*.php&quot;</span><span class="re2">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/fileset<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/phpdoc<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/target<span class="re2">&gt;</span></span></span><br />
<span class="sc3"><span class="re1">&lt;/project<span class="re2">&gt;</span></span></span></div></div>
<p><strong>Commandes</strong></p>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:540px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw3">cd</span> <span class="sy0">/</span>home<span class="sy0">/</span>mon_projet<span class="sy0">/</span>build<span class="sy0">/</span><br />
phing</div></div>
<p>Phing tout comme Ant gère la dépendance des tâches. Dans notre cas, si nous voulons générer la documentation après la vérification syntaxique. Il suffit de modifier notre fichier build.xml comme suit :</p>
<p><strong>Fichier build.xml</strong></p>
<div class="codecolorer-container xml " style="overflow:auto;white-space:nowrap;width:540px"><div class="xml codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="sc3"><span class="re1">&lt;?xml</span> <span class="re0">version</span>=<span class="st0">&quot;1.0&quot;</span> <span class="re0">encoding</span>=<span class="st0">&quot;UTF-8&quot;</span><span class="re2">?&gt;</span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;project</span> <span class="re0">name</span>=<span class="st0">&quot;premier_projet&quot;</span> <span class="re0">default</span>=<span class="st0">&quot;build&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;target</span> <span class="re0">name</span>=<span class="st0">&quot;lint&quot;</span> <span class="re0">description</span>=<span class="st0">&quot;Vérifie la syntaxe PHP&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;phplint<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;fileset</span> <span class="re0">dir</span>=<span class="st0">&quot;/home/mon_projet/src/&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;include</span> <span class="re0">name</span>=<span class="st0">&quot;**/*.php&quot;</span><span class="re2">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;exclude</span> <span class="re0">name</span>=<span class="st0">&quot;lib/Zend/**/*.php&quot;</span><span class="re2">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/fileset<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/phplint<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/target<span class="re2">&gt;</span></span></span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;target</span> <span class="re0">name</span>=<span class="st0">&quot;doc&quot;</span> <span class="re0">description</span>=<span class="st0">&quot;Génère la documentation&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;phpdoc</span> <span class="re0">title</span>=<span class="st0">&quot;API Documentation&quot;</span> </span><br />
<span class="sc3">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">destdir</span>=<span class="st0">&quot;/home/mon_projet/api&quot;</span></span><br />
<span class="sc3">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">sourcecode</span>=<span class="st0">&quot;no&quot;</span></span><br />
<span class="sc3">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">output</span>=<span class="st0">&quot;HTML:Smarty:PHP&quot;</span><span class="re2">&gt;</span></span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;fileset</span> <span class="re0">dir</span>=<span class="st0">&quot;/home/mon_projet/src/&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;include</span> <span class="re0">name</span>=<span class="st0">&quot;**/*.php&quot;</span><span class="re2">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;exclude</span> <span class="re0">name</span>=<span class="st0">&quot;lib/Zend/**/*.php&quot;</span><span class="re2">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/fileset<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/phpdoc<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/target<span class="re2">&gt;</span></span></span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;target</span> </span><br />
<span class="sc3">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">name</span>=<span class="st0">&quot;build&quot;</span></span><br />
<span class="sc3">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">depends</span>=<span class="st0">&quot;lint, doc&quot;</span></span><br />
<span class="sc3">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">description</span>=<span class="st0">&quot;Syntaxe PHP et Documentation&quot;</span> <span class="re2">/&gt;</span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/project<span class="re2">&gt;</span></span></span></div></div>
<p><strong>Commande</strong></p>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:540px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">phing</div></div>
<p>La commande <tt>phing</tt> va automatiquement séquencer les 2 tâches <tt>lint</tt> et <tt>doc</tt> car la tâche <tt>build</tt> dépend d&#8217;elles.<br />
Si nous voulons seulement générer la documentation il suffit de taper la commande suivante.</p>
<p><strong>Commande</strong></p>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:540px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">phing doc</div></div>
<p>Phing est très puissant. Il permet de gérer des tâches conditionnelles, des tâches spécifiques PHP comme l&#8217;analyse de code par le compilateur Zend, le lancement de tests unitaires classiques ou avec <a href="http://labs.pimsworld.org/2008/12/installation-de-selenium-rc-sous-ubuntu">Selenium</a>. Il sait aussi piloter des tâches plus génériques comme l&#8217;update de dépôt SVN ou l&#8217;exécution de commandes externes. La liste longue et complète des tâches disponibles se trouve dans la documentation de <a href="http://phing.info/docs/guide/current/">Phing</a>.</p>
<h2>Installation de Phing</h2>
<p>Pour installer Phing, le plus simple est d&#8217;utiliser PEAR. Sous Ubuntu tapez les commandes suivantes en mode super utilisateur.</p>
<p><strong>Installation de PEAR, la bibliothèque d&#8217;extensions à PHP</strong></p>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:540px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">apt-get</span> <span class="kw2">install</span> php-pear</div></div>
<p><strong>Installation de Phing</strong></p>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:540px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">pear channel-discover pear.phing.info<br />
pear <span class="kw2">install</span> phing<span class="sy0">/</span>phing</div></div>
<h2>On en parle ailleurs&#8230;</h2>
<p>Un <a href="http://nsslive.net/2009/02/16/shell-scripts-no-more/">article en anglais de Nabeel Shahzad</a> décrit comment il s&#8217;est débarrassé des scripts grâce à Phing </p>
]]></content:encoded>
			<wfw:commentRss>http://labs.pimsworld.org/2009/01/phing-automatise-les-operations-repetitives-des-developpements-php/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
