Pomme, poire & electro

Aller au contenu | Aller au menu | Aller à la recherche

jeudi, avril 5 2007

Les sites tout nus

Aujourd'hui c'est la seconde édition du CSS naked day, et dans ce cadre, ce ne sera pas ce blog qui va être dénudé mais quelques sites commerciaux sur lesquels je travaille à savoir :

Pour le fun...

Je ne suis pas un parfait webdesigner, donc il reste encore quelques styles inline mais j'ai trouvé intéressant de mettre autre chose que des blogs dans cette manifestation.

lundi, mars 19 2007

MACOS 10.4.9 a cassé votre ordinateur ? pas de panique !

Quelle honte ! Vous êtes en train de vous échiner à chercher une solution sur le web depuis le pc de votre coloc, qui lui jubile face à toute ces années où vous avez fait le beau à chaque fois qu'il faisait une réinstall de windows XP. Votre mac est bloqué, ce qui s'appelle bloqué. Impossible de booter depuis cette satanée mise à jour 10.4.9, pas même en mode single user, pas même depuis un lecteur externe, la cata quoi !

ça faisait un moment qu'apple n'en avait pas fait une aussi belle. Mais rappelez-vous la 10.3.1 qui détruisait les disques firewire et leur contenu, la mise à jour itunes qui faisait disparaitre la bibliothèque !

J'étais jusqu'à maintenant passé entre les gouttes, mais cette fois-ci je me suis fait bien peur, j'en ai même travaillé le dimanche (dire à mes clients le lundi "désolé mon ordi est en rade", ces clients à qui je clame furieusement qu'il faut du mac pour travailler, aurait fait beaucoup de mal à mon ego).

Mais voilà, victoire, aujourd'hui la bête se porte comme un charme, et voici comment faire :

  • Rendez-vous avec votre machine chez le voisin du premier qui, oh bonheur, possède un macintel.
  • Téléchargez sur le site d'apple la mise à jour 10.4.9 combo sur le macintel du voisin
  • Branchez-y votre machine en mode target (T au démarrage) et installez la mise à jour combo.
  • Ejectez, redémarrez, souriez

Enfin je ne saurais que trop vous recommander d'installer et utiliser régulièrement applejack qui permet de nettoyer les caches, les disques et réparer les autorisations en mode singluser (pomme-S au démarrage). C'est notamment un outil à utiliser avant et après chaque mise à jour Apple.

mercredi, janvier 24 2007

Blague de mac-user

windows XP

Spéciale dédicace à tous ceux pour qui l'informatique est une souffrance...

jeudi, janvier 18 2007

Parlons d'autre choses

Voilà un peu de nourriture à troll :

Je ne suis pas seul à vociférer contre Internet Explorer. Ce qui me fait encore plus plaisir, c'est que la nouvelle mouture donne matière à switcher vers Firefox (d'après des témoignages de proches dans la vraie vie)...

Vista aussi, donne envie de switcher !

Les grands esprits se recontrent (non je ne parle pas du livre) mais des expressions qui naissent ici et là aussi, et chez moi, sans consultation préalable.

Ceci dit il en reste qui font pire que moi en matière d'intégrisme facilitateur.

Bon ,maintenant, parlons d'autre chose...

Le site artimots est en ligne, tourne sous symfony (mon impression reste mitigée, mais c'est du au fait que la 1.0 n'est pas encore dans les bacs en stable, et que j'ai beaucoup travaillé avec les composant PEAR, donc que j'ai beaucoup de librairies maison qui me facilitent la tâche). Et Pascal, initiateur de ce site et béotien du web, s'éclate sur son blog.

Allez encore une : connaissez-vous la langue xyloglotte ?

vendredi, janvier 12 2007

Nick, Eude, et Effe

Je vous fait par d'une action sympathique, à laquelle je participerai avec bonheur, qui m'a été transmise par email

Le 1er février 2007, dans toute la France :

Participez à la plus grande mobilisation des citoyens contre le Changement Climatique !

L'Alliance pour la Planète (groupement national d'association environnementales) lance un appel simple à tous les citoyens, 5 minutes de répit pour la planète : tout le monde éteint ses veilles et lumières le 1er février 2007 entre 19h55 et 20h00. Il ne s'agit pas d'économiser 5 minutes d'électricité uniquement ce jour-là, mais d'attirer l'attention des citoyens, des médias et des décideurs sur le gaspillage d'énergie et l'urgence de passer à l'action !

5 minutes de répit pour la planète : ça ne prend pas longtemps, ça ne coûte rien, et ça montrera aux candidats à la Présidentielle que le changement climatique est un sujet qui doit peser dans le débat politique.

Pourquoi le 1er février ? Ce jour là sortira, à Paris, le nouveau rapport du groupe d'experts climatiques des Nations Unies. Cet événement aura lieu en France : il ne faut pas laisser passer cette occasion de braquer les projecteurs sur l'urgence de la situation climatique mondiale.

