Excellent article sur le blog SEOptimise.

Je retiens qu’un client est loin d’être roi. Il faut savoir entretenir la relation avec le client pour ne pas que ça dégénère d’un côté ou l’autre. Autrement dit, il faut savoir doser pour pas que le client en viennent à prendre trop de place dans votre travail, autant que l’inverse est vrai. Il ne faut pas que vous prenniez toute la place côté décision. Après tout vous travaillez pour le client et non pas pour vous. Le jugement est de mise.

Ajouter mon fil RSS à votre agrégateur de contenu préféré.

Dernièrement, j’ai eu a programmer l’envoi de courriels en BCC et CC. Comme le site a été fait avec Kohana, j’avais à utiliser le helper Email vue que tous mes courriels envoyés était avec ce dit helper. Après avoir fouillé quelque peu je me suis rendu compte que rien n’était prévu pour faire envoyer un courriel comme je le voulais.

Le helper de Kohana utilise Swift Mailer qui est une application PHP5 pour envoyer un courriel à l’aide en autre d’un serveur SMTP. Je devais donc modifier le helper de Kohana pour mon problème. Alors, voici comment j’ai procédé.

1. Copier le fichier Email du dossier System/Helper vers Applcation/Helper.

L’ordre de chargement des fichiers dans Kohana est Modules/Application/System. En plaçant le fichier dans le dossier application, on évite de modifier le fichier de base au cas ou un problème survient.

2. Reprogrammer la fonction send

La fonction send de base ressemble à ceci :

public static function send($to, $from, $subject, $message, $html = FALSE)
{
    // Connect to SwiftMailer
    (self::$mail === NULL) and email::connect();// Determine the message type
    $html = ($html === TRUE) ? 'text/html' : 'text/plain';
    // Create the message
    $message = new Swift_Message($subject, $message, $html, '8bit', 'utf-8')
    // Make a personalized To: address
    $to = is_array($to) ? new Swift_Address($to[0], $to[1]) : new Swift_Address($to);
    // Make a personalized From: address
    $from = is_array($from) ? new Swift_Address($from[0], $from[1]) : new Swift_Address($from);
    return self::$mail->send($message, $to, $from);
}

Pour commencer, on doit déclarer un objet Switf_RecipientList qui va contenir toutes les adresses courriel et nom de nos destinataires. Ensuite, on doit modifier la manière de gérer la variable $to. J’ai commencé par modifier le nom d’argument pour qu’il soit plus significatif. Donc $to devient $addresslist. Avec Kohana la variable du courriel de destination peut-être une chaine de texte ou un tableau :

Email::send('test@courriel.com');
//ou
Email::send(array('test@courriel.com','Le nom du destinataire'))

Cette technique sera encore valide. Par contre, nous allons ajouter la possibilité d’envoyer le courriel comme ceci :

$addresslist = array();
$addresslist['to'][] = 'test@courriel.com';
$addresslist['cc'][] = array('test2@courriel.com','Nom du destinataire en cc');
$addresslist['bcc'][] = array('test3@courriel.com','Nom du destinataire en bcc 1');
$addresslist['bcc'][] = array('test4@courriel.com','Nom du destinataire en bcc 2');
Email::send($addresslist);

Tout d’abord, on doit vérifier si la variable est sous la vieille forme ou la nouvelle

// Make a personalized To: address
$keys = array_keys($addresslist);
$isnumeric=false;
foreach($keys as $key){
    if(is_numeric($key)){
        $isnumeric=true;
    }
}
//la variable $isnumeric sera true si c'est la vieille version sinon c'est la nouvelle version

Ensuite on parcourt le tableau. La première alternative nous amène dans le code pour la vieille ou la nouvelle version de la variable. Pour la vieille version c’est la même chose que le helper de base de Kohana.

Le deuxième foreach sert à parcourir les nombreux courriels de type to,cc ou bcc. Ensuite on utilise le même code que Kohana pour obtenir un objet Swift_Address selon si c’est une chaine de texte ou un tableau. Pour finir, on ajoute l’objet retourné à l’objet Swift. Voici la fonciton send dans son entièreté :

