mardi 2 septembre 2008

He's back

Juste une note rapide pour vous informer que le geek-guitariste-procrastinateur-multiframeworkophile-lunatique-surdoué le plus attachant de la blogosphère vient de faire son come-back sur la blogoscène, et que ça c’est quand même un peu plus enthousiasmant que les annonces chromatiques de Sergey et Larry.

define:Chrome

defineChrome.png

Bon blague à part, a priori plutôt une bonne nouvelle pour le libre, les standards et le Web en général. Reste la question que soulève Daniel Glazman :

Your search engine is google, your mail is google mail, your docs are on google docs, your maps are google, the ads you see are google, your system is Android, your browser is Google Chrome. Did someone hear the word "monopoly" ?

Ça commence effectivement à sentir pas très bon le monopole. J’adore sa conclusion finale :

Let’s see it from the bright side of life: there’s a new OSS and standards-compliant browser and that’s good, and there’s a high probability Steve Ballmer is currently breaking a few chairs and it’s even better :-)

Rien à ajouter :-)

samedi 30 août 2008

Chalut

Hier matin, je m’insère comme tous les matins sur mon périphérique quotidien quand une petite boule de poil traverse juste devant moi, en faisant une pause juste devant ma trajectoire. N’allant pas vite et n’ayant personne me collant immédiatement au train, je m’arrête, active mes warnings et descend de la voiture pour voir ce qui se terre sous mon chassis, sous les invectives des autres voitures maintenant arrêtées derrière moi.

Je découvre une petite boule de poil totalement apeurée, un bébé chat d’à peine deux mois à tout casser. Je le récupère, le montre à ma poursuivante vociférante pour la faire taire et monte dans la voiture avec mon butin du moment. Je rentre chez moi, dépose la bestiole dans des mains de confiance, nourris la bête et repars derechef en direction du boulot. Le sourire aux lèvres.

perif.jpg

Bienvenue, Périf’ !

dimanche 24 août 2008

Comment faire fuir à coup sûr vos utilisateurs ?

C’est bien connu, il est déjà sufisament dur de faire (re)venir des utilisateurs sur vos services en ligne pour ne pas les faire partir à la moindre occasion. C’est pourtant ce que fait un site dédié à la guitare que j’ai tenté de consulter récemment. Connaissant les tendances dérivistes des services juridiques de certaines entités, je m’abstiendrai donc de faire un lien hypertexte direct vers ce dernier, et même de le citer textuellement[1].

Je tombe sur ce site, qui propose apparemment moult ressources sur l’instrument et qui m’intéressent potentiellement, mais au moment de consulter l’article objet de ma convoitise, on me notifie du message suivant :

registration_obligatoire.png

Jusque-là, rien de profondément choquant même si on peut imaginer que nombre d’internautes ne s’embêteront pas à créer un compte pour consulter la ressource et passeront à la concurrence[2].

Allez, je suis dans un bon jour, je demande la création d’un compte. Je me retrouve face à un formulaire assez copieux, exigeant bien entendu des informations hautement nécessaires pour consulter un tutoriel de guitare comme ma localisation géographique, mon nom de famille, ma date de naissance, sans oublier bien entendu les inévitables propositions d’abonnement à des newsletter très étroitement liées à la pratique de la guitare :

pollution.png

Sentant le SPAM arriver à grand pas, je rentre mon email suffixé pour détecter a posteriori le service à l’origine d’éventuels courriels indésirables reçus. Ben non :

wrong_email_validation.png

Vous noterez le plus fort, c’est que non seulement le service n’est pas à même de valider convenablement une adresse email (le signe + est acceptable), mais en plus on me soupçonne ouvertement de SPAM potentiel.

Normalement, à ce stade, je me casse sur Mars, comme on dit. Mais pour la beauté de l’exercice, je corrige mon adresse email, pérsévère en entrant un mot de passe et valide à nouveau le formulaire :

restricted_chars.png

Oui, cela commence à faire beaucoup. Je ne réexpliquerai pas ici pourquoi limiter les caractères dans les mots de passe est idiot, cela a déjà été fait ici-même précédemment.

Toujours dans la perspective de poursuivre cette expérience amusante, j’arrive enfin à valider le formulaire sans retours d’erreur et m’identifie donc sur le service pour consulter la ressource en question. Patatra :