Si nous y participons tous, cette action aura un réel poids médiatique et politique, moins de trois mois avant l'élection présidentielle!

Faites circuler au maximum cet appel autour de vous et dans tous vos réseaux ! Faites-le aussi apparaître sur votre site Internet et dans vos news letters.

Contact/ information : Cyrielle, Les Amis de la Terre : 01 48 51 18 95.

Le talent d'humoriste qui sommeille en moi me fait vous dire qu'il faudra bien penser à charger vos portables et GSM avant cet événement jovial et apocalyptique...

NPLB : Munissez-vous d'une bougie et d'une montre. Appuyez sur le gros bouton rouge dans le placard à droite en entrant. A 20h appuyez sur le bouton vert situé au-dessus du bouton rouge.

jeudi, janvier 11 2007

Introducing modalBox

I discovered and really really liked lightbox v2. It's so elegant inside and outside, useful and gives another dimension to any photo album.

But that was not enough, I was looking for something to make modal boxes, and googling made me discover some interesting stuff :

  • leightbox which can embed divs instead of images.
  • lighbox gone wild which shows a modal window dynamically loaded with an ajax request

Unfortunately these scripts are both based on lightbox V1 which is far less sexy than v2.

So I've started from v2 to make modalBox. I've inspired as well from the reflection.js script for additional parameters using class name. The result is an unobstrusive, elegant ajax call.

How it works

Setup and use is quite similar to lightbox v2, let's just see how it is...

Setup

Once you've downloaded the zip file, put the following files somewhere in your web server that can be accessed by client :

  • modalbox.js
  • modalbox.css

Additionally you will need scriptaculous.js (which embeds the needed prototype.js library)

Add the following in your main html page :

 geshi html4
      <script type="text/javascript" src="path/to/prototype.js"></script>
      <script type="text/javascript" src="path/to/modalbox.js"></script>
      <script type="text/javascript" src="path/to/scriptaculous.js?load=effects"></script>

That's it !

Now whenever you want to show up the url /box.php in a modal window just include the following link somwhere on your page :

 geshi html4
<a href="/box.php" rel="modalbox">Show me the box !</a>

Additional parameters : window size and resize speed

In lightbox.js the window size fits the image, but if you embed some html which has no specific size you must specify a block size, in order to do this just add some CSS class. So to show up our /box.php in a 600x300 modal window, this is how to do :

 geshi html4
<a href="/box.php" rel="modalbox" class="blocksize_600x300">Show me the box !</a>

If you want to make the resize animation, just add a resizeSpeed_* class (1 = very slow, 10 = very fast):

 geshi html4
<a href="/box.php" rel="modalbox" class="blocksize_600x300 resizeSpeed_2">Show me the box (slowly) !</a>

Voilà !

Example

I've not setup an example here but you can check one of the sites I'm working on as an example : southomes.com (click the link labelled 'email tracking/RSS'). You can try it also without javascript to check it's still working the classic way.