public static function send($addresslist, $from, $subject, $message, $html = FALSE)
{
    // Connect to SwiftMailer
    (self::$mail === NULL) and email::connect();
    // Determine the message type
    $html = ($html === TRUE) ? 'text/html' : 'text/plain';
    // Create the message
    $message = new Swift_Message($subject, $message, $html, '8bit', 'utf-8');
    $recipient = new Swift_RecipientList();
    // Make a personalized To: address
    $keys = array_keys($addresslist);
    $isnumeric=false;
    foreach($keys as $key){
        if(is_numeric($key)){
            $isnumeric=true;
    }
    }
    if(is_array($addresslist) && !$isnumeric){
        foreach($addresslist as $key=>$listofelement){
            foreach($listofelement as $element){
                $address = is_array($element) ? new Swift_Address($element[0], $element[1]) : new     Swift_Address($element);
                $recipient->add($address,false,$key);
            }
        }
    }else{
        $address = is_array($addresslist) ? new Swift_Address($addresslist[0], $addresslist[1]) : new     Swift_Address($addresslist);
        $recipient->add($address,false,'to');
    }
    // Make a personalized From: address
    $from = is_array($from) ? new Swift_Address($from[0], $from[1]) : new Swift_Address($from);
    return self::$mail->send($message, $recipient, $from);
}

Carsonified a mis en ligne une multitude de vidéos concernant la conférence Future of web Apps incluant des entrevues et conférences. La conférence FOWA a eu lieu du 7 au 10 octobre 2008 et regroupait plusieurs grands de l’industrie du web. La prochaine conférence aura lieu à Miami en février prochain.

21 octobre 2008Gros rattrape

Encore un autre retour sur le marché des blogues québécois. Un manque de temps jumelé avec un manque de sujet m’a amené à délaisser mon blogue à ma plus grande déception (ainsi qu’à mes 3 lecteurs). J’ai l’intention de réorienter mon blogue (pour une 3e fois) vers un blogue sur le web en général, que ce soit sur actualité des fureteurs ou sur un code javascript. En espérant cette fois-ci de tenir un rythme de publication beaucoup plus régulier.

Donc que c’est-il passé dans ma vie de programmeur depuis les 3 derniers mois? Beaucoup de chose. Tout d’abord, j’ai travaillé sur plusieurs petits projets en “sideline” à mon emploi principal. J’ai intégré le site de Mon assurance prêt, le tout nouveau site du groupe de Hip Hop québécois Taktika. Rien de particulier dans ces projets mis à part le fait que mes capacités avec Wordpress sont nettement meilleures. Avis aux intéressés.

Ensuite, j’ai travaillé sur le du Nunavik tour de l’Orchestre symphonique de Montréal. Le contrat consistait à modifier le header/menu flash du site web. J’ai en autre appris la librairie AS3 ExternalInterface qui permet d’effectuer des appels entrants/sortants entre la page web et le flash, ou entre deux fichiers flash. Très intéressant comme librairie. Cela permettrait en autre de faire communiquer deux publicités flash entre elles.

DuProprio.tv

Nous avons aujourd’hui lancé chez DuProprio une refonte de la web-télé DuProprio.tv. Nous avions lancé la version 2 du site web en juin alors que l’interface avait complètement été refaite, en plus d’offrir au visiteur des vidéos HD grâce au diffuseur Dailymotion. Pour la mise à jour d’aujourd’hui, le design général reste le même, mais plusieurs petites modifications viennent ajouter à l’expérience utilisateur. En autre la feature que j’aime le plus est la disposition de la liste des vidéos en grille horaire. Merci JQuery!

Conférence

Pour ceux comme moi qui ont manqué les conférences de Carsonfield, de Zend ou bien de An event Appart, vous aurez la chance de vous reprendre en 2009. Plusieurs conférences ont été annoncées dont celle de An Event appart et de Carsonified. Voici la liste :

Je serais à coup sûr à minimum une conférence, deux si je suis chanceux. Des suggestions?

À lire

Je vous laisse quelques billets intéressants que j’ai lus lors des dernières semaines.

PHP.net
Compte le nombre d’occurrences de segments dans une chaîne

Cette fonction de compte pas les chaines de caractère qui ce superpose


$text = 'Ceci est un test';
echo strlen($text); // 16

echo substr_count($text, 'est'); //retourne 2