abo_obligatoire.png

Non seulement la création d’un compte était obligatoire, mais maintenant il faut s’abonner (c’est à dire payer) pour consulter la ressource en question, chose qui n’avait été aucunement stipulée auparavant. Sachant bien entendu qu’à ce stade, je n’ai toujours aucune idée de la qualité des contenus proposés par le site.

Bref, je leur souhaite malgré tout un avenir comptable radieux, même si je ne peux m’empêcher de pouffer à l’idée du chiffre d’affaire généré par le se(r)vice.

Notes

[1] Mais les curieux trouveront bien entendu sans peine le site en question.

[2] Sur le Web, vous avez quasiment systématiquement un concurrent qui propose la même chose que vous gratuitement. C’est comme ça, et c’est aussi un peu pour ça que c’est chouette.

vendredi 25 juillet 2008

Partager la session utilisateur entre Flash/Flex et symfony avec AmfPHP

Pour les besoins d'un projet récent, j'ai eu besoin de valider la possibilité de gérer l'authentification et l'accès à la session symfony (côté serveur) depuis une interface générée par Adobe Flex (en Flash, donc côté client).

Pour cela, j'ai utilisé la librairie AmfPHP en version 1.9beta2, certes pas très récente mais suffisament fonctionnelle pour satisfaire à ce besoin précis. Voyons comment ça se passe concrètement. L'avantage de la démonstration ci-dessous est qu'elle ne nécessite pas d'installer Flex puisque AmfPHP fournit un navigateur de services (browser) qui nous suffira pour valider notre concept.

Installation du plugin sfGuard

Je pars du principe que tout le monde a une installation de symfony 1.1 nanti d'une application main, ainsi qu'un projet et un virtual host apache fonctionnels pointant sur local.mademo.org. Si ce n'est pas le cas, voila de quoi vous mettre à jour.

On commence par installer le plugin sfGuard, qui se chargera de la persistance des droits et permissions utilisateurs en base de données, et fournira les utilitaires d'authentification et de manipulation de la session côté serveur :

$ ./symfony plugin:install sfGuardPlugin
$ ./symfony propel-build-all
$ ./symfony cc

On charge quelques données de test dans notre base de données nouvellement mise à jour :

$ mkdir data/fixtures 
$ cp plugins/sfGuardPlugin/data/fixtures.yml.sample data/fixtures/fixtures.yml
$ ./symfony propel:data-load main

Ce jeu de données de test nous fournit par défaut un compte admin (mot de passe admin) qui nous servira à tester notre service d'authentification.

Ensuite, il nous faut modifier notre classe apps/main/lib/myUser.php gérant la session utilisateur afin qu'elle étende désormais la classe sfGuardSecurityUser, fournie par le plugin sfGuard :

<?php
// Fichier apps/main/lib/myUser.php
class myUser extends sfGuardSecurityUser
{
}

Installation et configuration d'AmfPHP

Nous allons installer la librairie AmfPHP dans le sous-répertoire web/ de notre projet[1], et aménager quelque peu notre arborescence pour accueillir les services AmfPHP :

$ cd /path/to/project
$ svn export https://amfphp.svn.sourceforge.net/svnroot/amfphp/tags/1.9beta2 web/amfphp
$ mkdir lib/amfphp-services
$ mv web/amfphp/services/amfphp lib/amfphp-services/

Ceci fait, nous allons éditer plusieurs fichiers d'amfphp afin de l'adapter à notre environnement symfony. Tout d'abord, commençons par éditer la valeur de la variable $servicesPath dans le fichier web/amfphp/globals.php :

<?php
// ...
$servicesPath = dirname(__FILE__).'/../../lib/amfphp-services/';

Enfin, il nous faut "patcher"[2] le fichier web/amfphp/core/amf/app/Filters.php, qui initialise la session PHP sans définir le nom de la session. Ici, nous utiliserons le nom de la session symfony par défaut, "symfony" (ligne 105 du fichier) :

102     //Fix for godaddy not allowing ini_get
103     $sessionName = "PHPSESSID";
104   }
105   session_name('symfony');
106   session_start();
107   $session_id = session_id();