BTW you can buy GDW0019 or GDW0020 and become my neighboor (I'm a lonely web developer around here)

Download the modalBox here as a .zip file

Limitations

  • a 50 pixels width modal window won't work correctly. This is an event-based problem I'll try to fix, so stay tuned !

What's next ?

I've tested this on the following browsers : Firefox2 and safari2 Mac, IE6 winwin. Any feedback from other browsers would be appreciated. Anyway the big work was done by Sam Stephenson, Thomas Fuchs and Lokesh Dhakar.

I thank them soooo much for these incredible tools that make using javascript fun. So this should be compatible with most modern browsers

In a next version I'd like to be able to show up only a selected identifier from the requested page. This way it would be easy to add modal capabilities to any app without doing anything server-side.

UPDATED 2007-02-09 : some bugs fixes, updated attached libraries (prototype and scriptaculous) to latest.

lundi, janvier 8 2007

DB_DataObject / MDB2 et la casse dans le nom des champs

J'ai été confronté à un problème qui je crois n'est pas documenté dans la doc de DB_DataObject. En effet je me suis retrouvé avec une base de données MySQL dans laquelle les noms des champs étaient en camelCase. En faisant tourner DB_DataObject sur DB, celà ne pose aucun problème.

Il n'en est pas de même pour MDB2. En effet ce dernier pour des soucis de portabilité n'utilise que des champs en minuscule. Sans en modifier la configuration le remplissage de l'objet DB_DataObject ne se fait donc pas pour les champs contenant des majuscules. Heureusement DB_DataObject permet de modifier de façon globale la configuration de MDB2, grâce à la méthode PEAR::getStaticProperty, comme ceci :

// Configuration de DB_DataObject. Attention a bien recuperer une reference et pas une copie du tableau renvoye par 
// PEAR::getStaticProperty
 
$options = & PEAR :: getStaticProperty('DB_DataObject', 'options');
$options = array ('database' => 'mysql://'.$cfg['db']['user'].':'.$cfg['db']['password'].'@'.$cfg['db']['host'].'/'.$cfg['db']['db'], 
'generator_no_ini'=>true,
'schema_location' => APP_ROOT.'helpers/includes/DOclasses/', 
'class_location' => APP_ROOT.'helpers/includes/DOclasses/', 
'require_prefix' => 'DataObjects/', 
'class_prefix' => 'DataObjects_', 
'db_driver'=>'MDB2'
);
// Configuration de MDB2. Cette facon de configurer MDB2 est propre à DB_DataObject 
require_once ("MDB2.php");// Pour initialiser les constantes MDB2_PORTABILITY_*
$db_options = & PEAR::getStaticProperty('MDB2','options');
$db_options['portability']=MDB2_PORTABILITY_ALL ^ MDB2_PORTABILITY_FIX_CASE;// Tout sauf passage en minuscule pour
                                                                                        // les noms des champs

Voilà, si vous rencontrez d'autres problèmes vous pouvez jeter un oeil aux différentes constantes concernant la portabilité dans /repertoire/pear/MDB2.php

P*** d'OS de m*** !

Je me délecte souvent à voir les débutants en informatique parler à leur ordinateur de façon assez véhémente. En ma qualité d'ours (pour ne pas dire autiste parce que faut pas exagérer) je pratique peu cette discipline, sauf peut-être quand un site est planté et que c'est l'heure de manger, ou d'aller chercher les enfants à l'école, mais je n'en pense pas moins.

Pour ma part, selon l'OS, ça va être, typiquement, "ta gueule" pour windows et ses multiples interventions du genre "attention votre ordinateur est en danger", ou "voulez-vous faire ceci ou celà" alors que je ne lui avait rien demandé. Pour macOS, c'est plutôt "accouche !", alors que la machine turbine au core2duo, le ballon de plage persiste et signe.

Pour Linux, ne pratiquant pas, je ne sais pas trop ce qui se dit chez les geeks ... y'aurait certainement de quoi faire de la BD tordante de rire[via]

Et vous, de quels doux noms d'oiseaux l'appelez-vous, votre machine chérie ?

PS : je viens de passer mon macbookpro à 2Go de RAM. Et manifestement je vais beaucoup moins l'insulter maintenant, tant la différence de réactivité est hallucinante.

lundi, décembre 11 2006

rendre DB_DataObject / MDB2 traversable

Voici une extension de DB_DataObject qui implémente l'interface Iterator.

Très pratique pour utiliser avec des moteurs de templates, qui possèdent quasiment tous leur "foreach".

<?php
 
class DB_DataObject_Iterator extends DB_DataObject implements Iterator {
    public function current() {
        return $this;
    }
    public function key() {
        global $_DB_DATAOBJECT;
        $result = &$_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid];
        return $result->rowCount();
    }
    public function next() {
        $this->fetch();
    }
    public function rewind() {
        global $_DB_DATAOBJECT;
        $result = &$_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid];
        if(!$result) return false;
        $result->seek();
        return $this->fetch();
    }
    public function valid() {
        global $_DB_DATAOBJECT;
        if (empty($_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid]) || 
            !is_object($result = &$_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid])) 
        {
            return false;
        }
        return true;
    }
}

Ne fonctionne qu'avec MDB2 (doit pouvoir être adapté à DB) et bien sûr nécessite PHP5, l'interface Iterator faisant partie des SPL.

vendredi, novembre 24 2006

traduction automatique, pas d'API, tant pis !

Je suis parti en quête d'une API publique pour proposer des champs multilingue avec traduction auto dans les backoffice que je développe. Après plusieurs messages sur plusieurs forums, il semble ne pas en exister. C'est assez étonnant car quand on voit les services que propose google notamment pour la carto on pourrait se dire que ce ne serait pas la mer à boire pour eux de proposer ça.

Je me suis donc fait un "extracteur de traductions" qui va chercher les infos dans le HTML. En espérant que les sites qui proposent ce service ne fermeront pas leur porte à ce genre de script, je vous en fais tout de même part. Si vous vous sentez le coeur de l'améliorer, faites-m'en part j'en serais ravi, et aussi si vous écrivez des drivers (pour le moment google et altavista) aussi.

Désolé pour la documentation absente mais cet extracteur est somme toute assez basique.

Dépendances : PEAR::HTTP_Request et prototype.js

A télécharger ici

samedi, octobre 28 2006

Changement de politique face à l'invasion MSIE

Je hais Explorer, comme beaucoup de gens qui font le même métier que moi (encore que certains ont l'air de le défendre, ou de ne pas apprécier ce genre d'humour, enfin je ne sais pas trop), je perds beaucoup de temps à rendre les sites compatibles IE, du temps que je pourrais plutôt passer à améliorer mon travail (ou à aller ramasser des champignons, par exemple).