Au départ, j’étais complètement contre l’utilisation de framework. Je voulais programmer mon site web de A à Z sans intermédiaire. Je voulais garder le contrôle sur mon code en écrivant chaque ligne de code. J’avais un donc un petit système déjà bâti qui utilisait un fichier de configuration, un fichier de fonctions ainsi que mes pages PHP/HTML ensemble. Ensuite je me suis mis à apprendre l’oriente-objet pour ensuite me mettre à lire des livres sur la POO pour améliorer mes techniques de programmation. Dans les deux livres que j’ai lus sur la POO, on expliquait le design pattern MVC (Modèle-Vue-Controlleur) qui consiste a séparer l’interaction avec l’utilisateur (contrôleur), la présentation (vue) et l’interaction avec les données (modèle). Je reviendrais sur ce design pattern dans un prochain billet. Lors de mes lectures sur le sujet, je connaissais déjà cette méthode de travail sans avoir réussi à l’implémenter. Je me suis questionné sur le sujet longuement en me demandant si, un coup un tel système monté, je sauverais du temps et énergie lors de mes prochains projets.

La découverte des frameworks

Lors de mon apprentissage autonome en 6e session lors de mon DEC, j’avais exploré CakePHP, un des frameworks PHP5 les plus populaires. J’avais détesté mon expérience ne comprenant pas trop comment il marchait, et ce, malgré la présence de tutoriels. On me vantait ce framework comme un système qui me ferait sauver un temps fou en développement, alors que je ne voyais pas comment il pouvait y arriver. J’avais tout de même accroché sur le fait qu’il était possible de développer avec le pattern MVC.

Lors de mon questionnement sur un développement en POO, recommencer à utiliser un framework m’est revenu à l’idée. En fait, c’est un collègue scolaire et bon ami Rémi Prévost qui fait découvrir un autre framework PHP5 : Code Igniter. Il m’aura fallu quand même 8 mois avant de l’utiliser. Et maintenant, après 4 mois d’utilisation, je peux faire une bonne critique de cet outil. Les avantages et inconvénients des frameworks qui suivront sont basés sur une utilisation de Code Igniter et Kohana. Je n’ai jamais utilisé Symfony ou ZendFramework. Également, je ne peux critiquer Cake vu ma trop courte utilisation de ce framework. Également, la vue d’ensemble que je vous offre aujourd’hui ne représente que les frameworks PHP.

La POO : un bijou en soi

Le plus dur pour un programmeur est de passer de la programmation procédurale à celle orientée-objet. Une multitude de concepts s’ajoute lorsqu’on fait le saut à la POO. Les frameworks vous offrent la possibilité d’apprendre l’orienté-objet facilement. Vu que le système est déjà préconçu, il est facile d’avancer dans un petit projet pour apprendre les bases de la POO. Avec un tutoriel bien monté ainsi qu’une documentation riche, il devient facile de s’en sortir.

Un autre avantage d’utiliser la POO des frameworks et que vous pouvez le modifier sans toucher au code original du système. Il suffit d’ajouter par exemple une classe enfant pour écraser une fonction dont vous n’aimez pas le fonctionnement. Cette méthode est également valide lors de prochaine modification sur votre projet. Elle vous évitera plusieurs problèmes que la programmation procédurale peut vous causer. Vous savez sûrement de quoi je parle quand vous modifiez une fonction sur une page en particulier qui affecte une dizaine de pages sans le vouloir.

Le pattern MVC

Comme je le disais plus haut, j’utilise les frameworks en partie en raison de la programmation orientée-objet et pour le pattern MVC. J’apprécie beaucoup le fait d’avoir mon contenu séparé en trois couches. Cela évite en premiers lieux d’avoir des fichiers beaucoup trop gros. Il m’est déjà arrivé d’avoir des fichiers de fonctions communes (disponible sur plusieurs pages de mon site) de plus de 3000 lignes de code. Trouver une erreur dans ce fichier gigantesque était un défi en soi. Tout étant séparé dans le pattern MVC, il devient facile de cerner une erreur et de la corriger rapidement. Par exemple, lorsque l’erreur est d’ordre HTML, il suffit de regarder dans la Vue concernée. Plus le site devient gros, plus l’utilisation du pattern MVC est utile.

Un autre avantage d’utiliser ce pattern se situe au niveau du travail d’équipe. On peut facilement se retrouver dans le travail d’un collègue, même en ayant perdu le fil du projet pendant des semaines. On peut également développer en même temps sur le même projet sans trop s’accrocher, surtout pour l’intégration CSS/HTML. Pendant qu’un intégrateur modifie l’HTML d’une page, rien n’empêche le programmeur PHP de continuer l’ajout de fonctionnalité dans les contrôleurs.

