XHTML.net

Technology talks by Loïc d’Anterroches

News, articles, PHP, scripts, XHTML/CSS, …

  1. Home
  2. PHP: Hypertext Preprocessor
  3. Pluf - Framework en PHP5

Unit testing dans Pluf

The 2008-05-09 at 14:32 by Loïc d'Anterroches filed under Pluf - Framework en PHP5.

Ce matin, je vous donnais 8 astuces pour votre développement d’application web et cela en même temps me forçait à penser à un système robuste pour faire des tests unitaires dans une application développée avec Pluf. J’ai maintenant un bon mal de crâne, mais j’ai aussi implémenté un système basé sur SimpleTest. Lisez les commentaires de ma note de ce matin, vous verrez la coincidence… en effet l’auteur de SimpleTest est venu proposer d’utiliser SimpleTest…

Avec testrunner.php, vous pouvez lancer les tests de votre application.

$ php ./chemin/vers/testrunner.php VotreApp ./VotreApp/conf/votreapp.test.php

Cela va charger tous les tests disponibles dans le répertoire VotreApp/Tests ainsi qu’un niveau de sous-répertoires et les lancer.

Chaque fichier doit contenir une classe qui étant la classe UnitTestCase. Le nom de la classe doit suivre les conventions de Pluf, par exemple VotreApp_Tests_monTest pour une classe dans le fichier VotreApp/Tests/monTest.php.

Et voilà !

Maintenant, la vraie partie intéressante est la possibilité de tester vos vues sans avoir besoin d’un serveur web ! Pour cela, utilisez le client Pluf_Test_Client dans vos tests :

Pluf::loadFunction('Pluf_HTTP_URL_urlForView');
$url = Pluf_HTTP_URL_urlForView('VotreApp_Views::accueil');
$client = new Pluf_Test_Client(Pluf::f('votreapp_views'));
$reponse = $client->get($url, array('param_optionel' => 'toto'));
$this->assertEquals(200, $response->status_code);
print $response->content;
print_r($response->template); 

L’objet $response vous donne accès au gabarit utilisé pour faire le rendu de la page. Il est disponible dans $response->template et le contexte associé est dans $response->template->context. Cela vous permet de regarder que le contexte a les bonnes valeurs.

Le client supporte les sessions. Donc si vous l’utilisez avec une méthode POST pour vous connecter, vous pouvez ensuite réutiliser ce client pour accéder une page qui demande d’être connecté, par exemple :

$client->post('/mapagedelogin/', array('login' => 'toto', 'password' => 'secret'));
$client->get('/mapageprivee/');

Bien entendu, c’est mieux d’utiliser Pluf_HTTP_URL_urlForView pour les URLs car cela évite de les coder en dur.

Bon, maintenant, il me reste à faire les choses suivantes :

  • Une méthode standard pour initialiser un environnement de test propre au moment de lancer le testrunner.
  • Convertir les tests de Pluf pour suivre la nouvelle infrastructure.
  • Convertir mon propre code pour suivre cette nouvelle infrastructure.
  • Faire la chasse aux bugs :)

Vary header avec Pluf

The 2008-05-08 at 19:08 by Loïc d'Anterroches filed under Pluf - Framework en PHP5.

Mes expériences avec le système de traduction de Pluf m’ont fait toucher à une en-tête (header) renvoyée par le serveur. Cet en-tête est Vary. Cet en-tête permet d’informer les navigateurs/agents ainsi que les proxy/caches que le contenu d’une page varie en fonction des en-têtes émis par l’agent faisant la requête.

Par exemple, mon navigateur, Firefox, envoie cela comme information quand il faut une requête :

Accept: text/xml,application/xml,application/xhtml+xml,
        text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en,fr;q=0.7,en-us;q=0.3