J'avais mis depuis quelques mois une protection par .htaccess empêchant IE d'afficher ce blog, je viens de changer de formule, histoire d'institutionnaliser la chose, j'ai opté pour la méthode 3 d'Explorer Destroyer.

J'espère juste ne pas être visité par des paranos qui désactivent le javascript sur leur IE.... Explorer Destroyer

MAJ : et voilà, ça me fout en pétard ! ce matin je regarde mes stats et qu'est-ce que je vois ?

statistiques polluées

Pourquoi les spammeurs utilisent systématiquement une identité IE ? Mon avis personnel, c'est que ce sont des machines infectées, qui se font commander l'IE pour aller polluer la toile. Si pour les commentaires, il y a Spamplemousse qui marche très bien, que faire pour ne pas se faire polluer les statistiques ? que de bande passante gaspillée. En outre je ne comprends toujours pas pourquoi je ne reçois que des commentaires critiquant mon comportement vis-à-vis de ce navigateur qui pour moi est une réelle problématique, aussi bien pour ses utilisateurs, abusés (sans le savoir), que pour les créatifs qui doivent se plier à ses règles et gommer ses tares.

Peut-être simplement parce que ce système qui génère tant de travail débile et de maintenance inutile est générateur d'emplois et de croissance ?

EDIT : pour le spamming par referer, voici un .htaccess qui va bien contre la co**erie humaine.

lundi, octobre 16 2006

On peut ne pas aimer le mac...

[via]

Mais faire preuve d'autant de mauvaise foi, c'est quand même très fort de café.

dimanche, octobre 8 2006

xdebug, macosX.4 et MAMP 1.3.1

Vous avez monté une application web que vous utilisez régulièrement, et vous souhaitez rechercher un moyen de l'optimiser, ou vous avez besoin d'un outil de profiling dans le cadre de votre développement PHP ? Vous êtes sur mac osX, vous utilisez MAMP (1.3.1). Moi aussi !!

Je me suis donc décidé à voir ce que donne xdebug qui semble être l'outil incontournable pour accomplir cette tâche. J'ai rencontré quelques obstacles pour arriver à mes fins, qui justifient je pense l'écriture de ce billet.

Installer xdebug

Il n'existe pas de version précompilée de Xdebug pour mac, qui plus est la compilation dépend de la version du moteur Zend utilisé dans votre environnement. Donc, une compilation est nécessaire. Le problème avec MAMP, c'est que les librairies C en sont absentes, ce qui rend toute compilation de module PHP impossible.

Il faut donc, dans un premier temps, récupérer une distribution de php avec le même moteur Zend que la version de MAMP incluant les librairies (à savoir 20050922). Tout ça uniquement pour compiler le module...

Le package d'entropy étant passé en php 5.2, je me suis rabattu sur une autre solution (plus simple, voir note de bas de page)

Pour ce faire j'ai opté pour le package php de Marc Liyanage (ceux qui sont sur osX depuis le début doivent connaitre car il a été le premier à proposer des packages d'installation apache/php/mysql pour osX, qui soient à la portée d'un développeur web de base comme moi).

