<?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>blogafab.com</title>
	<atom:link href="http://www.blogafab.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.blogafab.com</link>
	<description>Le blog de Fabien Pennequin</description>
	<lastBuildDate>Sat, 22 Oct 2011 16:48:57 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Installer et utiliser NodeJS et le module Less sur Mac OS X</title>
		<link>http://www.blogafab.com/installer-et-utiliser-nodejs-et-le-module-less-sur-mac-os-x/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=installer-et-utiliser-nodejs-et-le-module-less-sur-mac-os-x</link>
		<comments>http://www.blogafab.com/installer-et-utiliser-nodejs-et-le-module-less-sur-mac-os-x/#comments</comments>
		<pubDate>Tue, 30 Aug 2011 20:41:25 +0000</pubDate>
		<dc:creator>Fabien</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Less]]></category>
		<category><![CDATA[lion]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[macport]]></category>
		<category><![CDATA[NodeJS]]></category>

		<guid isPermaLink="false">http://www.blogafab.com/?p=396</guid>
		<description><![CDATA[Connaissez-vous LESS ? Il s&#8217;agit d&#8217;une sur-couche de CSS apportant son lot d&#8217;améliorations pour faciliter l&#8217;écriture de feuille de styles. LESS vous permettra par exemple de définir des fonctions ou des variables que vous pourrez utiliser dans vos règles CSS. &#8230; <a href="http://www.blogafab.com/installer-et-utiliser-nodejs-et-le-module-less-sur-mac-os-x/">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Connaissez-vous LESS ? Il s&#8217;agit d&#8217;une sur-couche de CSS apportant son lot d&#8217;améliorations pour faciliter l&#8217;écriture de feuille de styles. LESS vous permettra par exemple de définir des fonctions ou des variables que vous pourrez utiliser dans vos règles CSS. Pour en savoir plus, n&#8217;hésitez pas à consulter le site officiel de <a href="http://lesscss.org/">LESS</a>.</p>
<p>Pour utiliser LESS sur vos sites internet, vous devez « convertir » vos fichiers LESS en CSS afin que les styles soient interprétés par les navigateurs web. Le site officiel propose deux solutions, soit réaliser la conversion côté client avec le navigateur, soit côté serveur avec nodejs. La 1ère solution rend votre site web dépendant l&#8217;activation de Javascript par le visiteur, ce qui n&#8217;est pas une très bonne idée. J&#8217;ai donc choisi la solution &laquo;&nbsp;serveur&nbsp;&raquo;&#8230;</p>
<h2>Installation de NodeJS et LESS</h2>
<p>Nous allons voir ici comment installer NodeJS et le module less sur Mac OS X 10.6 (et 10.7) avec MacPort. L&#8217;installation de MacPort devra préalablement être réalisée.</p>
<ol>
<li>Commencez par installer NodeJS avec MacPort en utilisant la commande suivante :
<pre class="niji_code niji_shell" style="">port install nodejs</pre>
</li>
<li>Installez maintenant <abbr title="Node Package Manager">NPM</abbr> avec la commande ci-dessous. <abbr title="Node Package Manager">NPM</abbr> est un gestionnaire de packages/modules pour Node permettant de facilité l&#8217;installation de modules.
<pre class="niji_code niji_shell" style="">sudo port install npm</pre>
</li>
<li>Une fois l&#8217;installation de <abbr title="Node Package Manager">NPM</abbr> terminée, procédons à l&#8217;installation du module LESS pour NodeJS. A noter la présence du &laquo;&nbsp;-g&nbsp;&raquo; dans la commande afin de précéder à une installation globale (pour tous les utilisateurs)
<pre class="niji_code niji_shell" style="">sudo npm install less -g</pre>
</li>
<li>Vous avez terminé l&#8217;installation de NodeJS, NPM et LESS</li>
</ol>
<h2>Utilisation</h2>
<p>Écrivez un fichier less. Vous pouvez prendre un exemple du site officiel par exemple.</p>
<pre class="niji_code niji_shell" style="">lessc styles.less</pre>
<h2>Conclusion</h2>
<p>Voilà, vous êtes maintenant fin prêt pour l&#8217;utilisation de LESS dans vos projets web. Je vous recommande de faire un tour sur GitHub où vous trouverez des fichiers LESS pour facilité l&#8217;utilisation CSS3 sur les principaux navigateurs.</p>
<p>Personnellement, j&#8217;utilise LESS depuis presque 1 an et c&#8217;est un réel plaisir d&#8217;écrire des styles CSS avec un tel outil. Essayez-le !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogafab.com/installer-et-utiliser-nodejs-et-le-module-less-sur-mac-os-x/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Installer Apache 2, MySQL 5 et PHP 5.3 sur Mac OS 10.7 Lion avec MacPort</title>
		<link>http://www.blogafab.com/installer-apache-2-mysql-5-et-php-5-3-sur-mac-os-10-7-lion-avec-macport/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=installer-apache-2-mysql-5-et-php-5-3-sur-mac-os-10-7-lion-avec-macport</link>
		<comments>http://www.blogafab.com/installer-apache-2-mysql-5-et-php-5-3-sur-mac-os-10-7-lion-avec-macport/#comments</comments>
		<pubDate>Mon, 01 Aug 2011 21:00:04 +0000</pubDate>
		<dc:creator>Fabien</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[lion]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[macport]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://www.blogafab.com/?p=402</guid>
		<description><![CDATA[Bien que Apache et PHP soient pré-installés sur Mac OS X, j&#8217;évite depuis plusieurs années de les utiliser. Au départ pour un problème de compilation d&#8217;une extension PHP, aujourd&#8217;hui pour ne plus être dépendant d&#8217;Apple dans la mise à jour &#8230; <a href="http://www.blogafab.com/installer-apache-2-mysql-5-et-php-5-3-sur-mac-os-10-7-lion-avec-macport/">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Bien que Apache et PHP soient pré-installés sur Mac OS X, j&#8217;évite depuis plusieurs années de les utiliser. Au départ pour un problème de compilation d&#8217;une extension PHP, aujourd&#8217;hui pour ne plus être dépendant d&#8217;Apple dans la mise à jour de ces logiciels.</p>
<p>J&#8217;utilise donc MacPort, un excellent gestionnaire de packages pour Mac OS X, qui permet de compiler et d&#8217;installer toutes sortes de logiciels open-source bien utiles.</p>
<p>La sortie récente de Mac OS X Lion, la nouvelle version du système d&#8217;exploitation d&#8217;Apple pour ordinateur, a été l&#8217;occasion de ré-installer complétement mon environnement LAMP&#8230;</p>
<p>Je vous propose ici un guide sur l&#8217;installation et la configuration d&#8217;Apache, MySQL et PHP avec MacPort&#8230;<br />
<span id="more-402"></span></p>
<h2>Installation de votre environnement LAMP</h2>
<p>Nous allons dans une premier temps procéder à l&#8217;installation d&#8217;Apache 2, MySQL 5 et PHP 5.3 et ses extensions. Pour cela, nous devons installer MacPorts 2.0&#8230;</p>
<h3>Installation MacPorts 2.0</h3>
<p>MacPorts 2.0 nécessite au préalable que les outils développeur Mac OS X Lion soient installés. Vous les obtiendrez en installant Xcode 4, disponible sur le Mac App Store d&#8217;Apple.</p>
<ol>
<li>Téléchargez MacPorts 2.0 sur <a href="http://www.macports.org/">le site officiel</a></li>
<li>Ouvrez le fichier .dmg que vous venez de télécharger</li>
<li>Lancez le fichier .pkg et suivez les instructions</li>
</ol>
<p>A noter que dans la suite de l&#8217;article, les commandes données sont à exécuter dans le terminal et en mode &laquo;&nbsp;super-admin&nbsp;&raquo;, d&#8217;où le <em>sudo</em> au début des commandes.</p>
<h3>Installation Apache 2</h3>
<ol>
<li>Téléchargez et installez Apache2 et ces dépendances :
<pre class="niji_code niji_shell" style="">sudo port install apache2</pre>
</li>
<li>Une fois l&#8217;installation terminée, vous pouvez activer lancement automatique de Apache au démarrage de l&#8217;ordinateur :
<pre class="niji_code niji_shell" style="">sudo port load apache2</pre>
</li>
</ol>
<h3>Installation MySQL 5</h3>
<ol>
<li>Téléchargez et installez MySQL 5 et ces dépendances :
<pre class="niji_code niji_shell" style="">sudo port install mysql5</pre>
</li>
<li>Installez/Activez le serveur MySQL 5 :
<pre class="niji_code niji_shell" style="">sudo port install mysql5-server</pre>
</li>
<li>Une fois l&#8217;installation terminée, vous pouvez activer le lancement automatique de MySQL au démarrage de l&#8217;ordinateur :
<pre class="niji_code niji_shell" style="">sudo port load mysql5-server</pre>
</li>
<li>Terminez l&#8217;installation de MySQL :
<pre class="niji_code niji_shell" style="">sudo -u _mysql mysql_install_db5</pre>
</li>
<li>Une fois l&#8217;installation terminée, vous pouvez lancer MySQL au démarrage de l&#8217;ordinateur :
<pre class="niji_code niji_shell" style="">sudo port load mysql5</pre>
</li>
</ol>
<h3>Installation PHP 5.3</h3>
<ol>
<li>Téléchargez et installez PHP 5.3 et ces dépendances. A noter ici que je choisi également d&#8217;activer le PEAR, d&#8217;où le <em>+pear</em>.
<pre class="niji_code niji_shell" style="">sudo port install php5 +pear</pre>
</li>
<li>Ajoutez le module PHP pour Apache 2 :
<pre class="niji_code niji_shell" style="">sudo /opt/local/apache2/bin/apxs -a -e -n <span class="niji_string">&quot;php5&quot;</span> /opt/local/apache2/modules/libphp5.so</pre>
</li>
<li>Créez le fichier de configuration <em>php.ini</em>de PHP :
<pre class="niji_code niji_shell" style="">sudo cp /opt/local/etc/php5/php.ini-development /opt/local/etc/php5/php.ini</pre>
</li>
<li>Installez et activez MySQL pour PHP :
<pre class="niji_code niji_shell" style="">sudo port install php5-mysql</pre>
</li>
<li>Étape optionnelle : Installez quelques extensions utiles pour PHP (apc, curl, gd, iconv, mbstring, &#8230;).
<pre class="niji_code niji_shell" style="">sudo port install php5-apc php5-curl php5-gd php5-iconv php5-intl php5-mbstring php5-mcrypt php5-posix php5-sqlite php5-xdebug php5-zip</pre>
</li>
</ol>
<h2>Configuration de votre environnement LAMP</h2>
<p>Les logiciels sont maintenant installés, reste à les configurer correctement&#8230;</p>
<h3>Configuration Apache 2</h3>
<p>Les étapes ci-dessous permettent de configurer le support de PHP dans Apache et d&#8217;activer le module UserDir (facultatif).</p>
<ul>
<li>Activer PHP dans Apache<em></em>
<ol>
<li>Éditez le fichier /opt/local/apache2/conf/httpd.conf</li>
<li>Ajoutez à la fin du fichier
<pre class="niji_code niji_shell" style=""><span class="niji_comment"># Include PHP configuration
</span>Include conf/extra/mod_php.conf</pre>
</li>
</ol>
</li>
<li>Ajouter index.php dans les pages d&#8217;index reconnues par Apache<em></em>
<ol>
<li>Éditez le fichier /opt/local/apache2/conf/httpd.conf</li>
<li>Recherchez la ligne ci-dessous :
<pre class="niji_code niji_shell" style="">DirectoryIndex index.html</pre>
</li>
<li>Ajoutez sur la même ligne, à la fin :
<pre class="niji_code niji_shell" style=""> index.php</pre>
</li>
</ol>
</li>
<li>Étape optionnelle : Activer l&#8217;extension UserDir pour Apache. Cette extension permet d&#8217;avoir des urls dédiées pour chaque utilisateur de l&#8217;ordinateur du type <em>http://localhost/~utilisateur/</em>
<ol>
<li>Éditez le fichier /opt/local/apache2/conf/httpd.conf</li>
<li>Recherchez et décommentez la ligne ci-dessous :
<pre class="niji_code niji_shell" style="">#Include conf/extra/httpd-userdir.conf</pre>
</li>
<li>Étape optionnelle : Autoriser l&#8217;ajout/suppression d&#8217;options via un .htaccess (exemple <code>Options +FollowSymLinks</code>)
<ol>
<li>Éditez le fichier /opt/local/apache2/conf/extra/httpd-userdir.conf</li>
<li>Recherchez la ligne ci-dessous :
<pre class="niji_code niji_shell" style="">AllowOverride FileInfo AuthConfig Limit Indexes</pre>
</li>
<li>Ajoutez sur la même ligne, à la fin :
<pre class="niji_code niji_shell" style=""> Options</pre>
</li>
</ol>
</li>
</ol>
</li>
<li>Une fois les modifications effectuées, vous pouvez (re)démarrer Apache :
<pre class="niji_code niji_shell" style="">sudo /opt/local/apache2/bin/apachectl restart</pre>
</li>
</ul>
<h3>Configuration MySQL 5</h3>
<p>Les étapes ci-dessous ont pour objectif de configurer et sécuriser votre serveur MySQL.</p>
<ul>
<li>Démarrez le serveur MySQL
<pre class="niji_code niji_shell" style="">sudo /opt/local/lib/mysql5/bin/mysqld_safe &amp;</pre>
</li>
<li>Sécurisez votre serveur MySQL. Je vous recommande de configurer le mot de passe root et de répondre &laquo;&nbsp;Yes&nbsp;&raquo; à toutes les questions.
<pre class="niji_code niji_shell" style="">sudo /opt/local/lib/mysql5/bin/mysql_secure_installation</pre>
</li>
</ul>
<h3>Configuration PHP 5</h3>
<ul>
<li>Configurer MySQL pour PHP<em></em>
<ol>
<li>Éditez le fichier /opt/local/etc/php5/php.ini</li>
<li>Recherchez les paramètres <code>pdo_mysql.default_socket</code>, <code>mysql.default_socket</code>, <code>mysqli.default_socket</code>et mettez comme valeur ceci :
<pre class="niji_code niji_shell" style="">/opt/local/var/run/mysql5/mysqld.sock</pre>
</li>
</ol>
</li>
<li>Configurer le fuseau horaire par défaut<em></em>
<ol>
<li>Éditez le fichier /opt/local/etc/php5/php.ini</li>
<li>Recherchez la ligne suivante :
<pre class="niji_code niji_shell" style="">;date.timezone =</pre>
</li>
<li>Remplacez par :
<pre class="niji_code niji_shell" style="">date.timezone = <span class="niji_string">&quot;Europe/Paris&quot;</span></pre>
</li>
</ol>
</li>
<li>Étape optionnelle : Activer les archives Phar<em></em>
<ol>
<li>Éditez le fichier /opt/local/etc/php5/php.ini</li>
<li>Recherchez et décommentez la ligne ci-dessous
<pre class="niji_code niji_shell" style="">;phar.readonly = On</pre>
</li>
</ol>
</li>
<li>Une fois les modifications terminées, redémarrez votre serveur Apache 2.</li>
</ul>
<h2>Bonus</h2>
<h3>Bonus #1 : Installation et configuration de PhpMyAdmin</h3>
<p>Si vous souhaitez installer l&#8217;outil PhpMyAdmin afin d&#8217;administrer vos bases de données MySQL depuis une interface web, voici les étapes à suivre.</p>
<ol>
<li>Installez PhpMyAdmin
<pre class="niji_code niji_shell" style="">sudo port install phpmyadmin</pre>
</li>
<li>Activez PhpMyAdmin dans Apache
<ol>
<li>Créez le fichier /opt/local/apache2/conf/extra/mod_phpmyadmin.conf avec comme contenu ceci :
<pre class="niji_code niji_conf" style="">AliasMatch ^/phpmyadmin(?:/)?(/.<span class="niji_keyword">*</span>)?$ <span class="niji_string">&quot;/opt/local/www/phpmyadmin$1&quot;</span>

<span class="niji_keyword">&lt;</span>Directory <span class="niji_string">&quot;/opt/local/www/phpmyadmin&quot;</span><span class="niji_keyword">&gt;</span>
  Options <span class="niji_keyword">-</span>Indexes
  AllowOverride None
  Order allow,deny
  Allow from all

  LanguagePriority en de es fr ja ko pt<span class="niji_keyword">-</span>br ru
  ForceLanguagePriority Prefer Fallback
<span class="niji_keyword">&lt;</span>/Directory<span class="niji_keyword">&gt;</span></pre>
</li>
<li>Éditez le fichier /opt/local/apache2/conf/extra/mod_php.conf</li>
<li>Recherchez la ligne ci-dessous :
<pre class="niji_code niji_conf" style=""><span class="niji_keyword">&lt;</span>/IfModule<span class="niji_keyword">&gt;</span></pre>
</li>
<li>Ajoutez au-dessus les lignes suivantes :
<pre class="niji_code niji_conf" style=""><span class="niji_comment"># PhpMyAdmin configuration
</span>Include conf/extra/mod_phpmyadmin.conf</pre>
</li>
<li>Redémarrez Apache 2</li>
</ol>
</li>
<li>Étape optionnelle : Utiliser l&#8217;authentification HTTP plutôt que par cookies
<ol>
<li>Éditez le fichier /opt/local/www/phpmyadmin/config.inc.php</li>
<li>Recherchez la ligne ci-dessous et remplacez <code>cookie</code> par <code>http</code>
<pre class="niji_code niji_php" style=""><span class="niji_variable">$cfg</span>[<span class="niji_string">'Servers'</span>][<span class="niji_variable">$i</span>][<span class="niji_string">'auth_type'</span>] <span class="niji_keyword">=</span> <span class="niji_string">'cookie'</span>;</pre>
</li>
</ol>
</li>
</ol>
<h3>Bonus #2 : Restauration de base de données MySQL volumineuses</h3>
<p>Si vous essayez d&#8217;importer une base de données assez volumineuses (plusieurs Mo), vous obtiendrez une message d&#8217;erreur de MySQL :</p>
<blockquote><p>Got a packet bigger than &#8216;max_allowed_packet&#8217;</p></blockquote>
<p>Pour éviter ce problème vous devez personnaliser le fichier de configuration de MySQL. Voici les étapes à suivre.</p>
<ol>
<li>Créez le fichier de configuration
<pre class="niji_code niji_shell" style="">sudo cp /opt/local/share/mysql5/mysql/my-medium.cnf /opt/local/etc/mysql5/my.cnf</pre>
</li>
<li>Éditez le fichier /opt/local/etc/mysql5/my.cnf</li>
<li>Recherchez la ligne ci-dessous :
<pre class="niji_code niji_shell" style="">max_allowed_packet = 1M</pre>
</li>
<li>Remplacez par :
<pre class="niji_code niji_shell" style="">max_allowed_packet = 16M</pre>
</li>
<li>Redémarrez le serveur MySQL</li>
<li>Si vous obtenez toujours cette erreur, éditez à nouveau le fichier de configuration et augmentez la valeur de <code>max_allowed_packet</code></li>
</ol>
<h2>Conclusion</h2>
<p>Votre environnement LAMP est maintenant prêt et vous pouvez commencer ou prendre vos développements PHP/MySQL avec Mac OS X Lion en plaçant vos fichiers PHP dans votre dossier <em>Sites</em>&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogafab.com/installer-apache-2-mysql-5-et-php-5-3-sur-mac-os-10-7-lion-avec-macport/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Restart&#8230;</title>
		<link>http://www.blogafab.com/restart/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=restart</link>
		<comments>http://www.blogafab.com/restart/#comments</comments>
		<pubDate>Sun, 24 Jul 2011 13:54:23 +0000</pubDate>
		<dc:creator>Fabien</dc:creator>
				<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://www.blogafab.com/?p=401</guid>
		<description><![CDATA[Voilà un bout de temps que je n&#8217;ai plus écrit de nouveau article&#8230; Surtout par manque de temps, préférant consacrer mon temps libre à mon site internet sur Smallville, pour la dernière année de la série tv, et&#8230; un nouveau &#8230; <a href="http://www.blogafab.com/restart/">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Voilà un bout de temps que je n&#8217;ai plus écrit de nouveau article&#8230; Surtout par manque de temps, préférant consacrer mon temps libre à mon site internet sur Smallville, pour la dernière année de la série tv, et&#8230; un nouveau projet personnel sur lequel je travaille depuis plus d&#8217;un an et qui devrait voir le jour, je l&#8217;espère, dans très peu de temps.</p>
<p>Aujourd&#8217;hui, je remets donc en route mon blog et de nouveaux articles sont déjà en préparation. Cela sera l&#8217;occasion de parler de Symfony2, que je suis/utilise depuis plus d&#8217;un an maintenant, mais de Mac OS X, de développement web et plein d&#8217;autres choses.</p>
<p>Au passage, ce blog a été mis à jour à la dernière version de WordPress et s&#8217;offre un tout nouveau design. Le thème est basé sur celui par défaut de WordPress 3.2 nommé &laquo;&nbsp;Twenty Eleven&nbsp;&raquo; que j&#8217;ai un peu modifié pour mes besoins.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogafab.com/restart/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Utiliser l&#8217;extension Taggable de Doctrine avec Symfony 1.3/1.4</title>
		<link>http://www.blogafab.com/utiliser-extension-taggable-doctrine-symfony/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=utiliser-extension-taggable-doctrine-symfony</link>
		<comments>http://www.blogafab.com/utiliser-extension-taggable-doctrine-symfony/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 16:28:27 +0000</pubDate>
		<dc:creator>Fabien</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Doctrine]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[ORM]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://www.blogafab.com/?p=368</guid>
		<description><![CDATA[Jusqu&#8217;à symfony 1.2, si vous vouliez ajouter facilement de nouvelles fonctionnalités au framework PHP5 il fallait se diriger vers son importante base de plugins. Avec symfony 1.3 et 1.4, bien sûr vous pouvez toujours compter sur les plugins symfony mais &#8230; <a href="http://www.blogafab.com/utiliser-extension-taggable-doctrine-symfony/">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Jusqu&#8217;à symfony 1.2, si vous vouliez ajouter facilement de nouvelles fonctionnalités au framework PHP5 il fallait se diriger vers son importante base de plugins. Avec symfony 1.3 et 1.4, bien sûr vous pouvez toujours compter sur les <a href="http://www.symfony-project.org/plugins/">plugins symfony</a> mais viennent maintenant s&#8217;ajouter les <a href="http://www.doctrine-project.org/extensions">extensions pour Doctrine</a>&#8230;</p>
<p>Si vous utilisez Doctrine comme <a href="http://fr.wikipedia.org/wiki/Mapping_objet-relationnel">Object Relational Mapper (ORM)</a>, vous connaissez certainement les behaviours <em>Timestampable</em>, <em>Sluggable</em> ou encore <em>SoftDelete</em>. Les extensions Doctrine vous permettent justement d&#8217;en ajouter de nouveaux très facilement, en quelques clics ou lignes de commande.</p>
<p>Aujourd&#8217;hui, je vous propose d&#8217;installer et d&#8217;utiliser l&#8217;extension Taggable. Cette dernière permet d&#8217;ajouter des tags sur les modèles de votre choix. L&#8217;intérêt peut être de faire des recommandations ou retrouver des éléments relatifs à un autre.</p>
<p><span id="more-368"></span></p>
<p>Commençons d&#8217;abord par installer l&#8217;extension Taggable :</p>
<ol>
<li>Placez-vous dans le dossier racine de votre projet symfony.
<pre class="niji_code niji_shell" style=""><span class="niji_function">cd</span> /chemin/vers/le/projet/symfony/</pre>
</li>
<li>Créez un dossier <em>doctrine_extension</em> dans <em>lib</em>.
<pre class="niji_code niji_shell" style=""><span class="niji_function">mkdir</span> lib/doctrine_extension</pre>
</li>
<li>Téléchargez l&#8217;extension Taggable avec subversion.
<pre class="niji_code niji_shell" style="">svn co http://svn.doctrine-project.org/extensions/Taggable/branches/1.2-1.0 lib/doctrine_extension/Taggable</pre>
</li>
<li>Videz le cache symfony (peut-être plus nécessaire mais c&#8217;est encore un réflexe chez moi).
<pre class="niji_code niji_shell" style="">php symfony cc</pre>
</li>
<li>Activez l&#8217;extension Doctrine :
<ul>
<li>Éditez le fichier config/ProjectConfiguration.class.php</li>
<li>Si vous ne l&#8217;avez pas encore, créez la méthode <em>configureDoctrine</em>
<pre class="niji_code niji_php" style="">  <span class="niji_keyword">public</span> <span class="niji_keyword">function</span> <span class="niji_method">configureDoctrine</span>(Doctrine_Manager <span class="niji_variable">$manager</span>)
  {
  }</pre>
</li>
<li>Ajoutez le code ci-dessous dans la méthode.
<pre class="niji_code niji_php" style="">    <span class="niji_class">Doctrine</span><span class="niji_keyword"><span class="niji_keyword">::</span></span>setExtensionsPath(<span class="niji_class">sfConfig</span><span class="niji_keyword"><span class="niji_keyword">::</span></span>get(<span class="niji_string">'sf_lib_dir'</span>)<span class="niji_keyword">.</span><span class="niji_string">'/doctrine_extension'</span>);
    <span class="niji_variable">$manager</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>registerExtension(<span class="niji_string">'Taggable'</span>);</pre>
</li>
</ul>
</li>
</ol>
<p>Voilà l&#8217;extension avec maintenant installée et activée. Voyons maintenant, comment l&#8217;utiliser. Pour cela je vais prendre un exemple très simple avec des articles qui possèdent des tags.</p>
<ol>
<li>Définissez le modèle Article en copiant le contenu ci-dessous dans un fichier config/doctrine/10_articles.yml
<pre class="niji_code niji_yaml" style="">Article:
  actAs:
    Taggable:
  columns:
    title:          { type: <span class="niji_keyword">string</span>(<span class="niji_int">255</span>), notnull: <span class="niji_int">true</span>, notblank: <span class="niji_int">true</span> }
    body:           { type: clob, notnull: <span class="niji_int">true</span>, notblank: <span class="niji_int">true</span> }
</pre>
</li>
<li>Ajoutez des fixtures en copiant le contenu ci-dessous dans un fichier data/fixtures/10_articles.yml
<pre class="niji_code niji_yaml" style="">Article:
  Article_1:
    title: Mon premier article
    body: |
      Hello World <span class="niji_keyword">!</span>
      Ceci est mon premier article.
    tags: hello, world, article <span class="niji_int">1</span>

  Article_2:
    title: Mon second article
    body: |
      Hello World <span class="niji_keyword">!</span>
      Ceci est mon second article.
    tags: hello, world, article <span class="niji_int">2</span>
</pre>
</li>
<li>Créez les fichiers php associés au modèle et chargez les fixtures avec la commande suivante :
<pre class="niji_code niji_shell" style="">php symfony doctrine:build --all --and-load</pre>
</li>
<li>Créez un module Article dans l&#8217;application frontend
<pre class="niji_code niji_shell" style="">php symfony generate:module frontend article</pre>
</li>
<li>Éditez le fichier apps/frontend/modules/article/actions.class.php et remplacez le code de la méthode executeIndex par le code ci-dessous
<pre class="niji_code niji_php" style="">    <span class="niji_variable">$this</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>articles <span class="niji_keyword">=</span> <span class="niji_class">Doctrine</span><span class="niji_keyword"><span class="niji_keyword">::</span></span>getTable(<span class="niji_string">'Article'</span>)<span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>findAll();
    <span class="niji_variable">$this</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>popular_tags <span class="niji_keyword">=</span> <span class="niji_class">Doctrine</span><span class="niji_keyword"><span class="niji_keyword">::</span></span>getTable(<span class="niji_string">'TaggableTag'</span>)<span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>getPopularTags();</pre>
</li>
<li>Éditez le fichier apps/frontend/modules/article/indexSuccess.php et collez le code ci-dessous
<pre class="niji_code niji_php" style=""><span class="niji_keyword">&lt;</span>h1<span class="niji_keyword">&gt;</span>Articles<span class="niji_keyword">&lt;</span>/h1<span class="niji_keyword">&gt;</span>

<span class="niji_keyword">&lt;</span>h2<span class="niji_keyword">&gt;</span>Liste des articles<span class="niji_keyword">&lt;</span>/h2<span class="niji_keyword">&gt;</span>
&lt;?php <span class="niji_keyword">foreach</span> (<span class="niji_variable">$articles</span> <span class="niji_keyword">as</span> <span class="niji_variable">$article</span>): ?<span class="niji_keyword">&gt;</span>
  <span class="niji_keyword">&lt;</span>h3<span class="niji_keyword">&gt;</span>&lt;?php <span class="niji_function">echo</span> <span class="niji_variable">$article</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>title ?<span class="niji_keyword">&gt;</span><span class="niji_keyword">&lt;</span>/h3<span class="niji_keyword">&gt;</span>
  <span class="niji_keyword">&lt;</span>p<span class="niji_keyword">&gt;</span>&lt;?php <span class="niji_function">echo</span> <span class="niji_function">nl2br</span>(<span class="niji_variable">$article</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>body) ?<span class="niji_keyword">&gt;</span><span class="niji_keyword">&lt;</span>/p<span class="niji_keyword">&gt;</span>
  <span class="niji_keyword">&lt;</span>p<span class="niji_keyword">&gt;</span>Tags : &lt;?php <span class="niji_function">echo</span> <span class="niji_variable">$article</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>getTagsString() ?<span class="niji_keyword">&gt;</span><span class="niji_keyword">&lt;</span>/p<span class="niji_keyword">&gt;</span>
&lt;?php <span class="niji_keyword">endforeach</span> ?<span class="niji_keyword">&gt;</span>

<span class="niji_keyword">&lt;</span>h2<span class="niji_keyword">&gt;</span>Tags populaires<span class="niji_keyword">&lt;</span>/h2<span class="niji_keyword">&gt;</span>
<span class="niji_keyword">&lt;</span>ul<span class="niji_keyword">&gt;</span>
&lt;?php <span class="niji_keyword">foreach</span> (<span class="niji_variable">$popular_tags</span> <span class="niji_keyword">as</span> <span class="niji_variable">$tag</span>): ?<span class="niji_keyword">&gt;</span>
  <span class="niji_keyword">&lt;</span>li<span class="niji_keyword">&gt;</span>&lt;?php <span class="niji_function">echo</span> <span class="niji_variable">$tag</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>name ?<span class="niji_keyword">&gt;</span> (&lt;?php <span class="niji_function">echo</span> <span class="niji_variable">$tag</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>total_num ?<span class="niji_keyword">&gt;</span>)<span class="niji_keyword">&lt;</span>/li<span class="niji_keyword">&gt;</span>
&lt;?php <span class="niji_keyword">endforeach</span> ?<span class="niji_keyword">&gt;</span>
<span class="niji_keyword">&lt;</span>/ul<span class="niji_keyword">&gt;</span></pre>
</li>
</ol>
<p>Si vous avez utilisez la sandbox symfony 1.4 pour suivre ce tutoriel, vous ne devriez pas avoir de problème. Toutefois, il existe quelques subtilités dans l&#8217;utilisation de l&#8217;extension Taggable que j&#8217;ai rencontré lors de son utilisation dans un projet réel. Je les mets ci-dessous, si vous en avez d&#8217;autres n&#8217;hésitez pas à le signaler dans les commentaires.</p>
<ul>
<li>Pour utiliser la table TaggableTag vous devez obligatoirement avoir chargé une autre table utilisant l&#8217;extension. Dans mon exemple, si vous inversez les deux lignes de la méthode executeIndex, vous obtiendrez une belle exception &laquo;&nbsp;Couldn&#8217;t find class TaggableTag&nbsp;&raquo;.</li>
<li>Si vous essayez de supprimer un élément &laquo;&nbsp;Taggable&nbsp;&raquo;, une exception sera levée. En effet, les tags associés à l&#8217;objet doivent être supprimés avant l&#8217;objet lui-même. Vous pouvez soit utiliser l&#8217;évènement preDelete pour supprimer les tags avant l&#8217;objet soit appliquer <a href="http://www.doctrine-project.org/jira/secure/attachment/10250/TaggableConstraintError.patch">le patch que j&#8217;ai proposé dans l&#8217;issue tracker de Doctrine</a> pour ajouter un <em>onDelete CASCADE</em> sur la relation.</li>
<li>Les relations many-to-many entre votre modèle &laquo;&nbsp;Taggable&nbsp;&raquo; et les tags sont ajoutées à la volée, il faut donc &laquo;&nbsp;charger&nbsp;&raquo; le modèle avant l&#8217;utilisation d&#8217;une de ces relations. Ainsi, si vous voulez afficher un nuage de tags avec la méthode getPopularTags, il faudra charger chaque modèle &laquo;&nbsp;Taggable&nbsp;&raquo; où alors vous n&#8217;aurez que les tags populaires des modèles déjà chargés.</li>
</ul>
<p>En conclusion, l&#8217;extension Taggable est très intéressante mais il subsiste quelques défauts qui peuvent bloquer son utilisation dans un projet concret. Si j&#8217;ai réussi à corriger les problèmes 1 et 2, le 3e reste non résolu pour le moment. La solution serait d&#8217;ajouter les relations dans les fichiers php générés par Doctrine lors de la création des modèles. Pas sûr que ce soit possible dans l&#8217;état actuel&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogafab.com/utiliser-extension-taggable-doctrine-symfony/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Critique du livre &#171;&#160;Symfony 1.3 Web Application Development&#160;&#187;</title>
		<link>http://www.blogafab.com/critique-livre-symfony-1-3-web-application-development/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=critique-livre-symfony-1-3-web-application-development</link>
		<comments>http://www.blogafab.com/critique-livre-symfony-1-3-web-application-development/#comments</comments>
		<pubDate>Mon, 30 Nov 2009 10:15:14 +0000</pubDate>
		<dc:creator>Fabien</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://www.blogafab.com/?p=348</guid>
		<description><![CDATA[Il y a quelques semaines, l&#8217;éditeur PacktPublishing m&#8217;a proposé d&#8217;écrire une critique de son livre fraichement sorti intitulé &#171;&#160;Symfony 1.3 Web Application Development&#160;&#187; et écrit par Tim Bowler et Wojciech Bancer. Comme son nom l&#8217;indique, le livre est consacré au &#8230; <a href="http://www.blogafab.com/critique-livre-symfony-1-3-web-application-development/">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-medium wp-image-352" title="symfony 1.3 book" src="http://www.blogafab.com/wp-content/uploads/2009/11/symfony-1.3-book-241x300.jpg" alt="symfony 1.3 book" width="" height="214" />Il y a quelques semaines, l&#8217;éditeur <a href="http://www.packtpub.com/">PacktPublishing</a> m&#8217;a proposé d&#8217;écrire une critique de son livre fraichement sorti intitulé &laquo;&nbsp;Symfony 1.3 Web Application Development&nbsp;&raquo; et écrit par Tim Bowler et Wojciech Bancer. Comme son nom l&#8217;indique, le livre est consacré au framework PHP5 en vogue en ce moment, j&#8217;ai nommé symfony&#8230;</p>
<p>&laquo;&nbsp;Symfony 1.3 Web Application Development&nbsp;&raquo; compte un peu plus de 200 pages que je viens tout juste de terminer. Alors, convaincu ou déçu ? Voici mon avis&#8230;</p>
<p><span id="more-348"></span></p>
<h3>Symfony dans tous ses états</h3>
<p>Contraire à ce que je pensais avant la lecture du livre, le public visé n&#8217;est pas les développeurs utilisant déjà symfony et ayant envie d&#8217;en savoir plus sur la version 1.3 du framework. Non, le livre est plutôt destiné aux personnes qui ont envie de commencer à utiliser symfony et d&#8217;apprendre à l&#8217;utiliser.</p>
<p>Le livre est très complet et couvre les principales fonctionnalités proposées par le framework symfony : <acronym title="Modèle Vue Contrôleur">MVC</acronym>, <acronym title="Object Relational Mapping">ORM</acronym>, templates, admin generator, form framework, cache, ou encore internationalisation (i18n). Autant dire qu&#8217;à la fin de la lecture, le développeur dispose d&#8217;une bonne connaissance du framework et est fin prêt pour commencer un nouveau projet avec. Si il trouve symfony un peu <em>faible</em> en fonctionnalités (rappelons que le but de Symfony c&#8217;est de fournir ce qui est commun à 99% dans tous les projets web), il y a même un chapitre sur l&#8217;intégration de composants du Zend Framework ou de eZ Components. Un très bon point à mon avis.</p>
<h3>Vous avez dit symfony 1.3 ?</h3>
<p>Malgré cela, &laquo;&nbsp;Symfony 1.3 Web Application Development&nbsp;&raquo; souffre malheureusement de quelques défauts&#8230;</p>
<p>Tout d&#8217;abord, on trouve un certain nombre de fautes par ci par là, tant au niveau du texte qu&#8217;au niveau code. Si vous appliquez à la lettre le code présent dans le livre votre application ne fonctionnera pas. Rien de très grave, un développeur avec un minimum de connaissance en PHP n&#8217;aura aucun mal à les repérer et à les corriger&#8230;</p>
<p>Ensuite, bien que symfony 1.3 soit présent dans le titre, il s&#8217;agit plus d&#8217;un livre sur la version 1.2. En effet, à part des screenshots et quelques détails, je dois bien avouer que je n&#8217;ai pas vu grand chose de la nouvelle mouture du framework et c&#8217;est bien dommage. Le livre est sorti un peu trop vite, les grandes nouveautés de la version 1.3 n&#8217;étaient alors pas encore disponibles. Ainsi, par exemple, sur la partie &laquo;&nbsp;envoi de mails&nbsp;&raquo;, le livre est déjà obsolète. On pourrait également regretter l&#8217;utilisation Propel malgré que Doctrine soit l&#8217;<acronym title="Object Relational Mapping">ORM</acronym> par défaut de symfony 1.3.</p>
<h3>Conclusion</h3>
<p>Que penser du livre &laquo;&nbsp;Symfony 1.3 Web Application Development&nbsp;&raquo; ? Tout dépend de votre profil et de vos attentes. Si vous connaissez déjà symfony et que vous voulez connaître la version 1.3, passez votre chemin ce n&#8217;est pas le but du livre. Au contraire, si vous êtes développeur PHP et que vous avez envie d&#8217;apprendre à l&#8217;utiliser, allez-y ! Le livre est bien écrit et les choses sont bien expliquées. Une fois la lecture terminée, si vous voulez utiliser à fond Symfony 1.3, jetez un coup d&#8217;œil à la page <a href="http://www.symfony-project.org/tutorial/1_4/en/whats-new">What&#8217;s new in symfony 1.3/1.4</a> pour découvrir les nouveautés, cela terminera votre apprentissage.</p>
<p>En résumé, un bon livre qui permettra à tout ceux qui n&#8217;utilisent pas encore symfony d&#8217;appréhender l&#8217;outil sans difficulté.</p>
<p><a href="http://www.packtpub.com/symfony-1-3-web-application-development?utm_source=blogafab.com&amp;utm_medium=bookrev&amp;utm_content=blog&amp;utm_campaign=mdb_001299">Acheter &laquo;&nbsp;Symfony 1.3 Web Application Development&nbsp;&raquo; chez PacktPublishing</a><br />
<a href="http://www.amazon.fr/gp/product/1847194567?ie=UTF8&amp;tag=blogafab-21&amp;linkCode=as2&amp;camp=1642&amp;creative=19458&amp;creativeASIN=1847194567">Acheter &laquo;&nbsp;Symfony 1.3 Web Application Development&nbsp;&raquo; sur Amazon.fr</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogafab.com/critique-livre-symfony-1-3-web-application-development/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Traduire complètement l&#8217;admin generator de Symfony</title>
		<link>http://www.blogafab.com/traduire-completement-ladmin-generator-de-symfony/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=traduire-completement-ladmin-generator-de-symfony</link>
		<comments>http://www.blogafab.com/traduire-completement-ladmin-generator-de-symfony/#comments</comments>
		<pubDate>Wed, 30 Sep 2009 13:30:43 +0000</pubDate>
		<dc:creator>Fabien</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://www.blogafab.com/?p=331</guid>
		<description><![CDATA[Si vous avez déjà essayé de traduire l&#8217;admin generator de Symfony vous avez probablement été confronté au problème : certaines chaînes ne peuvent pas être traduites car elles n&#8217;utilisent pas le système d&#8217;internationalisation (i18n) du framework. Ces chaînes sont présentes &#8230; <a href="http://www.blogafab.com/traduire-completement-ladmin-generator-de-symfony/">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Si vous avez déjà essayé de traduire l&#8217;admin generator de Symfony vous avez probablement été confronté au problème : certaines chaînes ne peuvent pas être traduites car elles n&#8217;utilisent pas le système d&#8217;internationalisation (i18n) du framework. Ces chaînes sont présentes directement dans les widgets dédiés aux formulaires de filtrage. C&#8217;est le cas de <em>is empty</em>, <em>yes or no</em> ou encore de <em>from [...] to [...]</em>.</p>
<p>En faisant une recherche rapide sur Internet, vous trouverez quelques solutions mais elles nécessitent de modifier tous les formulaires du projet. Sur un petit projet, 2-3 formulaires, cela peut être acceptable mais avec une soixantaine de formulaires cela peut vite devenir embêtant.<br />
<span id="more-331"></span><br />
Je vous propose ici une solution/workaround que j&#8217;ai développé pour mes besoins afin de traduire ces fameuses chaînes. Elle fonctionne avec Symfony 1.2 et Doctrine 1.1 pour les formulaires actuels et futurs.</p>
<ol>
<li>Éditer le fichier <em>lib/filter/doctrine/BaseFormFilterDoctrine.class.php</em></li>
<li>
Utiliser maintenant cette classe :</p>
<pre class="niji_code niji_php" style="">
<span class="niji_keyword">abstract</span> <span class="niji_keyword">class</span> <span class="niji_method">BaseFormFilterDoctrine</span> <span class="niji_keyword">extends</span> <span class="niji_method"><em>sfFormFilterDoctrine</em></span>
{
	<span class="niji_keyword">protected</span> <span class="niji_variable">$booleanFieldChoices</span> <span class="niji_keyword">=</span> <span class="niji_function">array</span>(<span class="niji_string">''</span> <span class="niji_keyword">=</span><span class="niji_keyword">&gt;</span> <span class="niji_string">'yes or no'</span><span class="niji_default">,</span> <span class="niji_int">1</span> <span class="niji_keyword">=</span><span class="niji_keyword">&gt;</span> <span class="niji_string">'yes'</span><span class="niji_default">,</span> <span class="niji_int">0</span> <span class="niji_keyword">=</span><span class="niji_keyword">&gt;</span> <span class="niji_string">'no'</span>);

	<span class="niji_comment">/**
	 * @see sfForm
	 */</span>
	<span class="niji_keyword">public</span> <span class="niji_keyword">function</span> <span class="niji_method">__construct($<span class="niji_keyword">default</span>s <span class="niji_keyword">=</span> <span class="niji_function">array</span>()<span class="niji_default">,</span> <span class="niji_variable">$options</span> <span class="niji_keyword">=</span> <span class="niji_keyword">array</span></span>()<span class="niji_default">,</span> <span class="niji_variable">$CSRFSecret</span> <span class="niji_keyword">=</span> <span class="niji_int">null</span>)
	{
		<span class="niji_class">parent</span><span class="niji_keyword"><span class="niji_keyword">::</span></span>__construct($<span class="niji_keyword">default</span>s<span class="niji_default">,</span> <span class="niji_variable">$options</span><span class="niji_default">,</span> <span class="niji_variable">$CSRFSecret</span>);
		<span class="niji_variable">$this</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>fixI18N();
	}

	<span class="niji_comment">/**
	 * @see sfForm
	 */</span>
	<span class="niji_keyword">public</span> <span class="niji_keyword">function</span> <span class="niji_method">setup</span>()
	{
	}

	<span class="niji_keyword">protected</span> <span class="niji_keyword">function</span> <span class="niji_method">fixI18N</span>()
	{
		<span class="niji_keyword">foreach</span> (<span class="niji_variable">$this</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>widgetSchema<span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>getFields() <span class="niji_keyword">as</span> <span class="niji_variable">$field</span>)
		{
			<span class="niji_keyword">if</span> (<span class="niji_variable">$field</span> <span class="niji_keyword">instanceof</span> <span class="niji_function">sfWidgetFormFilterInput</span>)
			{
				<span class="niji_variable">$this</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>fixIsEmpty(<span class="niji_variable">$field</span>);
			}
			<span class="niji_keyword">elseif</span> (<span class="niji_variable">$field</span> instanceof sfWidgetFormChoice
			<span class="niji_keyword">and</span> <span class="niji_variable">$field</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>getOption(<span class="niji_string">'choices'</span>) <span class="niji_keyword">=</span><span class="niji_keyword">=</span> <span class="niji_variable">$this</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>booleanFieldChoices)
			{
				<span class="niji_variable">$field</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>setOption(<span class="niji_string">'choices'</span><span class="niji_default">,</span> <span class="niji_function">array_map</span>(
					<span class="niji_function">array</span>(<span class="niji_variable">$this</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>widgetSchema<span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>getFormFormatter()<span class="niji_default">,</span> <span class="niji_string">'translate'</span>)<span class="niji_default">,</span>
					<span class="niji_variable">$field</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>getOption(<span class="niji_string">'choices'</span>)
				));
			}
			<span class="niji_keyword">elseif</span> (<span class="niji_variable">$field</span> <span class="niji_keyword">instanceof</span> <span class="niji_function">sfWidgetFormFilterDate</span>)
			{
				<span class="niji_variable">$this</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>fixIsEmpty(<span class="niji_variable">$field</span>);

				<span class="niji_variable">$field</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>setOption(
					<span class="niji_string">'template'</span><span class="niji_default">,</span>
					<span class="niji_variable">$this</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>widgetSchema<span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>getFormFormatter()<span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>translate(
						<span class="niji_variable">$field</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>getOption(<span class="niji_string">'template'</span>)
					)
				);
			}
		}
	}

	<span class="niji_keyword">protected</span> <span class="niji_keyword">function</span> <span class="niji_method">fixIsEmpty</span>(<span class="niji_function">sfWidgetForm</span> <span class="niji_variable">$field</span>)
	{
		<span class="niji_variable">$field</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>setOption(
			<span class="niji_string">'empty_label'</span><span class="niji_default">,</span>
			<span class="niji_variable">$this</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>widgetSchema<span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>getFormFormatter()<span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>translate(
				<span class="niji_variable">$field</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>getOption(<span class="niji_string">'empty_label'</span>)
			)
		);
	}
}
</pre>
</li>
<li>Si vous aviez déjà personnalisé cette classe, n&#8217;oubliez de ré-appliquer vos modifications.</li>
<li>Modifier le fichier <em>apps/backend/i18n/fr/messages.xml</em> (où <em>backend</em> est l&#8217;applicaton utilisant l&#8217;admin generator et <em>messages</em> le catalogue i18n) et ajouter :
<pre class="niji_code niji_xml" style="">
      &lt;trans -unit&gt;<span class="niji_default">
        </span>&lt;source&gt;<span class="niji_default">is empty</span>&lt;/source&gt;<span class="niji_default">
        </span>&lt;target&gt;<span class="niji_default">est vide</span>&lt;/target&gt;<span class="niji_default">
      </span>&lt;/trans&gt;<span class="niji_default">
      </span>&lt;trans -unit&gt;<span class="niji_default">
        </span>&lt;source&gt;<span class="niji_default">yes or no</span>&lt;/source&gt;<span class="niji_default">
        </span>&lt;target&gt;<span class="niji_default">oui ou non</span>&lt;/target&gt;<span class="niji_default">
      </span>&lt;/trans&gt;<span class="niji_default">
      </span>&lt;trans -unit&gt;<span class="niji_default">
        </span>&lt;source&gt;<span class="niji_default">yes</span>&lt;/source&gt;<span class="niji_default">
        </span>&lt;target&gt;<span class="niji_default">oui</span>&lt;/target&gt;<span class="niji_default">
      </span>&lt;/trans&gt;<span class="niji_default">
      </span>&lt;trans -unit&gt;<span class="niji_default">
        </span>&lt;source&gt;<span class="niji_default">no</span>&lt;/source&gt;<span class="niji_default">
        </span>&lt;target&gt;<span class="niji_default">non</span>&lt;/target&gt;<span class="niji_default">
      </span>&lt;/trans&gt;<span class="niji_default">
      </span>&lt;trans -unit&gt;<span class="niji_default">
        </span>&lt;source&gt;<span class="niji_default"></span>&lt; ![CDATA[from %from_date%&lt;br /&gt;<span class="niji_default">to %to_date%]]&gt;</span>&lt;/source&gt;<span class="niji_default">
        </span>&lt;target&gt;<span class="niji_default"></span>&lt; ![CDATA[du %from_date%&lt;br /&gt;<span class="niji_default">au %to_date%]]&gt;</span>&lt;/target&gt;<span class="niji_default">
      </span>&lt;/trans&gt;
</pre>
<p> (attention aux espaces ajoutés par wordpress)
</li>
</ol>
<p>A noter cette solution corrige les formulaires de filtrage (<em>filters</em>), il existe également quelques chaînes <em>hardcoded</em> dans les widgets pour les formulaires &laquo;&nbsp;classiques&nbsp;&raquo;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogafab.com/traduire-completement-ladmin-generator-de-symfony/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Symfony : Gérer un formulaire dans un composant</title>
		<link>http://www.blogafab.com/symfony-gerer-un-formulaire-dans-un-composant/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=symfony-gerer-un-formulaire-dans-un-composant</link>
		<comments>http://www.blogafab.com/symfony-gerer-un-formulaire-dans-un-composant/#comments</comments>
		<pubDate>Mon, 22 Jun 2009 09:20:58 +0000</pubDate>
		<dc:creator>Fabien</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://www.blogafab.com/?p=275</guid>
		<description><![CDATA[Dans un projet Symfony, comment gérer la validation d&#8217;un formulaire lorsqu&#8217;il est dans un composant ? C&#8217;est la question que l&#8217;on m&#8217;a posé cette semaine la semaine dernière (le temps passe vite&#8230;). Tout d&#8217;abord, qu&#8217;est-ce qu&#8217;un composant dans Symfony ? &#8230; <a href="http://www.blogafab.com/symfony-gerer-un-formulaire-dans-un-composant/">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><em>Dans un projet Symfony, comment gérer la validation d&#8217;un formulaire lorsqu&#8217;il est dans un composant ?</em> C&#8217;est la question que l&#8217;on m&#8217;a posé <span style="text-decoration: line-through;">cette semaine</span> la semaine dernière (le temps passe vite&#8230;).</p>
<p>Tout d&#8217;abord, qu&#8217;est-ce qu&#8217;un composant dans Symfony ? Il s&#8217;agit en quelque sorte d&#8217;une action qui est réutilisable entre les différents modules de l&#8217;application. A la différence des &laquo;&nbsp;partials&nbsp;&raquo;, qui sont &laquo;&nbsp;que&nbsp;&raquo; des templates, les composants contiennent de la logique : le plus souvent, récupérer un ou plusieurs modèles.</p>
<p>Pour revenir à la question, le problème n&#8217;est pas de gérer la validation à proprement parler, Symfony va s&#8217;en occuper grâce au <em>forms framework</em> mais plutôt de savoir où envoyer le visiteur une fois le formulaire soumis et comment, à la fin, le rediriger sur la page initiale, celle où il a rempli le formulaire.</p>
<p><span id="more-275"></span></p>
<p>Une solution possible est de créer une action spécifique pour valider le formulaire et d&#8217;ajouter un champ caché &laquo;&nbsp;referer&nbsp;&raquo; contenant l&#8217;url de la page initiale. Dans le fonctionnement, c&#8217;est relativement simple, le formulaire du composant pointe vers l&#8217;action et lorsque les données saisies sont valides, l&#8217;utilisateur est redirigé vers le valeur du champ &laquo;&nbsp;referer&nbsp;&raquo;.</p>
<p>Pour les intéressés, vous trouverez ci-dessous le contenu des différents fichiers pour l&#8217;utilisation d&#8217;un formulaire en composant. C&#8217;est prévu pour fonctionner avec Symfony 1.2.</p>
<ol>
<li>Le formulaire (<em>lib/form/TestForm.class.php</em>)
<pre class="niji_code niji_php" style=""><span class="niji_keyword">&lt;</span> ?php
<span class="niji_keyword">class</span> <span class="niji_method">TestForm</span> <span class="niji_keyword">extends</span> <span class="niji_method"><em>sfForm</em></span>
{
	<span class="niji_keyword">public</span> <span class="niji_keyword">function</span> <span class="niji_method">configure</span>()
	{
		<span class="niji_variable">$this</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>setWidgets(<span class="niji_function">array</span>(
			<span class="niji_string">'name'</span>    <span class="niji_keyword">=</span><span class="niji_keyword">&gt;</span> <span class="niji_keyword">new</span> <span class="niji_function">sfWidgetFormInput</span>()<span class="niji_default">,</span>
			<span class="niji_string">'referer'</span> <span class="niji_keyword">=</span><span class="niji_keyword">&gt;</span> <span class="niji_keyword">new</span> <span class="niji_function">sfWidgetFormInputHidden</span>()<span class="niji_default">,</span>
		));

		<span class="niji_variable">$this</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>setValidators(<span class="niji_function">array</span>(
			<span class="niji_string">'name'</span>    <span class="niji_keyword">=</span><span class="niji_keyword">&gt;</span> <span class="niji_keyword">new</span> <span class="niji_function">sfValidatorString</span>()<span class="niji_default">,</span>
			<span class="niji_string">'referer'</span> <span class="niji_keyword">=</span><span class="niji_keyword">&gt;</span> <span class="niji_keyword">new</span> <span class="niji_function">sfValidatorString</span>(<span class="niji_function">array</span>(<span class="niji_string">'required'</span> <span class="niji_keyword">=</span><span class="niji_keyword">&gt;</span> <span class="niji_int">false</span>))<span class="niji_default">,</span>
		));

		<span class="niji_variable">$this</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>widgetSchema<span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>setNameFormat(<span class="niji_string">'test-form[%s]'</span>);
	}
}</pre>
</li>
<li>Le composant (<em>apps/frontend/modules/mymodule/actions/components.class.php</em>)
<pre class="niji_code niji_php" style=""><span class="niji_keyword">&lt;</span> ?php
<span class="niji_keyword">class</span> <span class="niji_method">mymoduleComponents</span> <span class="niji_keyword">extends</span> <span class="niji_method"><em>sfComponents</em></span>
{
	<span class="niji_keyword">public</span> <span class="niji_keyword">function</span> <span class="niji_method">executeTestForm</span>(<span class="niji_function">sfWebRequest</span> <span class="niji_variable">$request</span>)
	{
		<span class="niji_variable">$this</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>form <span class="niji_keyword">=</span> <span class="niji_keyword">new</span> <span class="niji_function">TestForm</span>(<span class="niji_function">array</span>(
			<span class="niji_string">'referer'</span> <span class="niji_keyword">=</span><span class="niji_keyword">&gt;</span> <span class="niji_variable">$request</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>getUri()
		));
	}
}</pre>
</li>
<li>Le template du composant (<em>apps/frontend/modules/mymodule/templates/_TestForm.php</em>)
<pre class="niji_code niji_html" style="">
&lt;h2&gt;<span class="niji_default">My Form</span>&lt;/h2&gt;<span class="niji_default">
</span>&lt;form action=<span class="niji_string">&quot;<span class="niji_default">&lt;?php <span class="niji_function">echo</span> url_for(<span class="niji_string">'test-form'</span>) ?&gt;</span>&quot;</span> method=<span class="niji_string">&quot;post&quot;</span>&gt;<span class="niji_default">
  </span>&lt;table&gt;<span class="niji_default">
    </span>&lt; ?php echo $form ?&gt;<span class="niji_default">
  </span>&lt;/table&gt;<span class="niji_default">
  </span>&lt;input type=<span class="niji_string">&quot;submit&quot;</span> value=<span class="niji_string">&quot;Send&quot;</span> /&gt;<span class="niji_default">
</span>&lt;/form&gt;</pre>
</li>
<li>L&#8217;action (<em>apps/frontend/modules/mymodule/actions/actions.class.php</em>)
<pre class="niji_code niji_php" style=""><span class="niji_keyword">&lt;</span> ?php
<span class="niji_keyword">class</span> <span class="niji_method">mymoduleActions</span> <span class="niji_keyword">extends</span> <span class="niji_method"><em>sfActions</em></span>
{
	<span class="niji_keyword">public</span> <span class="niji_keyword">function</span> <span class="niji_method">executeTestForm</span>(<span class="niji_function">sfWebRequest</span> <span class="niji_variable">$request</span>)
	{
		<span class="niji_variable">$this</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>form <span class="niji_keyword">=</span> <span class="niji_keyword">new</span> <span class="niji_function">TestForm</span>(<span class="niji_function">array</span>(
			<span class="niji_string">'referer'</span> <span class="niji_keyword">=</span><span class="niji_keyword">&gt;</span> <span class="niji_variable">$request</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>getUri()
		));

		<span class="niji_keyword">if</span> (<span class="niji_variable">$request</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>isMethod(<span class="niji_string">'post'</span>))
		{
			<span class="niji_variable">$this</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>form<span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>bind(<span class="niji_variable">$request</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>getParameter(<span class="niji_variable">$this</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>form<span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>getName()));

			<span class="niji_keyword">if</span> (<span class="niji_variable">$this</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>form<span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>isValid())
			{
				<span class="niji_variable">$this</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>redirect(
					<span class="niji_variable">$this</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>form<span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>getValue(<span class="niji_string">'referer'</span>) ? <span class="niji_variable">$this</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>form<span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>getValue(<span class="niji_string">'referer'</span>) : <span class="niji_string">'homepage'</span>
				);
			}
		}
	}
}</pre>
</li>
<li>Le template de l&#8217;action (<em>apps/frontend/modules/mymodule/templates/TestFormSuccess.php</em>)
<pre class="niji_code niji_php" style=""><span class="niji_keyword">&lt;</span> ?php include_partial(<span class="niji_string">'TestForm'</span><span class="niji_default">,</span> <span class="niji_function">array</span>(<span class="niji_string">'form'</span> <span class="niji_keyword">=</span><span class="niji_keyword">&gt;</span> <span class="niji_variable">$form</span>)) ?<span class="niji_keyword">&gt;</span></pre>
</li>
<li>La règle de routage (<em>apps/frontend/config/routing.yml</em>)
<pre class="niji_code niji_xml" style="">test-form:
  url:    /test-form
  param:  { module: mymodule, action: TestForm }</pre>
</li>
</ol>
<p>Une fois tous les fichiers créés, il ne reste plus qu&#8217;à inclure le composant dans un template, par exemple <em>apps/frontend/layout.php</em>, en ajoutant ceci :</p>
<pre class="niji_code niji_php" style=""><span class="niji_keyword">&lt;</span> ?php include_component(<span class="niji_string">'mymodule'</span><span class="niji_default">,</span> <span class="niji_string">'TestForm'</span>) ?<span class="niji_keyword">&gt;</span></pre>
<p>Ici, le formulaire ne sert absolument à rien, la valeur saisie n&#8217;est pas utilisée. Il s&#8217;agit juste d&#8217;un exemple pour montrer le principe. <img src='http://www.blogafab.com/wp-content/plugins/smilies-themer/Silk/emoticon_wink.png' alt=';-)' class='wp-smiley' /> </p>
<p>Note : Attention WordPress à ajouté un espace entre <em>&lt;</em> et <em>?php</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogafab.com/symfony-gerer-un-formulaire-dans-un-composant/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Symfony : Utiliser un fichier de config personnalisé</title>
		<link>http://www.blogafab.com/symfony-utiliser-un-fichier-de-config-personnalise/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=symfony-utiliser-un-fichier-de-config-personnalise</link>
		<comments>http://www.blogafab.com/symfony-utiliser-un-fichier-de-config-personnalise/#comments</comments>
		<pubDate>Mon, 11 May 2009 19:13:12 +0000</pubDate>
		<dc:creator>Fabien</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://www.blogafab.com/?p=252</guid>
		<description><![CDATA[Lorsque l&#8217;on développe un projet, on a (presque?) toujours un certain nombre de paramètres propres à ce dernier. Cela peut-être le nom du site internet, la clé d&#8217;accès à un WebService ou encore la taille des miniatures à générer. De &#8230; <a href="http://www.blogafab.com/symfony-utiliser-un-fichier-de-config-personnalise/">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Lorsque l&#8217;on développe un projet, on a (presque?) toujours un certain nombre de paramètres propres à ce dernier. Cela peut-être le nom du site internet, la clé d&#8217;accès à un WebService ou encore la taille des miniatures à générer. De façon générale, il s&#8217;agit de tous ces paramètres communs à la fois au <em>frontend</em> et au <em>backend</em> du projet.</p>
<p>Tout bon développeur qui se respecte, je ne laisserai pas ce genre de paramètre perdu dans la logique métier. Tout d&#8217;abord parce que ça n&#8217;a absolument rien à faire là et ensuite parce qu&#8217;il ne serait pas facile de modifier le paramètre plus tard. Une bonne pratique est donc de créer un fichier à part pour stocker ces paramètres&#8230;</p>
<p><span id="more-252"></span></p>
<p>Dans symfony, il y a un fichier de paramètres pour les applications (apps/<em>monapp</em>/config/app.yml) et un pour les modules (apps/<em>monapp</em>/modules/<em>monmodule</em>/config/module.yml) mais pour tout le projet il n&#8217;y aucun fichier pré-défini par défaut. Heureusement, symfony est un framework très flexible et l&#8217;on peut ainsi ajouter un nouveau fichier de config en quelques lignes seulement&#8230;</p>
<p>Pour les intéressés, voici la procédure :</p>
<ol>
<li>Créez un fichier nommé config_handlers.yml dans le dossier config</li>
<li>Copiez dans le fichier précédemment créé le code ci-dessous :
<pre class="niji_code niji_xml" style="">config/project.yml:
  class:		sfDefineEnvironmentConfigHandler
  param:
    prefix: project_</pre>
</li>
<li>Créez le fichier config/project.yml et ajoutez quelques paramètres. Par exemple :
<pre class="niji_code niji_xml" style="">all:
  website:
    name: Mon site internet</pre>
</li>
<li>Il faut maintenant charger les paramètres pour chaque application du projet.
<ul>
<li>Modifiez le fichier config/ProjectConfiguration.class.php</li>
<li>Ajoutez une fonction loadProjectConfig :
<pre class="niji_code niji_php" style="">	<span class="niji_keyword">protected</span> <span class="niji_keyword">function</span> <span class="niji_method">loadProjectConfig</span>()
	{
		<span class="niji_keyword">static</span> <span class="niji_variable">$load</span> <span class="niji_keyword">=</span> <span class="niji_int">false</span>;

		<span class="niji_keyword">if</span> (<span class="niji_keyword">!</span><span class="niji_variable">$load</span> <span class="niji_keyword">&amp;</span><span class="niji_keyword">&amp;</span> <span class="niji_variable">$this</span> <span class="niji_keyword">instanceof</span> <span class="niji_function">sfApplicationConfiguration</span>)
		{
			<span class="niji_keyword">require</span> <span class="niji_variable">$this</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>getConfigCache()<span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>checkConfig(<span class="niji_string">'config/project.yml'</span>);
			<span class="niji_variable">$load</span> <span class="niji_keyword">=</span> <span class="niji_int">true</span>;
		}
	}</pre>
</li>
<li>Chargez le fichier de config en ajoutant le code ci-dessous dans la méthode setup de la classe :
<pre class="niji_code niji_php" style="">			<span class="niji_variable">$this</span><span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>loadProjectConfig();</pre>
</li>
</ul>
</li>
<li>C&#8217;est fini !</li>
</ol>
<p>Vous pouvez maintenant, dans les applications de votre projet, accéder aux paramètres définis dans project.yml en utilisant <code lang="php">sfConfig::get('project_...')</code>.</p>
<p>Attention, si comme moi vous écrivez des tests automatisés pour vos projets, pour les tests unitaires, il faudra ajouter un ligne afin de charger le fichier de config personnalisé :</p>
<pre class="niji_code niji_php" style=""><span class="niji_variable">$configuration</span> <span class="niji_keyword">=</span> <span class="niji_class">ProjectConfiguration</span><span class="niji_keyword"><span class="niji_keyword">::</span></span>getApplicationConfiguration(<span class="niji_string">'frontend'</span><span class="niji_default">,</span> <span class="niji_string">'test'</span><span class="niji_default">,</span> <span class="niji_int">true</span>);</pre>
<p>Je vous conseille d&#8217;ailleurs d&#8217;écrire un bootstrap avec cette ligne plutôt que de la copier/coller dans chaque fichier de test <img src='http://www.blogafab.com/wp-content/plugins/smilies-themer/Silk/emoticon_wink.png' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogafab.com/symfony-utiliser-un-fichier-de-config-personnalise/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Ecrire des tests unitaires en C++ avec Xcode</title>
		<link>http://www.blogafab.com/ecrire-des-tests-unitaires-en-c-avec-xcode/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ecrire-des-tests-unitaires-en-c-avec-xcode</link>
		<comments>http://www.blogafab.com/ecrire-des-tests-unitaires-en-c-avec-xcode/#comments</comments>
		<pubDate>Tue, 14 Apr 2009 19:40:49 +0000</pubDate>
		<dc:creator>Fabien</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Test Unitaire]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://www.blogafab.com/?p=241</guid>
		<description><![CDATA[Il y a quelques jours, à l&#8217;Université, dans le cadre du TP de &#171;&#160;Flots de Multiflots dans les Réseaux&#160;&#187;, j&#8217;ai dû stocker et manipuler des graphes en implémentant les algorithmes de Dikjstra, de Bellman-Ford, de Johnson, de Floyd-Warshall afin d&#8217;obtenir &#8230; <a href="http://www.blogafab.com/ecrire-des-tests-unitaires-en-c-avec-xcode/">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Il y a quelques jours, à l&#8217;Université, dans le cadre du TP de &laquo;&nbsp;Flots de Multiflots dans les Réseaux&nbsp;&raquo;, j&#8217;ai dû stocker et manipuler des graphes en implémentant les algorithmes de Dikjstra, de Bellman-Ford, de Johnson, de Floyd-Warshall afin d&#8217;obtenir un plus court chemin.</p>
<p>Les graphes c&#8217;est sympa mais je m&#8217;en méfie toujours, peut-être parce qu&#8217;en licence 3 j&#8217;ai dû perdre quelques cheveux lorsque j&#8217;ai coder 2-3 algorithmes, relativement simples par rapport à ceux cités avant, sur les graphes. Cette année pour ne pas me faire avoir, j&#8217;ai décidé d&#8217;utiliser des tests unitaires afin vérifier mon code. C&#8217;était en plus une bonne occasion pour découvrir un framework de tests en C++</p>
<p><span id="more-241"></span></p>
<p>Pour développer en C++ j&#8217;utilise le logiciel de développement proposé par Apple à savoir Xcode. Il est relativement bien fait, rapide à lancer, propose l&#8217;auto-complétion et surtout, on peut débugger facilement son programme. En plus de ça, Xcode intègre un framework de tests nommé CPlusTest. Pour ceux que cela intéressent, voici comment écrire des tests unitaires en C++ avec Xcode&#8230;</p>
<ol>
<li>Ouvrez ou créez un projet.</li>
<li>Créez une cible pour les tests unitaires
<ol>
<li>Dans le panneau latéral gauche, faites un clic droit sur &laquo;&nbsp;Targets&nbsp;&raquo; et cliquez sur &laquo;&nbsp;Add&#8230;&nbsp;&raquo; &gt; &laquo;&nbsp;New Target&#8230;&nbsp;&raquo;.</li>
<li>Dans la fenêtre qui apparaît, choisissez &laquo;&nbsp;Carbon&nbsp;&raquo; puis &laquo;&nbsp;Unit Test Bundle&nbsp;&raquo; et cliquez sur &laquo;&nbsp;Next&#8230;&nbsp;&raquo;.</li>
<li>Entrez un nom pour votre cible, &laquo;&nbsp;UnitTest&nbsp;&raquo; par exemple, et appuyez sur &laquo;&nbsp;Finish&nbsp;&raquo;.</li>
</ol>
</li>
<li>Créez une classe à tester
<ol>
<li>Il nous faut maintenant une classe à tester. Pour cela, clic droit sur le dossier &laquo;&nbsp;Source&nbsp;&raquo;, puis &laquo;&nbsp;Add&#8230;&nbsp;&raquo; &gt; &laquo;&nbsp;New File&#8230;&nbsp;&raquo;.</li>
<li>Choisissez &laquo;&nbsp;C++ File&nbsp;&raquo; dans le groupe &laquo;&nbsp;Carbon&nbsp;&raquo; puis appuyez sur &laquo;&nbsp;Next&#8230;&nbsp;&raquo;.</li>
<li>Entrez le nom de votre classe, exemple MyFirstClass. Dans la partie &laquo;&nbsp;Targets&nbsp;&raquo;, vérifiez que &laquo;&nbsp;UnitTest&nbsp;&raquo; est bien coché puis cliquez sur &laquo;&nbsp;Finish&nbsp;&raquo;.</li>
<li>Codez une classe MyFirstClass, avec une méthode HelloWorld qui renvoie une string (std::string)<br />
Le .h :</p>
<pre class="niji_code niji_cpp" style=""><span class="niji_comment">#ifndef FIRST_H
</span><span class="niji_comment">#define FIRST_H
</span>
<span class="niji_comment">#include
</span>
<span class="niji_keyword">class</span> MyFirstClass
{
    <span class="niji_keyword">public</span>:
    MyFirstClass();
    std<span class="niji_keyword">::</span>string HelloWorld();
};

<span class="niji_comment">#endif
</span></pre>
<p>Le .cpp :</p>
<pre class="niji_code niji_cpp" style=""><span class="niji_comment">#include &quot;MyFirstClass.h&quot;
</span>
MyFirstClass<span class="niji_keyword">::</span>MyFirstClass()
{
}

std<span class="niji_keyword">::</span>string MyFirstClass<span class="niji_keyword">::</span>HelloWorld()
{
    std<span class="niji_keyword">::</span>string hello <span class="niji_keyword">=</span> <span class="niji_string">&quot;Hello World&quot;</span>;
    <span class="niji_keyword">return</span> hello;
}
</pre>
</li>
</ol>
</li>
<li>Créez les tests unitaires
<ol>
<li>Il faut maintenant créer un fichier de tests. Pour cela, clic droit sur le nom du projet dans le panneau gauche, &laquo;&nbsp;Add&#8230;&nbsp;&raquo; &gt; &laquo;&nbsp;New File&#8230;&nbsp;&raquo;.</li>
<li>Cliquez sur &laquo;&nbsp;Carbon&nbsp;&raquo; puis sur &laquo;&nbsp;C++ Test Case&nbsp;&raquo; et appuyez sur &laquo;&nbsp;Next&nbsp;&raquo;.</li>
<li>Entrez un nom pour votre fichier de test, &laquo;&nbsp;MyFirstClassTest&nbsp;&raquo; par exemple. N&#8217;oubliez pas de vérifier que dans la partie &laquo;&nbsp;Targets&nbsp;&raquo;, la cible &laquo;&nbsp;UnitTest&nbsp;&raquo; est bien coché puis cliquez sur &laquo;&nbsp;Finish&nbsp;&raquo;.</li>
<li>Créez votre première méthode de tests dans MyFirstClassTest.cpp :
<pre class="niji_code niji_cpp" style=""><span class="niji_keyword">void</span> MyFirstClassTest<span class="niji_keyword">::</span>test_HelloWorld()
{
    MyFirstClass <span class="niji_keyword">*</span>instance <span class="niji_keyword">=</span> <span class="niji_keyword">new</span> MyFirstClass();
    CPTAssert(instance<span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>HelloWorld() <span class="niji_keyword">=</span><span class="niji_keyword">=</span> <span class="niji_string">&quot;Hello World&quot;</span>);
    CPTAssert(instance<span class="niji_keyword">-</span><span class="niji_keyword">&gt;</span>HelloWorld() <span class="niji_keyword">=</span><span class="niji_keyword">=</span> <span class="niji_string">&quot;Hello&quot;</span>);
}</pre>
<p>(N&#8217;oubliez pas d&#8217;ajouter l&#8217;entête de la méthode dans le .h)</li>
<li>Enregistrez le test. Pour cela dans le fichier MyFirstClassTest.h, ajoutez à la fin :
<pre class="niji_code niji_cpp" style="">MyFirstClassTest test1(<span class="niji_int">TEST_INVOCATION</span>(MyFirstClassTest, test_HelloWorld));</pre>
</li>
</ol>
</li>
<li>Lancez les tests unitaires
<ol>
<li>Dans le menu, cliquez sur &laquo;&nbsp;Project&nbsp;&raquo;, allez à &laquo;&nbsp;Set Active Target&nbsp;&raquo; et choisissez &laquo;&nbsp;UnitTest&nbsp;&raquo;.</li>
<li>Toujours dans le menu, cliquez sur &laquo;&nbsp;Build&nbsp;&raquo; puis &laquo;&nbsp;Build and Go (Run)&nbsp;&raquo;.</li>
<li>Erreur devrez vous être rapportée, c&#8217;est le 2e test qui échoue. Si vous supprimez ce test et que vous refaite les étapes 5.1 et 5.2 tout devrait passer sans problème.</li>
</ol>
</li>
</ol>
<p>Voilà, vous êtes fin prêt pour écrire des tests unitaires en C++ avec Xcode. A noter que c&#8217;est la version 3.1 d&#8217;Xcode qui a été utilisé pour réaliser ce tutoriel. Il peut y avoir quelques changements selon la version de l&#8217;IDE que vous utilisez.</p>
<p>Pour plus d&#8217;informations sur les tests unitaires avec Xcode : http://developer.apple.com/documentation/developertools/Conceptual/UnitTesting/UnitTesting.html</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogafab.com/ecrire-des-tests-unitaires-en-c-avec-xcode/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Installer Apache, MySQL et PHP sur Mac OS 10.5 avec MacPorts</title>
		<link>http://www.blogafab.com/installer-apache-mysql-php-sur-mac-os-105-avec-macports/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=installer-apache-mysql-php-sur-mac-os-105-avec-macports</link>
		<comments>http://www.blogafab.com/installer-apache-mysql-php-sur-mac-os-105-avec-macports/#comments</comments>
		<pubDate>Fri, 06 Mar 2009 10:02:16 +0000</pubDate>
		<dc:creator>Fabien</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[Leopard]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[MacPorts]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://www.blogafab.com/?p=216</guid>
		<description><![CDATA[Suite la récente mésaventure que j&#8217;ai eu avec mon MacBook, j&#8217;ai dû ré-installer un environnement AMP sur mon ordinateur. L&#8217;occasion pour moi d&#8217;écrire ce billet et de présenter un outil génial pour Mac&#8230; J&#8217;en ai déjà parlé, la version de &#8230; <a href="http://www.blogafab.com/installer-apache-mysql-php-sur-mac-os-105-avec-macports/">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Suite la récente mésaventure que j&#8217;ai eu avec mon MacBook, j&#8217;ai dû ré-installer un environnement AMP sur mon ordinateur. L&#8217;occasion pour moi d&#8217;écrire ce billet et de présenter un outil génial pour Mac&#8230;</p>
<p>J&#8217;en ai déjà parlé, la version de PHP fournie avec Mac OS X Leopard est assez&#8230; épurée : pas de GD ou de PEAR par exemple et la compilation d&#8217;extensions ne marchent pas (cf. mon billet sur Runkit). Pour une utilisation (très?) basique de PHP cela suffira mais si vous voulez, par exemple, manipuler des images il faudra utiliser une autre solution&#8230;</p>
<p><span id="more-216"></span></p>
<p>Parmi les autres solutions possibles, j&#8217;ai choisi d&#8217;utiliser MacPorts et de compiler &laquo;&nbsp;moi-même&nbsp;&raquo; PHP. Certains auraient peut-être choisi <a href="http://www.mamp.info/en/index.html">MAMP</a> qui est une solution plus simple et plus &laquo;&nbsp;rapide&nbsp;&raquo; mais peut-on compiler des extensions avec ? A priori oui mais je n&#8217;en suis pas sûr. L&#8217;objectif est aussi de pouvoir installer d&#8217;autres packages que le trio Apache-MySQL-PHP et de mettre à jour ces packages très simplement (une ligne de commande).</p>
<p>Pour ceux que cela intéresse, voici la procédure pour installer et configurer Apache-MySQL-PHP avec MacPorts sur Leopard. A noter que je suppose que vous avez déjà installé les “Developper Tools” d’Apple.</p>
<h4>Installation de MacPorts</h4>
<ol>
<li>Téléchargez MacPorts sur le site officiel : http://www.macports.org/</li>
<li>Ouvrez l&#8217;image disque (.dmg)</li>
<li>Lancez le .pkg et suivez les instructions.</li>
<li>Une fois l&#8217;installation terminée, allez dans le terminal et lancez la commande :
<pre class="niji_code niji_shell" style="">sudo port selfupdate</pre>
</li>
</ol>
<h4>Installation d&#8217;Apache 2.2</h4>
<ol>
<li>Installez Apache 2.2 en exécutant la commande qui suit dans le terminal :
<pre class="niji_code niji_shell" style="">sudo port install apache2</pre>
</li>
<li>Une fois l&#8217;installation terminée, lancez Apache :
<pre class="niji_code niji_shell" style="">sudo /opt/local/apache2/bin/apachectl start</pre>
</li>
<li>Si vous allez à l&#8217;adresse http://localhost vous devriez voir &laquo;&nbsp;It works!&nbsp;&raquo; à l&#8217;écran.</li>
<li>Si vous souhaitez qu&#8217;Apache soit lancé au démarrage de votre ordinateur, lancez la commande ci-dessous :
<pre class="niji_code niji_shell" style="">sudo launchctl load -w /Library/LaunchDaemons/org.macports.apache2.plist</pre>
</li>
</ol>
<h4>Configuration d&#8217;Apache 2</h4>
<p>Maintenant qu&#8217;Apache 2 est installé, nous allons le configurer pour qu&#8217;il fonctionne comme la version d&#8217;Apache fournie avec Mac OS X Leopard.</p>
<ol>
<li>Ouvrez le fichier /opt/local/apache2/conf/httpd.conf avec votre éditeur préféré.</li>
<li>Recherchez la ligne
<pre class="niji_code niji_shell" style="">#Include conf/extra/httpd-userdir.conf</pre>
<p>et enlevez le caractère <code>#</code> au début.</li>
<li>Editez le fichier /opt/local/apache2/conf/extra/httpd-userdir.conf et ajoutez à la fin les lignes ci-dessous :
<pre class="niji_code niji_shell" style=""><span class="niji_comment">#
</span><span class="niji_comment"># Include user configurations
</span><span class="niji_comment">#
</span>Include /etc/apache2/users/*.conf</pre>
</li>
<li>Si vous souhaitez accéder au manuel d&#8217;Apache à l&#8217;adresse http://localhost/manual/ :
<ol>
<li>Editez le fichier /opt/local/apache2/conf/httpd.conf</li>
<li>Recherchez la ligne ci-dessous et enlevez le <code>#</code> au début.
<pre class="niji_code niji_shell" style="">#Include conf/extra/httpd-manual.conf</pre>
</li>
</ol>
</li>
<li>Si vous souhaitez afficher la liste des éléments d&#8217;un dossier lorsqu&#8217;il n&#8217;y a pas de fichier index dedans :
<ol>
<li>Editez le fichier /opt/local/apache2/conf/httpd.conf</li>
<li>Recherchez la ligne la ligne ci-dessous et enlevez le <code>#</code> au début.
<pre class="niji_code niji_shell" style="">#Include conf/extra/httpd-autoindex.conf</pre>
</li>
</ol>
</li>
<li>Relancez Apache :
<pre class="niji_code niji_shell" style="">/opt/local/apache2/bin/apachectl restart</pre>
</li>
</ol>
<h4>Installation et configuration de Mysql 5</h4>
<ol>
<li>Dans le terminal, lancez la commande suivante :
<pre class="niji_code niji_shell" style="">sudo port install mysql5 +server</pre>
</li>
<li>Une fois l&#8217;installation terminée, exécutez la commande :
<pre class="niji_code niji_shell" style="">sudo -u mysql mysql_install_db5</pre>
</li>
<li>Démarrez le serveur MySQL :
<pre class="niji_code niji_shell" style="">sudo /opt/local/bin/mysqld_safe5 &amp;</pre>
</li>
<li>Sécurisez votre installation de MySQL :
<pre class="niji_code niji_shell" style="">sudo /opt/local/bin/mysql_secure_installation5</pre>
</li>
<li>Si vous voulez que MySQL soit automatiquement lancé au démarrage, lancez la commande suivante :
<pre class="niji_code niji_shell" style="">sudo launchctl load -w /Library/LaunchDaemons/org.macports.mysql5.plist</pre>
</li>
</ol>
<h4>Installation de PHP 5</h4>
<ol>
<li>Lancez l&#8217;installation de php5 :
<pre class="niji_code niji_shell" style="">sudo port install php5 +apache2 +mysql5 +sqlite +pear</pre>
</li>
<li>Une fois l&#8217;installation terminée, créez un fichier de configuration pour php (le php.ini) :
<pre class="niji_code niji_shell" style="">sudo cp /opt/local/etc/php.ini-dist /opt/local/etc/php.ini</pre>
</li>
<li>Installez le module php pour Apache :
<pre class="niji_code niji_shell" style=""><span class="niji_function">cd</span> /opt/local/apache2/modules
sudo /opt/local/apache2/bin/apxs -a -e -n <span class="niji_string">&quot;php5&quot;</span> libphp5.so</pre>
</li>
<li>Editez le fichier /opt/local/apache2/conf/httpd.conf, recherchez
<pre class="niji_code niji_shell" style="">DirectoryIndex index.html</pre>
<p>et remplacez par</p>
<pre class="niji_code niji_shell" style="">DirectoryIndex index.html index.php</pre>
</li>
<li>Editez le fichier /opt/local/apache2/conf/httpd.conf et ajoutez à la fin les lignes suivantes :
<pre class="niji_code niji_shell" style=""><span class="niji_comment"># Load the PHP module
</span>LoadModule php5_module modules/libphp5.so

<span class="niji_comment">#
</span><span class="niji_comment"># Include PHP configurations
</span><span class="niji_comment">#
</span>Include conf/extras-conf/mod_php.conf</pre>
</li>
<li>Relancez Apache :
<pre class="niji_code niji_shell" style="">/opt/local/apache2/bin/apachectl -k restart</pre>
</li>
<li>Vous pouvez maintenant créer dans votre dossier Sites (/Users/<em>votrePseudo</em>/Sites/) un fichier phpinfo.php</li>
</ol>
<p>Voilà, votre environnement de développement AMP est installé et prêt à acceuillir vos scripts et applications ! Pour aller un peu plus loin, vous pouvez installer phpmyadmin et xdebug, avec MacPorts bien sûr.</p>
<p>Concernant MacPorts, je l&#8217;utilise depuis maintenant plusieurs mois et j&#8217;en suis très content. J&#8217;ai pu installer tous les packages dont j&#8217;avais besoin très simplement et sans problème. Je regrette juste de ne pas l&#8217;avoir découvert plus tôt&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogafab.com/installer-apache-mysql-php-sur-mac-os-105-avec-macports/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>