Cela veut dire, j’accepte du contenu dans différents formats, avec la priorité au format text/xml, puis application/xml, … et à la find image/png et enfin */* tout ce qui reste. Le navigateur accepte aussi le contenu en Anglais, puis Français et Anglais américain. Vous noterez pour certains cas la présence d’un paramêtre q avec une valeur. Ce paramêtre q, comme qualité, avec les langues s’explique de la façon suivante :

en,fr;q=0.7,en-us;q=0.3 correspond en étendu à en;q=1,fr;q=0.7,en-us;q=0.3

Maintenant supposons que vous puissiez accéder au site http://example.com/mon_sujet/ et que ce dernier dispose de 3 versions, une en anglais, une en français et une en américain. Le serveur va maintenant devoir choisir quelle page retourner. Comment choisir ?

Il faut d’abord attribuer une valeur aux trois versions. La valeur correspondera par exemple à la quantité d’information disponible. On va dire que par exemple, la page en Anglais à une qualité de 0.5, la page française de 0.9 et la page américaine de 1.0.

Le résultat du calcul pour chaque langue est le suivant :

  • Anglais : 1.0x0.5 = 0.5
  • Français : 0.7x0.9 = 0.63
  • Américain : 0.3x1.0 = 0.3

C’est donc la page française avec le score le plus haut qui sera retournée. Maintenant, c’est à vous de donner en interne un score pour chaque version de vos pages… en pratique les personnes donnent un score de 1 pour chaque version et donc retourne dans notre cas la version anglaise.

Vous pouvez lire un peu plus sur ces en-tête ici : RFC 2616, Header Field Definitions.

Donc maintenant, vous comprenez que la page http://example.com/mon_sujet/ ne va pas toujours être la même et que le contenu varie en fait par rapport à l’en-tête Accept-Language. Si vous avez maintenant un système de cache naïf, qui stocke une version par URL, cela ne marche pas, car finalement une seule des 3 versions va être mise en cache… problème !

C’est là que l’en-tête Vary du serveur intervient. Cet en-tête dit au système de mise en cache, attention, le contenu de cette page varie en fonction de certaines caractéristiques de la requête. C’est pourquoi on renvoie l’en-tête suivant :

Vary: accept-language

Si vous renvoyez une page qui est en xml ou html en fonction de la requête, vous pourriez mettre :

Vary: accept-language, accept

Il faut donc dans Pluf un moyen élégant de mettre à jour cet en-tête. Je n’ai trouvé qu’une solution pour le moment, mettre dans l’objet requête l’information de la manière suivante :

$request->response_vary_on = 'accept';

Pourquoi sur la requête et pas ajouter manuellement dans la réponse ? Vous pouvez le faire, mais souvent, on n’a pas accès à l’objet réponse. En effet, une vue typiquement ce termine par l’appel suivant :

function mavue($request, $match) 
{ 
    .....
    return Pluf_Shortcuts_RenderToResponse('mongabarit.html', 
                              array('param1' => $toto, ...));
}

Comme vous ne touchez pas à l’objet réponse, il faut trouver une autre solution élégante. Et comme l’objet $request est disponible à tous les niveaux du dispatcher, j’ai donc choisi cette option :

function mavue($request, $match) 
{ 
    .....
    $request->response_vary_on = 'accept';
    return Pluf_Shortcuts_RenderToResponse('mongabarit.html', 
                               array('param1' => $toto, ...));
}

Le problème est que cela fait une condition if supplémentaire pour toutes les vues, que l’en-tête Vary soit utilisé ou non. Cela pose donc une question de performance. Je vais voir si je trouver une méthode plus élégante.

Petit plaisir du système de traduction

The 2008-05-08 at 12:19 by Loïc d'Anterroches filed under Pluf - Framework en PHP5.

Avec le système de traduction, voici une réponse type :

Date: Thu, 08 May 2008 12:10:14 GMT
Server: Apache/2.2.4 (Ubuntu) PHP/5.2.3-1ubuntu6.3
X-Powered-By: Pluf - http://pluf.org/
Vary: Accept-Language
Content-Language: fr
Content-Length: 19263
Keep-Alive: timeout=15, max=90
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8

200 OK

Le système retourne bien la langue du contenu et indique bien que le contenu de la page varie en fonction de l’en-tête Accept-Language du l’agent faisant la requête. C’est chouette… Le choix de la langue se fait en cherchant dans l’ordre :

  1. la clef pluf_language dans la session ;
  2. un cookie pluf_language (le nom peut être changé dans la configuration de l’application) ;
  3. la configuration du navigateur/agent faisant la requête ;

La langue séléctionnée est disponible dans $request->language_code et est utilisée pour écrire l’en-tête Content-Language dans la réponse. Bon, pour le moment, l’en-tête Vary est écrasé par le middleware, je vais devoir mettre à jour et non écraser. Mais bon, ce n’est pas trop important pour le moment.

Le système de traduction dans Pluf

The 2008-05-08 at 16:39 by Loïc d'Anterroches filed under Pluf - Framework en PHP5.

Et voilà, c’est en ligne la doc pour traduire vos applications avec Pluf. Voici un exemple de gabarit traduit :

<h1>{trans "Pluf internationalization"}</h1>
{assign $n_methods = $methods.count()} 
<p>{blocktrans $n_methods}To translate your code, use 
  the following method:{plural}To translate your code, use 
  one of the {$n_methods} methods:{/blocktrans}</p>
<ul>
{foreach $methods as $method}
  <li>{blocktrans}Name: {$method.name}, 
  Description: {$method.description}.{/blocktrans}</li>
{/foreach}
</ul>

Grosso modo, vous avez la fonction trans pour une ligne simple à traduire, blocktrans pour du multi ligne avec substitution de variables et pour les cas pluriels. Dans le code vous pouvez utiliser __() et __n().

Pour activer la locale, il suffit d’activer le middleware Pluf_Middleware_Translation et d’avoir la liste des langues supportées par l’application dans la configuration: $cfg[‘languages’] = array(‘en’, ‘fr’, ‘fr_QC’,);

Le middleware va automatiquement détecter le langage adapté pour le navigateur et retourner la bonne traduction.

Mise en place des traductions dans Pluf

The 2008-05-07 at 10:24 by Loïc d'Anterroches filed under Pluf - Framework en PHP5.

Au départ, Pluf a hérité du module de traduction de Plume. Dans les tests unitaires de Pluf vous pourrez voir que j’ai étendu ce module pour supporter le cas des pluriels. C’était une extension simple et peu pratique pour supporter les langues avec des pluriels variés (genre le Russe).

Conclusion, j’ai presque fini de faire une implémentation propre de gettext en PHP. L’intérêt par rapport à l’utilisation de la version de gettext installée avec PHP est que vous n’avez pas besoin d’avoir la locale concernée installée sur votre système pour que cela fonctionne,

Le système utilise les catalogues au format gettext (fichiers .po) en utf-8, donc vous pouvez utiliser un éditeur comme Poedit pour faire les traductions. Le fichier .po est lu par Pluf et pour des raisons de performances peut être mis en cache dans un tableau PHP stocké dans un fichier. L’utilisation d’un simple tableau dans un fichier PHP pour la mise en cache permet la mise en cache par des systèmes comme XCache.

J’ai encore un peu de travail pour mettre en place le middleware qui va charger la bonne locale en fonction du choix de l’utilisateur et la mise en place de ce que les anglais nomment le "lazy loading", qui permet de charger la locale qu’au premier appel à une traduction. Vous pouvez vous attendre à voir arriver tout cela en ligne d’ici à la fin de cette semaine avec la doc qui va bien sur le site de Pluf.

Les migrations dans Pluf, c'est génial

The 2008-04-29 at 09:59 by Loïc d'Anterroches filed under Pluf - Framework en PHP5.

Pour mon application de gestion de conférences, j’utilise Pluf (oui, les sites ont tous les deux un design ultra léger) et comme je modifie et j’ajoute de nouvelles fonctionnalités régulièrement, je me retrouve aussi régulièrement à devoir modifier les tables de ma base de données. Pour faire cela facilement, j’utilises les migrations de Pluf. C’est tout simple. Par exemple, ici j’ajoute la table d’un nouveau modèle CM_Track et je modifie celle de CM_Session quand je fais l’upgrade de la version 8 à la version 9, dans le downgrade, j’enlève la table et la colonne.

function CM_Migrations_9AddTracks_up($params=null)
{
   $db = Pluf::db();
   $db->begin(); // Start a transaction
   try {
       $track = new CM_Track();
       $schema = new Pluf_DB_Schema($db);
       $schema->model = $track;
       $schema->createTables();
       $session = new CM_Session();
       $table = $session->getSqlTable();
       $db->execute('ALTER TABLE '.$table.' ADD COLUMN track INTEGER NOT NULL '
                    .'CONSTRAINT '.$table.'_track_fkey '
                    .'REFERENCES '.$track->getSqlTable().' (id) MATCH SIMPLE '
                    .'ON UPDATE NO ACTION ON DELETE NO ACTION');
   } catch (Exception $e) {
       $db->rollback();
       throw $e;
   }
   $db->commit(); 
}

function CM_Migrations_9AddTracks_down($params=null)
{
   $db = Pluf::db();
   $db->begin(); // Start a transaction
   try {
       // Update the abstract and review tables
       $session = new CM_Session();
       $table = $session->getSqlTable();
       $db->execute('ALTER TABLE '.$table.' DROP COLUMN track');
       $schema = new Pluf_DB_Schema($db);
       $schema->model = new CM_Track();
       $schema->dropTables();
   } catch (Exception $e) {
       $db->rollback();
       throw $e;
   }
   $db->commit(); 
}

Les migrations de Pluf inspirées de Ruby on Rails permettent de facilement passer d’une version de la base de données à une autre sans se compliquer la vie, on peut facilement revenir en arrière et donc on peut facilement faire des tests. Si vous utilisez un framework x ou y, regardez ce qu’il propose pour vous simplifier la vie de développeur.

Un nouveau site pour Pluf

The 2008-04-25 at 21:44 by Loïc d'Anterroches filed under Pluf - Framework en PHP5.

Cela commence tout doucement Pluf.org.

C’est vide, très vide, mais cela va se remplir régulièrement, surtout que je produits le contenu du site off-line et ensuite je fais un simple upload. Et oui, un site à l’ancienne. Bon, je code en MarkDown uniquement le contenu des pages puis j’ai un script qui fait tout le travail pour mettre en-tête, pied de page, mais au final c’est du bon .html sur le serveur. Le serveur, d’ailleurs, c’est nginx, car depuis un moment je n’utilise plus Apache.

Administration automatique pour Pluf, cela avance

The 2008-04-14 at 11:38 by Loïc d'Anterroches filed under Pluf - Framework en PHP5.

Liste des choses à faire via l'admin

Ajouter quelque chose à faire via l'admin

Comme vous pouvez le voir, les modèles de l’application de test peuvent être directement utilisés dans l’interface d’administration. Pour les déclarer dans l’administration, seul un fichier papp.php suffit. Voici le contenu de ce fichier :

return array('path' => 'todo',
            'name' => __('Todo Manager'),
            'models' => array('list' => 
                              array('model' => 'Todo_List',
                                    ),
                              'item' =>
                              array('model' => 'Todo_Item',
                                    'list_display' => 
                                    array('item', 
                                          'completed',
                                          ),
                                    ),
                              ),
            );

Vraiment tout simple…

Packager pour Pluf

The 2008-04-13 at 20:52 by Loïc d'Anterroches filed under Pluf - Framework en PHP5.

Vous avez peut-être constaté que pour coder proprement une application vous compartimentez votre code en un certain nombre de fichiers. Cela vous donne donc un code tout propre où vous retrouvez facilement vos petits. Maintenant, dans le cas d’une application web, cela pose un problème d’efficacité. Prenons l’exemple d’une application qui se trouve dans environs 100 fichiers :

  • votre serveur va devoir dans le pire des cas accéder 100 fichiers pour générer votre page ;
  • vous n’avez aucune garantie que vos fichiers sont rassemblés au même endroit sur le disque ;
  • si dans le cas de php vous utilisez des include_once cela va faire beaucoup de test d’existence de fichiers pour rien ;

Maintenant si vous pouviez toujours charger dans un fichier, cela serait bien pratique. Par contre, il faut bien entendu ne pas tout coder dans un seul fichier. La solution est de coder normalement, avec par exemple un fichier par class/module, et au moment de mettre en ligne, vous compilez le tout en un gros fichier.

Cela vous coûtera un peu de mémoire car toute la bibliothèque va être chargée mais les performances au niveau du disque seront bien meilleures. Si vous ne touchez pas l’occupation mémoire limite de votre hébergement, c’est tout bénéfice.

Pluf a maintenant un packageur. Cela réduit le code à un gros fichier de 250ko environ, que du code, pas de commentaires.

Au niveau performance, cela donne pour une page assez complexe de mon application les résultats suivants :

Avant : Mémoire 3Mo, temps 0,3s, fichiers inclus 74.
Après : Mémoire 9,5Mo, temps 0,25s, fichiers inclus 11.

On gagne du temps et on perd de la mémoire…

L'administration automatique de Pluf dans le dépôt

The 2008-04-13 at 14:06 by Loïc d'Anterroches filed under Pluf - Framework en PHP5.

Bonne nouvelle, vous disposez maintenant de l’administration automatique dans Pluf. Le principe et les restrictions sont les suivantes :

  • le code n’est pas prêt pour la production du tout, c’est plus du preuve que le concept fonctionne ;
  • la partie graphique vient de Django et cette partie n’est pas libre, il reste donc un gros travail pour faire un style propre à Pluf ;
  • c’est à peine testé ;
  • il faut créer un fichier papp.php dans le dossier de votre application pour qu’elle apparaisse dans la partie d’administration, cf. le fichier papp.php de Pluf ;

Pour installer l’application :

php migrate.php --conf=chemin/vers/Admin/conf/admin.php -i -a

Cela va faire la création de la base de données et tout le bazar au besoin.

Auto admin avec Pluf

The 2008-04-13 at 09:53 by Loïc d'Anterroches filed under Pluf - Framework en PHP5.

Petite prévisualisation de ce que je fais en ce moment. Jojaba va me taper sur les doigts car je ne travaille pas sur Plume 1.2.3, mais bon, par moment c’est bon de juste faire ce qu’on a envie.

Auto admin dans Pluf, inspirée par Django

Merci Django pour la base du thème et Ubuntu/Tango pour les couleurs.

Finalement, DRY c'est bien

The 2008-04-11 at 13:02 by Loïc d'Anterroches filed under Pluf - Framework en PHP5.

DRY, Don’t Repeat Yourself, en français, ne vous répétez pas. C’est la maxime des programmeurs, on ne fait pas du copier-coller, mais on essaye de structure son code pour que chaque ligne soit vraiment indispensable tout en ayant un code clair au final.

En développant Pluf, j’ai essayé de bien suivre cette maxime et c’était une bonne idée, surtout quand je vois la vitesse à laquelle je suis en train de construire l’administration automatique pour Pluf. Oui, totalement inspirée par Django, car à chaque fois que je code avec Django cette administration fait mon bonheur, alors pourquoi ne pas avoir la même chose pour Pluf ?

Note : Finalement, je vais continuer sur l’idée de faire du libre en début d’après midi. Ce n’est pas très long, mais cela aura le mérite d’être une plage horaire régulière.

Introduction à PHP 5.3 et Pluf

The 2008-03-15 at 14:02 by Loïc d'Anterroches filed under Pluf - Framework en PHP5.

Si vous codez régulièrement en PHP, voici une introduction à PHP 5.3. Cela vaut la peine de passer rapidement en quelques minutes à travers les 30 diapos de la présentation. Ilia présente de manière synthétique et efficace les améliorations de cette nouvelle version. L’intérêt vient particulièrement de l’ajout des espaces de noms.

namespace LIB;
class MySQL {}
class SQLite {}
$b = new SQLite();
                       
namespace LIB_EXTRA;
class MScrypt {}
$a = new MScrypt();
var_dump(
       get_class($a),
       get_class($b)
); 

string(18) "LIB_EXTRA::MScrypt"
string(11) "LIB::SQLite"

La très bonne nouvelle est qu’il est possible d’avoir plusieurs espaces de noms dans le même fichier PHP. Aujourd’hui, pour des raisons de performances, je suis en train de mettre en place un système permettant de faire un paquet de Pluf. C’est à dire que je prends tous les fichiers de Pluf, je les passe via php -w ce qui enlève tous les commentaires et les espaces inutiles et je consolide cela en un fichier unique.

Cela permet d’enlever le besoin de tous les includes et surtout cela ne garde en mémoire qu’un unique fichier. Quand j’utilise un système qui met en cache l’opcode PHP comme XCache ce n’est pas très important, mais quand cela tourne sur du serveur partagé, cela améliore les performances notablement.

La possibilité d’avoir plusieurs espaces de noms dans un fichier PHP permet de continuer de faire cette optimisation, yeah !

Système de préconditions pour les vues dans Pluf

The 2008-01-31 at 12:19 by Loïc d'Anterroches filed under Pluf - Framework en PHP5.

Supposons qu’avec Pluf, vous avez 10 vues et que toutes les vues demandent à ce que l’utilisateur soit enregistré pour voir ces vues. Aujourd’hui, dans le code vous avez 10 fois quelque chose du genre :

class maclass
{
    function mavue($request, $match)
    {
        if ($request->user->isAnonymous()) {
            return new Pluf_HTTP_Response_RedirectToLogin($request);
        }
        ....
    }
}

Maintenant vous pouvez enlever le bloque if, prendre la liste des vues et ajouter pour chaque vue :

$ctl[ = array('regex' => '#^/whatever/$#',
               'priority' => 4,
               'base' => '/index.php',
               'precond' => 'Pluf_Precondition::loginRequired',
               'model' => 'maclass',
               'method' => 'mavue');

precond est soit une unique précondition, soit un tableau avec une liste de préconditions. Une précondition est une méthode statique qui retourne soit true en cas de succès soit objet de type Pluf_HTTP_Response ou dérivé en cas d’erreur. C’est tout simple et c’est rudement efficace. Encore un petit truc pour éviter d’écrire plusieurs fois la même chose dans votre code.

Système de permission pour chaque objet de manière individuelle

The 2008-01-29 at 12:50 by Loïc d'Anterroches filed under Pluf - Framework en PHP5.

Les anglophones nomment cela row level permissions, pour les autres, bon la traduction n’est pas évidente.

Bon, si vous utilisez Pluf, vous avez certainement découvert le système de permissions. Il est basé sur le principe des groupes et des permissions individuelles. En gros, vous pouvez :

  • associer une (ou plusieurs) permission directement à un utilisateur ;
  • associer une (ou plusieurs) permission à un groupe et associer le groupe à un utilisateur, l’utilisateur hérite des permissions du groupe.

C’est simple et efficace, vous pouvez facilement faire quelque chose du genre :

if ($user->hasPerm('Monde.detruire_monde')) {
    // appuyer sur le bouton rouge
}

Mais maintenant supposons que nous ayons plusieurs mondes, on fait comment pour donner des droits sur un monde et pas sur un autre ?

$user = new Pluf_User(1); // utilisateur un
$monde = new Monde(3); // on prend le monde 3
Pluf_RowPermission:add($user, $monde, 'Monde.detruire_monde'); 

Maintenant, c’est sympa :

// $user n'a pas la permission sur tous les mondes
assert(false, $user->hasPerm('Monde.detruire_monde'));
// $user peut détruire le monde 3
$monde = new Monde(3);
assert(true, $user->hasPerm('Monde.detruire_monde', $monde));
// mais pas le monde 2
$monde2 = new Monde(2);
assert(false, $user->hasPerm('Monde.detruire_monde', $monde2));

Toujours aussi simple, souple et efficace ! Comme ce n’est pas une fonctionnalité intéressante pour tous et que cela nécessite 1 requête SQL supplémentaire quand on va chercher les permissions de l’utilisateur, il faut l’activer dans le fichier de configuration avec la clef ‘pluf_use_rowpermission’ mise à true.

$cfg['pluf_use_rowpermission'] = true;

Et pour ceux qui se posent la question, oui c’est pour permettre de donner des droits à un auteur sur un site particulier et pas un autre dans Plume 2.

Un système de blog avec Pluf

The 2008-01-21 at 10:22 by Loïc d'Anterroches filed under Pluf - Framework en PHP5.

Je suis face à un dilemne. Je dois mettre en place un blog. Mon problème est de savoir quel système utiliser. Aujourd’hui on ne peut pas ne pas ignorer WordPress ou DotClear.

Mais je me trouve alors avec les problèmes suivants :

  • WordPress n’a pas un historique très flatteur au niveau de la gestion de la sécurité.
  • WordPress n’a pas de filtre anti-spam de qualité et c’est voulu pour que les gens utilisent le système Akismet qui est un service proposé par les mainteneurs de WordPress.
  • La qualité du code de WordPress laisse à désirer et donc pour quelqu’un qui aime mettre les mains dedans, ce n’est pas très sympa.
  • DotClear n’est pas au niveau de l’annonce. Annoncé comme le meilleur système de blog disponible, la version 2 a, il me semble, redoutablement souffert du changement d’activité du créateur. Elle est toujours en béta depuis très, trop, longtemps. Il semble que cela va changer pour 2008, mais connaissant la manière dont se développe un projet de logiciel libre, l’assurance n’existe pas.
  • Je veux cette année sortir la version 2 de Plume CMS, cette version sera basée sur Pluf.

Je pense donc créer un système de blog très simple avec Pluf. Le but sera d’être vraiment élégant et flexible pour pouvoir intégré ensuite ce blog dans Plume CMS 2. La partie brèves de Plume sera alors gérée par l’application blog.

Pouvoir à la fois gérer des articles et des brèves est une force de Plume. Cela permet d’avoir pour le site d’une entreprise la possibilité d’avoir un fil de nouvelles ainsi que les pages institutionnelles. Cette approche me permettrait donc de garder cela. L’autre point positif très important, c’est que cela me permet de commencer doucement le codage de Plume 2, c’est en effet très important d’avoir vite du code qui fonctionne et de pouvoir vite le mettre à l’épreuve du feu. Si on ne fait pas cela, on arrive vite à rester dans les specs et ne jamais avoir quelque chose de fonctionnel au final.

Je me donne 10h pour coder un système de blog complet avec Pluf (notez que j’ai réussi à avoir le domaine pluf.org pour le projet, cool non?), je vous tiendrai au courant.

Ajout d'un système de migrations pour Pluf

The 2008-01-03 at 20:52 by Loïc d'Anterroches filed under Pluf - Framework en PHP5.

Si vous écrivez une application avec Pluf, il arrivera un moment où la mise à jour de votre code impliquera des changements sur votre base de données (ajout/suppresion de tables ou champs, etc.) ou une modification des fichiers dans votre espace de stockage. Jusqu’à présent avec Pluf vous deviez développer votre propre solution "ad-hoc", soyez heureux, avec la révision 124 du code, un système simple et performant est maintenant disponible.

Le principe est inspiré de Ruby On Rails. La seule nécessité est l’ajout d’une table schema_info qui contient tout simplement pour chaque application, la version actuelle du schema. Ensuite, il suffit de créer une série de scripts de migration pour aller d’une version à une autre, aussi bien en upgrade qu’en downgrade (si quelqu’un peut me donner une bonne traduction française de ces deux termes je suis preneur) et le système de migration s’occupera du reste.

Par exemple, voici le code d’installation de Pluf. Vous pouvez voir l’installation et la suppression des tables. Le script de migration s’utilise très simplement. Par exemple :

$ php migrate.php --conf=/fichier/de/conf.php --app=Pluf --version=1

Cela passe l’application Pluf configurée avec le fichier /fichier/de/conf.php en version 1. Ou encore :

$ php migrate.php --conf=/fichier/de/conf.php -a

Passe toutes les applications définies dans le fichier de configuration dans la version la plus récente.

Avec ce système, si vous avez fait correctement vos fonctions de migration, vous pouvez tranquillement mettre à jour votre site sans vous poser de questions.

Note : Je pense faire migration particulière avec comme nom Setup pour permettre l’installation et la suppression d’une application.

Afficher des équations latex dans une page web avec texvc

The 2007-12-04 at 15:01 by Loïc d'Anterroches filed under Pluf - Framework en PHP5.

Pour mon système de gestion de conférences, je me trouve avec le besoin d’afficher des équations dans des pages web. En effet, il faut permettre aux auteurs d’articles de présenter leur travail de la meilleure façon qu’il soit. Dans mon précédent travail, j’avais fait l’installation de MediaWiki avec le support des équations, donc je savais que c’était faisable.

J’ai donc regardé le support de texvc pour mon application et que je pourrais bien reprendre le code de MediaWiki pour mon application. Je n’aime pas trop faire cela, car cela me force à mettre un énorme bloque de commentaire dans mon code avec toutes les informations nécessaires pour tracer l’origine du code et la licence, mais si cela peut économiser quelques heures de travail…

Le code pour le support des équations dans MediaWiki, le voici. Incompréhensible, effectivement.

Par contre, quand on lit la définition de l’interface de texvc, on constate que là, c’est un programme simple et efficace.

Conclusion ? Pluf propose maintenant une class pour faire l’interface avec texvc, nettement plus simple à utiliser.

Mélanger PEAR et Pluf

The 2007-11-25 at 16:39 by Loïc d'Anterroches filed under Pluf - Framework en PHP5.

Vous connaissez la règle de base du développement logiciel : Ne pas réinventer la roue.

Grosso modo, si vous pouvez utiliser un système déjà existant et de qualité, c’est le mieux. La qualité des bibliothèques disponibles via le projet PEAR n’est pas égale. Il en existe d’excellentes, d’autres plutôt médiocres. Une de qualité est Mail et Mail_mime pour envoyer des emails.

J’ai donc décider de réécrire Pluf_Mail pour profiter de cette bibliothèque. Par contre, PEAR n’a pas complètement migré vers PHP5, ce qui donne des erreurs du type E_STRICT et comme je code avec E_ALL, cela veut dire que mon code s’arrête sur ces erreurs.

La solution pour ne pas avoir à changer ma gestion des erreurs fut de ne pas considérer les erreurs E_STRICT venant de PEAR via mon propre gestionnaire d’erreurs. Voici le début, simplifié, du code :

function PlufErrorHandler($code, $string, $file, $line) 
{ 
    if (E_STRICT == $code && 
        0 === strpos($file, '/usr/share/php/')) {
        return;
    }
    ... ici la suite
}

En gros, si j’ai une erreur E_STRICT et que le fichier vient de là où est PEAR, je laisse couler… simple et élégant, car les erreurs E_STRICT de Pluf seront bien affichées.

Mise à jour du site de Pluf

The 2007-11-23 at 10:37 by Loïc d'Anterroches filed under Pluf - Framework en PHP5.

Pour vous faciliter le suivi du développement de Pluf, j’ai mis en place une liste des changements et tous mes écrits sur le sujet sont maintenant dans la catégorie Pluf.

N’hésitez pas à me contacter si vous avez des suggestions pour améliorer le tout.

Next Page


Logo of Plume CMS