Le package php 5.1.6 se trouve ici. Récupérez-le, installez-le (c'est un .pkg). Toute l'installation est placée dans le dossier /usr/local/php5/. La version PHP de MAMP est 5.1.4, mais le moteur Zend est le même,c'est ce qui compte.

Cette fois on a les librairies C (dans le dossier include).

Allons nous placer dans une fenêtre terminal.

A savoir, le module php de marc liyanage a effectué une installation des binaires en root/wheel. Alors ceux de MAMP vous appartiennent. Il va donc falloir compiler le module en tant que root.

Pour ce faire, et comme je suis un partisan du moindre effort (il faut déjà en faire assez) nous allons utiliser le gestionnaire de packages PECL (celui du package PHP de Marc Liyanage, pas celui de MAMP !). comme ceci :

macbookpro:~/ moi$ sudo /usr/local/php5/bin/pecl install xdebug

après quelques dizaines de secondes, le téléchargement des source et la compilation sont effectués. le nouveau module a été copié dans /usr/local/php5/lib/php/extensions/no-debug-non-zts-20050922 . Il va falloir, d'une part basculer les droits pour coller avec ceux de MAMP, puis déplacer le module dans le dossier des extensions Zend de MAMP :

sudo chown moi /usr/local/php5/lib/php/extensions/no-debug-non-zts-20050922/xdebug.so
sudo chgrp admin /usr/local/php5/lib/php/extensions/no-debug-non-zts-20050922/xdebug.so
cp /usr/local/php5/lib/php/extensions/no-debug-non-zts-20050922/xdebug.so /Applications/MAMP/bin/php5/lib/php/extensions/no-debug-non-zts-20050922/xdebug.so

Ne reste plus qu'à ajouter une ligne à notre php.ini :

echo zend_extension=/Applications/MAMP/bin/php5/lib/php/extensions/no-debug-non-zts-20050922/xdebug.so >> /Applications/MAMP/conf/php5/php.ini

Et redémarrer les serveurs depuis l'interface MAMP. Il ne vous reste plus qu'à vérifier que le module est bien chargé, en allant consulter le phpinfo(); (si vous lisez cet article, vous savez faire, non ?...)

Premières utilisations

On peut déjà utiliser Xdebug directement dans notre code PHP. Le module xdebug.so ajoute quelques fonctions PHP (consultez la liste complète dans la documentation de xdebug). Premier exemple de base, remplacer le gestionnaire d'erreurs de PHP par celui de Xdebug :

<?php
xdebug_enable();
fonction_a_la_con_qu_existe_pas();
?>

Allez voir ce que ça donne :

Wowo que c 'est bô !!! L'intérêt semble limité pour un simple appel de fonction, mais la pile de traçage devient vite très intéressante lorsque l'on se retrouve à gérer des erreurs dans une imbrication multiple d'objets.

Je vous invite, à partir de ce point, à explorer les différentes fonctions xdebug, dans la doc correspondant (voir lien plus haut). Attention la version 1.3 et la version 2 (celle qu'on a installé) fonctionnent tout à fait différemment.

En tout cas, le top avec xdebug, c'est d'utiliser une interface graphique pour profiler son application. Comme souvent sur mac, on est à la traine et il faut jouer des coudes pour trouver ce dont on a besoin. Heureusement que cet OS est le plus agréable du monde, ça fait oublier ces petits désagréments ;). Heureusement il y a Fink grâce auquel nous allons pouvoir installer Kcachegrind....

Installation de Kcachegrind

bas débit s'abstenir !

Pour installer Kcachegrind sur mac osX, il faut également récupérer un paquet de paquets liés à l'environnement graphique KDE. La solution la plus simple pour ne pas s'empêtrer dans les dépendances, est de laisser faire Fink. Il saura installer tout ce dont on aura besoin pour faire tourner la bête. Mais avant d'installer Fink, assure-vous d'avoir installé :

  • Les Developer Tools (Fink a besoin de gcc entre autres)
  • X11 (KDE tourne sur un moteur de ce type)

Ensuite, récupérez l'installeur de fink ici. L'installation se fait classiquement par un .pkg. L'installeur crée un répertoire sw en racine de votre disque système, tout ce que fink installera, ce sera dans ce dossier. Si vous êtes habitué à apt-get, pear, pecl ou dselect, sachez que fink est un gestionnaire de packages au fonctionnement similaire à ceux-ci, mais il est spécialisé dans le port d'application unix sur mac. Dans le même genre il existe Darwinports. Je n'ai pas testé, mais je pense que si les packages KDE sont dispo sur darwinports on doit arriver au même résultat.

Passons au rapatriement de kacachegrind et toute la cohorte de packages (140 pour moi) nécessaires à son bon fonctionnement. Je n'ai pas compté mais on doit pas être loin du gigaoctet, donc faites chauffer les modems ! D'abord, il faut configurer, et tant qu'à faire, mettre à jour Fink. Kcachegrind n'étant disponible qu'en statut beta, il faut indiquer dans la config que l'on souhaite pouvoir utiliser des packages en beta.

Retour dans le terminal :

vi /sw/etc/fink.conf

Et effectuez la modification suivante :

# Avant
Trees: local/main stable/main stable/crypto
# Après
Trees: local/main stable/main stable/crypto unstable/crypto unstable/main

voilà maintenant mise à jour de Fink et réindexation des packages :

fink selfupdate; fink index; fink scanpackages

Allez boire un café.... ... ... voilà, la journée doit être pas loin de se terminer pour lancer ce qui suit, téléchargement et compilation qui vont prendre... du temps :

sudo fink install kcachegrind

Répondez tout de même aux quelques questions (laissez les valeurs par défaut par exemple, ça suffit) pour que l'opération démarre. .... .... Le lendemain matin... Je vous souhaite de tout coeur qu'aucune erreur n'apparaisse dans votre terminal, en principe tout a bien du se passer, kcachegrind est prêt à être lancé. Il se trouve dans /sw/bin/kcachegrind.

Pour qu'il fonctionne correctement, il doit être lancé depuis X11, par le terminal. Vous pouvez ajouter le chemin de l'exécutable au menu Applications, c'est fait pour ça.

Vous devez obtenir quelque chose comme ça :

Vous savez quoi : on y est presque ! Ne reste plus qu'à configurer xdebug (on retourne dans le php.ini s'il vous plait)