Création d'un service permettant le partage de la session utilisateur

Voila, nous pouvons maintenant créer un service de gestion de l'authentification, que nous nommerons pompeusement UserSessionService et que nous enregistrerons dans le fichier lib/amfphp-services/UserSessionService.php :

<?php
require_once dirname(__FILE__).'/../../config/ProjectConfiguration.class.php';
 
/**
 * This class tests the symfony session within an AmfPHP context
 *
 */
class UserSessionService
{
  /**
   * Symfony context
   * @var sfContext
   */
  protected $context = null;
  
  /**
   * Symfony session
   * @var sfGuardSecurityUser
   */
  protected $user = null;
  
  /**
   * Public constructor
   *
   */
  public function __construct()
  {
    $configuration = ProjectConfiguration::getApplicationConfiguration('main', 'dev', true);
    $this->context = sfContext::createInstance($configuration);
    $this->user = $this->context->getUser();
  }
  
  /**
   * Checks wheter user is authenticated or not
   *
   * @return boolean
   */
  public function isAuthenticated()
  {
    return $this->getUser()->isAuthenticated();
  }
  
  /**
   * Authenticates user
   *
   * @param  string  $username
   * @param  string  $password
   * @return boolean True if user has been successfully authenticated
   */
  public function login($username, $password)
  {
    if ($this->isAuthenticated())
    {
      return true;
    }
    
    $user = sfGuardUserPeer::retrieveByUsername($username);
    
    if (!is_null($user) && $user->checkPassword($password))
    {
      $this->getUser()->signIn($user);
      return true;
    }
    
    return false;
  }
  
  /**
   * Signs out a user 
   *
   */
  public function logout()
  {
    return $this->getUser()->signOut();
  }
  
  /**
   * Retrieves the current symfony context
   *
   * @return sfContext
   */
  protected function getContext()
  {
    return $this->context;
  }
  
  /**
   * Retrieves the current symfony user session
   *
   * @return sfGuardSecurityUser
   */
  protected function getUser()
  {
    return $this->user;
  }
}

Pour tester notre service, utilisons le navigateur de service proposé par AmfPHP. Pour cela, il faut lancer un navigateur sur http://local.mademo.org/amfphp/browser/index.html :

Naviagateur de services AmfPHP

Via cette interface, elle même réalisée en Flex, on peut tester les méthodes publiques définies dans notre service, manipuler les arguments, et constater que nous arrivons à nous authentifier et que nous accédons bien à la même session utilisateur que dans symfony : login, logout et test du statut d'authentification.

En conclusion

On pourrait aller beaucoup plus loin dans cet exemple, en proposant par exemple une classe proxy en ActionScript 3 représentant un utilisateur du système (dans notre cas, une instance de la classe sfGuardUser), cette dernière reproduisant tout ou partie de ses méthodes et propriétés, et donc d'utiliser l'ORM Propel directement depuis Flash... Je vous laisse faire vos tests si le coeur vous en dit.

D'autre part, même si la librairie AmfPHP semble un peu passée au niveau architecture, elle reste néanmoins très efficace pour publier des services PHP dans Flash au travers du protocole AMF. J'ai eu vent d'autres librairies comme WebORB ou SabreAMF, mais je ne sais pas vraiment ce qu'elles valent... Des avis dans l'assistance ?

Notes

[1] Du coup, on expose certains scripts AmfPHP, mais la librairie n'est malheureusement que prévue pour fonctionner en ce sens...

[2] Oui, c'est terriblement crade, je ne comprend d'ailleurs pas qu'AmfPHP n'aie pas prévu ce cas de figure...

mercredi 23 juillet 2008

Mes conventions de codage...

... sont celles des projets sur lesquels je me greffe. C'est en effet pour moi une forme de respect que d'appliquer les standards de codage partagés par une communauté (ou une équipe) de développeurs : ainsi, on maximise les chances de se comprendre et on minimise les coûteuses phases de communication entre geeks introvertis[1] :p

En effet, rien de plus pénible que de reprendre le code de quelqu'un qui a pris des libertés avec des conventions établies à ce niveau, l'apothéose étant obtenue avec ce genre de code :