La réécriture d’URL

Avec la puissance de Google, il est plus qu’important d’être visible sur le web. Une des techniques utilisées pour y arriver est la réécriture d’URL. Elle permet de passer d’une URL de type : posts.php?id=1&page=2 à quelques choses du genre posts/une-nouvelle-page/2 . Cette URL est beaucoup plus significative pour un moteur de recherche que la première, vu la présence de mots-clés directement dans l’URL. C’est souvent long et pénible de réécrire des URL. Avec un framework, on commence avec 90% du travail effectué. La manière dont le système est bâti vous offre déjà l’URL réécrite. Par exemple, l’URL par défaut de Kohana est http://www.monsite.com/index.php/welcome/index. Ce qui veut dire que le framework appelle la page index.php (la pièce maîtresse du système) qui appelle le contrôleur welcome et ensuite la fonction index du contrôleur. Il ne vous reste qu’à utiliser un htaccess pour cacher le index.php pour avoir une réécriture d’URL presque parfaite. Le reste de votre travail se fera dans le routage de ces URL pour qu’elles soient peaufinées à votre goût.

Les validations

Je déteste faire les validations d’un formulaire. Ce sont souvent des routines que vous avez fait des centaines de fois, mais qui vous font perdre énormément de temps de développement. Les frameworks offrent presque tous maintenant des routines de validation pour les formulaires qui vous épargne beaucoup de temps. En passant par la validation de courriel ou simplement la validation d’un champ requis tout y est. Vous pouvez sans problème ajouter des validations manuellement. La beauté de tout cela est que les messages d’erreurs sont gérés automatiquement.

Internationalisation du site web

Traduire un site web devient de plus en plus important, surtout pour un francophone qui veut que son site web soit lu et visité par le plus de personnes possible. Les méthodes variaient de beaucoup que ce soit un simple fichier PHP ou un XML qui contenait les lignes de texte. Un framework n’échappe pas vraiment à ces méthodes, mais c’est plus une certaine automatisation qui fait la beauté du système. Codeigniter et Kohana utilisent un peu le même système, soit un fichier dossier par langue qui contient plusieurs fichiers selon les pages du site (en fait vous décidé de la manière dont vos fichiers de langues sont gérés). Donc, il ne vous reste plus qu’à appeler la fonction lang (avec kohana) pour afficher le texte désiré. Votre site a besoin d’une deuxième langue, copier la première langue et traduisez. Ensuite il ne vous reste plus qu’à faire la validation qui détermine dans quelle langue le site se trouve.

Et bien plus encore…

Les frameworks contiennent encore plus que vous le pensez. On retrouve souvent un système de cache, de benchmark ou de logs. Ces trois éléments sont souvent utilisés pour améliorer les performances d’un site web. Plus votre site est gros, plus il est impératif d’avoir les meilleures performances possible. D’autres éléments viennent se greffer à tout ce que je vous ai déjà montré. Des librairies monter pour vous faire sauver du temps de développement, des classes dites “helper” qui ont les mêmes tâches que les librairies, mais plus petites. On ajoute à cela une configuration malléable pour former une recette gagnante.

Vais-je continuer à utiliser un framework?

La réponse est oui avec un bémol. L’utilisation d’un framework doit être justifiée. Un site de petite envergure comme une compagnie d’électricien sur la Rive-Sud de Montréal ne justifie en rien l’utilisation d’un framework. Le site doit être d’une envergure moyenne à grosse pour que l’utilisation d’un framework soit rentable. Un facebook ne devrait pas être développé avec un framework vu sa grosseur et sa complexité. Notez que plus le site devient gros et complexe, plus le temps sauvé par l’utilisation d’un framework par rapport à un site procédural devient presque inexistant. Pour ce point je parle par rapport à l’expérience vécue lors des derniers mois. Est ce que je regrette l’utilisation d’un framework pour ce projet? Non pas du temps. Si c’était à refaire, je referais la même chose.