xdebug.profiler_enable="1"
xdebug.profiler_output_dir="/Applications/MAMP/tmp/xdebug/"

Les valeur "xdebug.trace_output_dir" et "xdebug.profiler_output_dir" sont modifiables par l'emplacement où vous souhaiter enregistrer les fichiers de profiling.

Relancez le serveur apache

Lancez une page web PHP de votre serveur local, un fichier de profiling est créé à l'endroit que vous souhaitez. Il ne vous reste plus qu'à ouvrir ce fichier (extension .out) dans kcachegrind. Excellent ! Ci-dessous un profil d'un des sites que j'ai monté. Le retour visuel est immédiat et sans appel : mon système d'internationalisation, utilisant PEAR::XML_Serializer, a sérieusement besoin d'un système de cache :

Amusez-vous bien, n'hésitez pas à émettre remarques ou suggestions sur ce billet.


Voici la liste des articles écrits ça et là, qui m'ont aidé à monter cet environnement.

EDIT : si vous êtes sur php 5.2 un brave ch'ti gars de chez Komodo propose les binaires pour Linux/macosX/Win32 par ici :

PHP 5.2 / xdebug builds

EDIT2 : souhaitant installer PHPunit 3, qui demande xDebug version 2, je me suis retrouvé coincé (après un changement de machine) car le package d'entropy est passé en php 5.2, et toujours pas MAMP (ben ouais j'ai pas upgradé). Donc là, le seul moeyn reste l'extension compilée de komodo. Elle est récupérable directement dans l'application elle-même.

mardi, octobre 3 2006

Enhancing/Extending PEAR::DB_DataObject_FormBuilder

For the ones that use DB_DataObject_FormBuilder, it's clear that this extension easily becomes one of the "must-have" in any project that need form and database. It may have some disadvantages, for example concerning the display of a select with linked values. In Symfony and Propel, and in other Frameworsk certainly, the many ones I don't know, you can implement the __toString() method, which since php5 (AFAIK) is the default method called when you try to echo and object. It's much more flexible than $fb_linkDisplayFields which show the field values separated with a coma. This can be fastly frustrating.

You can think I'm a dumb sometimes, but I took much time for me to figure out how to extend FormBuilder. Finally I found. In fact many things in OOP, (me) seem (to me) inaccessible from the first place, because the solution is sooo simple that you can turn around without seeing it. So, here it is :

require_once 'DB/DataObject/FormBuilder.php';
 
class myFB extends DB_DataObject_FormBuilder
{
  
  function DB_DataObject_FormBuilder(&$do, $options = false)
  {
    DB_DataObject_FormBuilder::DB_DataObject_FormBuilder(&$do, $options = false);
  }
  
  function &create(&$do, $options = false, $driver = 'QuickForm', $mainClass = 'myFB')
  {
 
    $fb = DB_DataObject_FormBuilder::create($do,$options,$driver,$mainClass);
 
    if(PEAR::isError($fb)) {
      die ($fb->getMessage());
    }
    return $fb;
  }
  
  function getDataObjectString(&$do, $displayFields = false, $linkDisplayLevel = null, $level = 1) {
    if($this->isCallableAndExists(array($do,'__toString'))) {
      return $do->__toString();
    } else {
      return parent::getDataObjectString($do, $displayFields, $linkDisplayLevel, $level);
    }
  }
}

Voilà, I just had to overload the create method, to have an extensible FormBuilder. Here I just add the ability tu use __toString() on the linked object, if it's implemented.

Obviously to make a new form, you have to use MyFB::create($dataobj); instead of DB_DataObject_FormBuilder::create($dataobj);

Améliorer/Etendre DB_DataObject_FormBuilder

Pour ceux qui utilisent DB_DataObject_FormBuilder, il faut bien avouer que ça peut devenir vite une charnière inévitable dans tout projet où il y a du formulaire et de la bdd. Il peut présenter cependant quelques défauts, notamment en ce qui concerne l'affichage de select avec des références étrangères. Chez Symfony et Propel, et chez d'autres Frameworsk certainement, que je ne connais pas, il est possible d'implémenter le fonction __toString(), qui depuis php5 (me semble-t-il) est la méthode appelée par défaut lorsque l'on tente de faire un echo d'un objet. C'est beaucoup plus souple que le $fb_linkDisplayFields qui sépare simplement les champs souhaités par une virgule. On se retrouvé vite limité.

ça peut paraitre c*n, mais j'ai mis un moment à me demander par quel bout prendre formBuilder pour l'étendre. Finalement, j'ai franchi le cap. En fait beaucoup de choses dans la prog objet, (me) semblent inaccessibles d'un premier abord parce que la solution est tellement simple qu'on passe à côté. Donc voilà, ce que ça donne :

require_once 'DB/DataObject/FormBuilder.php';
 
class myFB extends DB_DataObject_FormBuilder
{
  