<?php
  class Ma_superClasse {
 
    function dire_coucou ( $popol) {
  echo 'coucou ' . $popol   . ' !' ;
}
     function DireAuRevoir($Popol )
{ print "Au revoir $Popol !";
     }
  }

Je force bien évidemment ici le trait, mais tout le monde est déjà tombé sur ce genre de code illisible, qui multiplie par 10 votre temps d'intervention sur ce dernier et divise par 1000 votre passion pour la TMA.

Bien entendu, il peut arriver de produire du code sur un projet ne nécessitant l'utilisation d'aucune brique logicielle existante. Auquel cas vous pouvez librement appliquer vos propres standards de codage, l'important étant ici qu'ils soient cohérents et constamment appliqués. S'il peuvent être ceux d'un projet open source existant reconnu, cela augmentera la sympathie potentielle à votre égard de futurs intervenants sur votre code ;)

Je noterai quand même en vrac quelques bonnes pratiques générales globalement reconnues et appréciées :

  • être explicite,
  • indenter son code,
  • documenter son code,
  • à choisir entre les deux, privilégier la lisibilité à la concision,
  • utiliser des noms de variables, de classes, de méthodes, de fonctions et d'arguments parlants,
  • utiliser des noms anglophones,
  • utiliser des motifs de conception connus.

Personnellement, j'ai mes petites préférences et tout comme Oncle Tom - qui m'a gentiment refilé cette chaîne[2] - j'ai tendance à appliquer les standards de codage de symfony, que je trouve homogènes et cohérents. Mais ce sont là bien évidemment essentiellement des questions de goûts et de couleurs.

Notes

[1] Voire les trolls genre les tabulations ça pue, vive l'indentation à trois espaces...

[2] Salopard, ça va se payer ! ;-)

dimanche 20 juillet 2008

Debug PHP facile avec Firefox, Firebug et FirePHP

Tous ceux qui ont déjà eux à batailler avec du code javascript connaissent certainement la fabuleuse extension Firebug pour Firefox. L'outil propose une console permettant d'examiner l'environnement d'exécution javascript mais aussi HTML et CSS de n'importe quelle page web.

FirePHP est une autre extension qui a pour but de proposer le même service mais pour le langage PHP. L'extension repose elle-même sur Firebug et propose, une fois installée, l'affichage dans la console des messages de debug émis depuis vos scripts PHP :

Démo FirePHP

Une fois l'extension Firefox installée, pour pouvoir envoyer un message de log dans la console depuis vos scripts, il faut utiliser une librairie spécifique PHP fournie téléchargeable depuis la page d'accueil du projet FirePHP. Cette librairie très simple est d'ailleurs documentée ici. Une fois l'archive récupérée, décompressez-la et appelez FirePHP de cette façon depuis un script PHP standard :

require_once '/path/to/firephp/lib/FirePHPCore/FirePHP.class.php';
 
$f = FirePHP::getInstance(true);
$f->fb('Hello FirePHP console', FirePHP::INFO);
$f->fb(array('hello' => 'how are you?'));
$f->fb(array('hello' => array('how', 'are', 'you')));
$f->fb(array('foo', 'bar'), 'Results', FirePHP::WARN);
 
$o = new stdClass();
$o->foo = 'foofoo';
$o->bar = 'barbar';
 
$f->fb($o);

Pour envoyer les informations de debug à la console, la librairie PHP envoie les données sérialisées au format JSON dans un entête HTTP personnalisé dédié (X-FirePHP-Data). Ainsi, aucune interférence n'est possible avec vos scripts existants, la seule condition étant bien entendu de ne pas lancer la sortie standard PHP avant que ces entêtes aient été envoyés.

Données JSON passées dans un entête dédié

En bref, un outil génialement simple et efficace.

vendredi 18 juillet 2008

Un beau geste ?

Ayant moi-même un petit bout de chou du même âge, je n'ai pu rester insensible à l'appel à donation lancé par Zack Urlocker pour le compte d'Andrei Nikitin. En effet, son fils atteint d'une grave maladie, a besoin d'une greffe très coûteuse pour survivre (plus de 150 000 dollars).

Andrii et son fils

Je relaie donc ici cet appel, en espérant participer modestement à la réunion des fonds nécessaires au financement de cette opération.

- page 1 de 68