On vous vente souvent la rapidité avec laquelle vous aller développer votre site web en utilisant un framework. Je suis ne pas vraiment d’accord avec cette affirmation. Il y a trop de facteurs à prendre en considération lors d’un développement de site web qui influence le temps de développement. Prenez simplement par exemple le temps d’apprentissage du dit framework. Il est évident que vous allez développer très vite si vous êtes un programmeur expert en POO et que c’est votre vingtième site avec votre framework. Même chose si vous êtes un habitué des sites plus traditionnels, vous aurez une vitesse de croisière supérieure comparativement à l’utilisation d’un framework. Tous ces arguments font en sorte que je n’ai même pas donné la vitesse de développement comme raison d’utiliser un framework.

Un autre désavantage de développer avec un framework est que lorsque vous avez besoin de quoi de moindrement hors-norme, il peut devenir complexe de le coder. Vous devez toujours avoir en tête que cela fonctionne avec le framework, sans le ralentir ou le détruire. Également, si vous n’aimez pas un “feature” du framework vous êtes pris avec ou vous devez changer de système. Par exemple, la classe de la gestion des bases de données. Finalement un dernier point, lorsque vous développerez une “feature” sur un framework, vous serez porté à utiliser les librairies ou helper du framework. Le problème sera lorsque vous tenterez de déplacer la classe ou fonction dans un nouveau framework ou dans un site qui n’en utilise pas. Vous perdrez beaucoup de temps à réécrire certaines parties du code pour le rendre compatible avec votre nouveau site web. Un conseil, limitez le plus possible les utilisations de librairies ou helper externe dans votre nouvelle feature.

Voilà, j’espère vous avoir éclairé sur l’utilisation d’un framework. Mon but n’est pas de vous forcer la main pour utiliser un framework ou non, mais bien de vous faire comprendre pourquoi moi j’ai utilisé un framework lors des derniers mois. À vous de juger si cela vous convient ou non.

Federico Cargnelutti a publié hier sur son blogue PHP impact une liste d’applications PHP open-sources qui selon lui, ont changé le monde du web. On retrouve dans cette liste des applications connues de tous tel que phpMyAdmin ou bien Wordpress.

Je suis d’avis que bien des applications sur cette listes n’ont pas vraiment changé le monde tel quel, mais plus des habitudes de programmation. La plupart des applications sont quasi réservé au programmeur (tel que joomla, phpmyadmin ou bien symfony). Les deux plus grandes applications open-sources sur cette liste qui ont changé le monde à mon avis sont phpBB et Wordpress vue leur utilisation mondiale et leur multitude d’applications dérivés.

http://phpimpact.wordpress.com/2008/05/22/open-source-php-applications-that-changed-the-world/

Il ne reste plus que quelques jours avant le lancement officiel de Firefox 3. Et pour l’événement, Firefox souhaite s’inscrire dans le livre des records Guinness en étant le logiciel le plus téléchargé en 24 heure. Pour réaliser l’exploit, Firefox à lancé un site web qui voua rappellera le jour du lancement de télécharger Firefox3.

Définition tiré de PHP.net
Vérifie la liste des fonctions définies par l’utilisateur afin d’y trouver function_name.

Cette fonction vous permet de vérifier si une fonction est déclaré dans votre code PHP. Très utile pour vérifier si une librairie est chargé.


if(function_exists("mcrypt_encrypt")){
	echo 'La librairie MCrypt est chargé';
}else{
	echo 'La librairie MCrypt n\'est pas chargé. Impossible d\'encrypter des données';
}

30 mai 2008Les Exceptions

Une Exception est une classe d’erreur souvent disponible sur tous les langages en orienté objets. Cette classe est disponible depuis PHP5 et elle est de plus en plus utilisée pour la gestion d’erreur dans un contexte POO.

Un tour d’horizon de la classe

Tout d’abord, la classe à trois variables importantes accessibles par leur fonction respective. Chaque variable est typé protected ce qui veut dire qu’elles ne peuvent être modifiées ou lues de l’extérieur de la classe ou des classes parent/enfant.

  • message : contient le message assigné à la classe.
  • line : contient la ligne où l’erreur s’est produite.
  • file : contient le fichier où s’est produit l’erreur.