  function DB_DataObject_FormBuilder(&$do, $options = false)
  {
    DB_DataObject_FormBuilder::DB_DataObject_FormBuilder(&$do, $options = false);
  }
  
  function &create(&$do, $options = false, $driver = 'QuickForm', $mainClass = 'myFB')
  {
 
    $fb = DB_DataObject_FormBuilder::create($do,$options,$driver,$mainClass);
 
    if(PEAR::isError($fb)) {
      die ($fb->getMessage());
    }
    return $fb;
  }
  
  function getDataObjectString(&$do, $displayFields = false, $linkDisplayLevel = null, $level = 1) {
    if($this->isCallableAndExists(array($do,'__toString'))) {
      return $do->__toString();
    } else {
      return parent::getDataObjectString($do, $displayFields, $linkDisplayLevel, $level);
    }
  }
}

Voilà, il suffisait juste de surcharger la méthode create, pour ensuite avoir un Formbuilder extensible à souhait. Ici simplement j'ajoute la possibilite d'invoquer __toString() sur l'objet lié, si la fonction est implémentée.

Evidemment lorsque l'on crée un nouveau formulaire il faut utiliser MyFB::create($dataobj); au lieu de DB_DataObject_FormBuilder::create($dataobj);

jeudi, septembre 21 2006

Suppression récursive en ligne de commande

J'ai pris la sale habitude de travailler sur certains projets que j'héberge pendant la période de développement, direct sur le serveur (local), en AFP. Je ne sais pas si c'est textmate ou l'AFP ou les deux, en tout cas cette méthode de travail de barbare (plutôt que de faire des commit sur mon SVN, ce qui serait tout de même plus sérieux) a foutu le bordel (enregistrement des deux fourchettes de fichier en deux fichiers, dont un commençant par '._').

Donc au bout de quelques temps je me dis "Tiens, je vais tout de même faire un petit commit, et on va essayer de repartir ans le droit chemin". Oui mais voilà, svn status me sort une liste grande comme le bras (et c'est peu dire) avec tous ces nouveaux fichiers. Le bordel quoi ! Heureusement mon pote Pascal qui assure bien en ligne de commande m'aiguille sur une méthode pour supprimer d'un coup d'un seul tous ces fichiers '._' de mon arborescence. Voilà ce que ça dit :

find ./ -name "._*" | xargs rm -R -v

Sympat non ?

EDIT : dans la série des petites bricoles qui facilitent la vie, Pascal m'a fait passer une page bourrée de scripts monolignes en perl, c'est assez puissant - Ecrire un programme d'une ligne en Perl

lundi, septembre 4 2006

été chaud. Les poires se branchent

J'ai passé un été mouvementé, surtout au niveau des doigts, qui n'ont pas arrêté de courir sur le clavier. Au fur et à mesure des projets que j'attaque, je garde la même trame, toujours à base de briques PEAR pour la plupart et certaines classes commencent à murir.

Celle dont je voudrais vous parler, c'est une extension de DB_DataObject, celle que j'utilise sur tous les projets. Cette classe a commencé à prendre du poids au fur et à mesure que je lui ajoutais des fonctionnalités (upload et redimensionnement de photos, internationalisation, gestion de propriétaire ...). Donc j'ai voulu faire quelque chose qui puisse ne charger que ce dont a besoin l'objet au moment où il est fabriqué.

En fin de compte, j'arrive à une structure de 'plugins' pour mes objets d'accès aux données, et ma foi, ça permet de capitaliser le code de façon assez intéressante. Le résultat obtenu fait vaguement penser au pattern decorator. Voici le principe:

  • La classe (Mdo) étend DB_DataObject, et les objets générés étendent cette classe Mdo.
<?php
class Mdo extends DB_DataObject
{
}

Dans cette classe, on crée quelques méthodes pour gérer le chargement des plugins. Voici un extrait :

      /**
       * Charge les plugins. Cette methode est appelee a la premiere invocation de _executePlugins
       * @access protected
       **/ 
	function _loadPlugins() {
		$pluginInfos=$this->getInstalledPlugins();
		foreach($pluginInfos as $aPluginInfos) {
			if(isset($this->$aPluginInfos['var'])){
				$this->_loadPlugin($aPluginInfos);
			}
		}
		$this->_pluginsLoaded = true;
	}
	/**
       * Cree une instance d'un plugin, associe a l'objet courant
	 * @access protected
	 **/
	protected function _loadPlugin($infos) {
		require_once PLUGIN_DIR.$infos['include_file'];
		$plugin = & new $infos['class_name'];
            // init va se charger de vérifier que les infos prodiguées sont correctes pour le fonctionnement du plugin
            if(!$plugin->init($this)) {
                 throw new Exception('Les paramètres envoyés au plugin ne sont pas valides');
            }
  		$this->_plugins[$infos['name']] = & $plugin;
      	Log::info('Chargement du plugin '.$infos['class_name'].' depuis '.get_class($this));
	}
	
	/**
       * Renvoie un tableau avec la liste des plugins installes
       * TODO : recuperer ces informations a partir d'un fichier separe (XML ou ini)
       * Et creer une methode qui permette d'installer des plugins supplementaires
	 * @access public
       * @return array
	 **/
	public function getInstalledPlugins() {
		if(count($this->_pluginInfos)>0) {
			return $this->_pluginInfos;
		} else {
			return array(
                                                  array(  'name'=>'images',
  									'include_file'=>'Images.php',
  									'class_name'=>'DOPlugin_Images',
  									'var'=>'photoFields'
  									),
									
									
  					                      array(  'name'=>'ownership',
  									'include_file'=>'Ownership.php',
  									'class_name'=>'DOPlugin_Ownership',
  									'var'=>'ownershipFields'
  									),
									);
		}
		return array();
	}
 
	/**
       * Execute un callback sur tous les plugins. 
       * Typiquement ce sont les methodes du meme nom que celles de DB_DataObject qui sont appelees
	 * @access private
	 **/
	private function _executePlugins($callback,$params=null) {
      	if(!$this->_pluginsLoaded) {
      	    $this->_loadPlugins();
      	}	
		if(is_array($params)) {
			$params[]=&$this;
		} else {
			$params=array(&$this);
		}
				
		foreach($this->_plugins as $plugin) {
				call_user_func_array(array($plugin,$callback),$params);
		}
	}
	/**
       * Renvoie une reference à un plugin active dans l'objet en cours
	 * @access public
       *
	 **/
	function &getPlugin($pname) {
	  if(!key_exists($pname,$this->_plugins)) {
	    throw new Exception('le plugin '.$pname.' est absent de '.get_class($this));
	  } else {
	    return $this->_plugins[$pname];
	  }    
	}

Des intéressés pour la suite ?

Héberger symfony

Symfony est un excellent framework, mais il a pas mal d'exigences au niveau de l'hébergement. Après m'être cassé le nez sur plusieurs hébergeurs (il y a vraiment à boire et à manger dans les hébergeurs), dont OVH : je croyais que c'était tout bonnement impossible mais un nouvel article dans le wiki de symfony me prouve le contraire. Dommage que je ne sois pas tombé dessus la semaine dernière. En tout cas le service client a assuré et m'a remboursé l'hébergement fraichement ouvert dans la foulée. C'est de bonne guerre.

Tout ça pour dire que j'ai fini par prendre un hébergeur outre-atlantique, listé dans les hébergeurs supportant symfony, toujours sur le wiki de ce projet. J'ai donc choisi A2Hosting. Pour la bagatelle approximative de 100 euros par an, vous avez :

  • 35Go d'espace disque (oui oui je ne me trompe pas !)
  • 50Go de trafic mensuel
  • 20 adresses mail
  • 20 sous-domaines
  • 1 base de données (un peu juste mais c'est le seul point noir, si on peut appeler ça un point noir) MySQL 4.1.2
  • Une adresse IP (pour 15 dollars d'installation + 30 dollars par an)
  • PHP5
  • Une interface un peu genre plesk, mais en plus sympa
  • ... Et symfony installé par défaut

Je trouve ça plus qu'honnête, voire exceptionnel, non ?

Et cerise sur le gâteau, le service de support a l'air d'assurer grave. La preuve : hier dimanche, j'envoie un message à 13h, avec plusieurs questions concernant mon installation. Je reçois la réponse à 14h08. Je suis bluffé, je ne m'y attendais pas du tout.

En conclusion, même si ça ne fait que 24h que je suis client chez eux, je vous recommande cet hébergeur, que vous ayez besoin de symfony ou non. Ne serait-ce que pour l'espace disque colossal pour du mutualisé, et le support qui semble être l'héritier de Speedy Gonzalez.

EDIT : Maintenant il faut aussi compter avec OVH, et leur serveur dédié kimsufi, encore plus fort que free et la dedibox !

mardi, août 8 2006

Apple, retour aux sources

Grâce à l'arrivée des nouveaux Mac Pro, Apple renoue enfin avec ce qui l'avait quitté il y a si longtemps, à l'époque des 2fx : on peut avoir des configurations de follie avec le prix associé. Une petit extrait :

PS : à noter, encore plus pfff, la proposition d'échelonnement. vive ajax !

dimanche, juin 25 2006

Va y'avoir du changement ici...

Petit billet vite fait juste pour dire que je m'intéresse au framework symfony ces derniers temps, et que j'en profite pour refaire ma façade. Donc bientôt en ligne une nouvelle version de demental.info

EDIT : Faut vraiment que j'arrête de faire la grande gueule des fois, moi, quand j'ai pas le temps de faire ce que je dis...

- page 1 de 4