Ensuite il existe 5 méthodes dans la classe Exception accessible sous le format $exception->méthode()

  • getMessage() : retourne le message d’erreur assigné lors de la création de la classe.
  • getCode() : retourne le code d’erreur
  • getLine() : retourne la ligne où l’erreur s’est produite.
  • getFile() : retourne le fichier où l’erreur s’est produite.
  • getTrace() : retourne un tableau associatif qui contient plusieurs informations sur l’erreur que voici:
    • file : le fichier où s’est produite l’erreur.
    • line : la ligne où s’est produite l’erreur.
    • function : la fonction où s’est produite l’erreur.
    • class : la classe où s’est produite l’erreur.
    • type : type d’appelle de la fontion (static, public etc.).
    • args : tableau associatif contenant les arguements passés à la fonction.
  • getTraceAsString : retourne la même chose que getTrace mais sous forme de chaine de texte.

Bien comprendre les Exceptions

Utiliser une exception est fort simple. Il suffit de le voir comme la relation entre le lanceur et le receveur au baseball. Le lanceur est le programmeur alors que le receveur est PHP. Tout d’abord, le lanceur choisi qu’elle balle lancer, ensuite le receveur attrape la balle. Que cette balle soit une rapide, une courbe ou un changement de vitesse, il l’attrape. La différence entre le receveur et PHP est que PHP adapte son action en conséquence du type d’exception lancé. Mais avant de rentrer dans la partie la plus dure du sujet, utilisons une exception pour bien comprendre son fonctionnement dans le code.


throw new Exception('une erreur est survenu');

Si vous essayé ce code vous aller avoir l’erreur suivante : Fatal error: Uncaught exception. Nous devons y aller de deux étapes pour régler cette erreur. La première, essayer de lancé l’exception et ensuite l’attraper


try{
	throw new Exception('une erreur est survenu');
}
catch(Exception $e){
	echo $e->getMessage();
}

Ce code écrira le message d’erreur, qui dans ce cas-ci est une erreur est survenu. L’avantage de la gestion d’erreur est que nous pouvons faire a peu près n’importe quoi suite à une erreur voulu. Par erreur voulu, je veux dire une erreur déclarée par le programmeur après une validation. Voici une exception dans un contexte réelle.


function check_type($int){
	if(!is_numeric($int)){
		throw new Exception('Vous devez envoyer un nombre en argument.');
	}
	return true;
}
try{
	check_type('test');
}
catch(Exception $e){
	exit($e->getMessage());
}

Vos propre classe Exception

Il est possible grâce à l’héritage de créer vos propres classes d’exception. Pourquoi? Pour vous permettre de gérer plusieurs types d’erreur de manière différente. Disons pour notre exemple que nous voulons un type d’erreur d’exécution. Le message d’erreur sera toujours la même grâce à l’héritage, ce qui veut dire que le message d’erreur ne sera pas obligatoirement passé en argument lors de l’envoi de l’exception.


class Execution_Exception extends Exception{

	protected $message = 'Erreur d\'éxécution';

	public function __construct(){}
}

try{
	throw new Execution_Exception();
}
catch(Execution_Exception $e){
	exit($e->getMessage());
}

Adieu Try/Catch!

Vous conviendrez avec moi que d’écrire la syntaxe Try/Catch à chaque Exception serait relativement pénible. Ça serait du trouble qui ferait en sorte qu’aucun programmeur n’utiliserait les Exceptions et se tournerait vers la bonne vieille fonction die(). Heureusement, PHP à créé une fonction appelé set_exception_handler() qui vous permet de dire à PHP d’appeler la fonction de votre choix s’il ne trouve pas la syntaxe Try/Catch. Cette fonction est un bijou en soit et vous ouvre la porte à une multitude d’avenu pour la gestion d’erreur. Par exemple, vous pourriez dans cette fonction ajouter un système de Log qui vous permettrait de garder la trace des erreurs survenu sur votre site web. Voici un petit bout de code qui vous montre brièvement l’utilisation de set_exception_handler().


set_exception_handler("exceptionHandler");

function exceptionHandler($exception){
	echo $exception->getMessage();
}

class Execution_Exception extends Exception{

	protected $message = 'Erreur d\'éxécution';

	public function __construct(){}
}

throw new Execution_Exception();

Voila pour ce petit tour d’horizon rapide des Exceptions. Implémenter des Exceptions nécessite un peu plus de temps de programmation, mais un coup complété, on en sort un réelle plaisir à les utiliser.


© 2008 Blogue de Pierre-Luc Babin | Curved Wordpress Theme by JustSkins.com | Propulsé by Wordpress 2.5