De la regex …

… il en faut et dieu sait que c’est pas simple à utiliser quand on ne le fait que rarement.

Il arrive que dans symfony, on en ait besoin (pourtant, symfony fournit un paquet de validateurs efficaces – comme pour le mail) et quand on est pas coutumier de leur utilisation, aie aie aie !

Bref, j’ai trouvé un petit site sympathique avec plein d’exemples (des sites expliquant les regex, yen a plein mais des exemples concrets, j’ai toujours du mal à en trouver).
Je vous le fais donc partager : http://www.roscripts.com/PHP_regular_expressions_examples-136.html

Et juste pour la forme, un petit pattern qui peut servir à tester des champs avec des accents ou des ‘ç’ par exemple :

'/^[\p{L}\-\' \*]{1,255}$/'

Comment activer le ‘no_script_name’ de symfony

Afin de ne pas avoir index.php dans l’url réécrite de votre site en production, il y a deux manipulations à effectuer :

- activer le no_script_name :

.settings:
  no_script_name: on

- activer le mod_rewrite d’apache :

a2enmod rewrite
/etc/init.d/apache2 restart

N’oubliez pas non plus de modifier la configuration de votre site (/etc/apache2/conf/xxx.conf) en indiquant index.php pour l’application de base de votre site.

getParameterHolder()->set() = setParameter()

$request->getParameterHolder()->set('foo', 'bar');
// équivaut à
$request->setParameter('foo', 'bar');
$request->getParameterHolder()->get('foo');
// équivaut à
$request->getParameter('foo');

Vous pouvez passer un paramètre par défaut dans le getter si le paramètre foo n’existe pas :

$request->getParameter('foobar', 'default');

Je n’invente rien, il s’agit juste d’une astuce fournie dans le guide de symfony mais à côté de laquelle on peut passer :)

[Doctrine vs Propel] symfony 1.3 et 2.0

Une petite information que vous connaissez sans doute déjà si vous avez lu ce post sur le blog officiel : Doctrine devient l’ORM par défaut sur la version 1.3 de symfony.

Cela veut-il dire que Propel est mort chez symfony ? Non absolument pas … enfin pas tout de suite :p

Fabien Potentier nous a assuré que Propel serait toujours supporté et de la même manière pour toute la ligne 1.x mais qu’à partir de la version 1.3 (qui sortira semble-t-il en novembre), Doctrine deviendra l’ORM par défaut.

Par contre, Doctrine deviendrait pour la version 2.0 le seul et unique ORM supporté par symfony. En effet, Propel semble être un peu au point mort et sachant que Jonathan Wage fait partie de la Core Team de symfony, cela semblait logique.

Quoiqu’il en soit, la version 2.0 est encore embryonaire et ne sera pas là l’an prochain (enfin, c’est ce que j’ai ressenti des dires de Fabien).

Voilà, juste pour clarifier les choses sur ce point là :)

Bonne journée à tous !

Compte-rendu Symfony Live 2009

Plus de deux jours après la fin du Symfony Live 2009, il est temps de vous faire mon compte-rendu sur ce 1er événement dans la communauté Symfony.
Il fallait bien les deux jours de ce week-end pour se reposer de cette conférence d’une telle intensité ! En effet, pas moins de 21 conférences entre 9h00 et 19h45 (jeudi) ou 19h (vendredi) se sont tenues à la Cité Universitaire !

Je ne vais pas faire un descriptif des conférences car vous pouvez retrouver l’ensemble des présentations sous forme de PDF sur le site officiel (Day 1Day 2) et les vidéos devraient être accessibles à partir de la fin de cette semaine sur le site PHPTV.

Les différentes interventions peuvent être regroupées en plusieurs catégories :
- présentation de développement spécifique et retours d’expériences
- présentation de plugins
- nouveautés (Doctrine / sf 2.0)
- bonnes pratiques

Il va de soit que chaque conférence n’était pas forcément intéressante sur le thème (tout ce qui touche à Facebook ne me touche pas :p) mais le contenu apportait toujours au moins un petit quelque chose d’utile.

J’avoue avoir particulièrement apprécié les interventions sur les bonnes pratiques car étant assez jeune dans la communauté et sur le framework, il s’avère que je ne fais pas encore toujours ce qu’il faudrait :) De même, étant assez friand de veille technologique, les discutions autour des nouveautés à venir sur symfony et Doctrine m’ont encore plus motivées à m’intégrer de manière active à la communauté.

Concernant le contexte et le côté pratique de la conférence, j’avoue avoir été pleinement satisfait.
Le cadre de la cité universitaire était très plaisant et agréable, la salle mis à notre disposition l’était tout autant et les différents services (petit-déjeuner et déjeuner) efficaces (bon, le déjeuner était un peu light et le choix restreint à un unique sandwich mais bon :p).

Fabien et toute l’équipe était très accessible ; ce qui rajoutait à la convivialité de ces deux journées !

Je tenais à les remercier chaleureusement et j’espère pouvoir participer à la prochaine conférence Symfony Live (qui semble-t-il sera en anglais malheureusement).

Voilà, je voulais éviter de faire un résumé de chaque conférence. Je ne pense pas que cela soit nécessaire du fait de la mise à disposition des interventions. Je voulais surtout vous présenter mon ressenti général qui, comme vous l’aurez compris, est très bon.

Du coup, pas de tuto ou d’astuce pour cette semaine (peut-être en fin de semaine si j’ai le temps).

[MAJ 13/06] Symfony Live -Day 2

MAJ 1 : Vous trouverez quelques informations sur la deuxième journée sur le site officiel et n’étant pas là ce week end, je vous ferai un résumé la semaine prochaine !


La première journée du symfony live est déjà passée et la deuxième va bientôt débuter !
Je n’ai pas eu de temps pour vous faire un résume complet d’hier mais rien que sur le site officiel, vous trouverez ce qu’il vous faut.
Cette première journée fut chargée dans le bon sens : beaucoup d’informations, beaucoup de bonne présentations plus intéressantes les unes que les autres ! Qui plus est, la core team est super abordable et agréable.
Une journée longue (arrivée à 8:15 pour ma part et fin de la journée à 19:45 quand on nous a viré de la salle :p) et fatiguante mais une super journée!
Vivement aujourd’hui !

Intégration de la librairie XAJAX (admin generator) – Partie 2

Reprenons ou nous nous étions arrêté hier soir sur la première partie de ce tutoriel.

Il nous restait donc à créer les différentes actions :

Actions du module TOOLS
Le module tools me sert pour plusieurs choses (par exemple XAJAX + JQUERY autocompleter). Je ne vais vous proposer que le code pour XAJAX :

<?php

class toolsActions extends sfActions
{
  public function executeXajax(sfWebRequest $request)
  {
  }
}

// FONCTION XAJAX D'AFFICHAGE DE LA LISTE DES VILLES EN FONCTION DU CODE POSTAL SAISI
function xajax_alert($message){
  $objResponse = new xajaxResponse();
  $objResponse->alert($message);
  return $objResponse;
}>

Vous le voyez, c’est assez simple. Il faut bien voir aussi que nous utilisons ici une fonction très simple d’alert javascript.
La fonction executeXajax() permet ici de charger la fonction xajax_alert() qui n’est pas dans la classe toolsActions.
J’ai choisi d’utiliser une fonction simple de XAJAX car je ne prétends pas faire un tutoriel sur l’utilisation d’XAJAX mais je l’ai utilisé dans un projet afin de remplir des champs en fonction d’un autre champ ou d’afficher une liste déroulante de ville en fonction du code postal saisi dans un champ de formulaire.

Ajout dans le layout
Nous alons rajouter une ligne dans le layout qui permettra d’enregistrer la fonction que nous souhaitons appeler (le helper prend en argument un tableau donc on peut enregistrer plusieurs fonctions en même temps) :

 <?php use_helper('xajax') ?> // code ajouté hier
<?php register_functions(array("xajax_alert")) ?>
<?php init_xajax_javascript() ?>  // code ajouté hier

Nous le plaçons après avoir chargé le helper (logique :p) et avant l’initialisation du script dans le document (je ne sais pas si c’est important mais ça fonctionne ainsi :p).

Action/Template dans votre module
Voilà, il ne nous reste plus qu’à utiliser notre fonction xajax_alert() quelque part. Soit vous utilisé un module déjà créé soit vous créez un nouveau module. Je vous propose de créer un module et du coup, une nouvelle action :

public function executeAffichagexajax(sfWebRequest $request)
{
}

Bon, il faut bien se dire ici que cette action est vide et ne sert uniquement qu’à tester notre fonction xajax. Si vous voulez utiliser XAJAX dans une action différente, c’est tout aussi possible. Dans ce cas, il suffit juste d’ajouter dans le template correspondant (action = executeAffichagexajax / template = affichagexajaxSuccess.php) un appel à cette fonction :

<?php echo link_to('cliquez moi !', '', array('onclick' => 'xajax_xajax_alert("BRAVO, XAJAX FONCTIONNE !");return false;')) ?>

Voilà, si tout va bien, vous devriez voir ceci sur votre page :

Ce tutoriel est assez complexe dans le sens où il faut travailler avec beaucoup de fichiers et du coup, il se peut qu’à un endroit ou un autre, cela coince.

Quoiqu’il en soit, j’espère vous avoir aidé à comprendre comment intégrer XAJAX à symfony permettant d’offrir au framework de nouvelles fonctionnalités sympathiques :)

Si vous avez des questions, des problèmes ou autres, n’hésitez pas, j’essayerai de vous répondre rapidement.

Mon prochain article devrait concerner la conférence Symfony Live qui a débute ce jeudi. Je ne garantis pas un article pour lundi prochain mais je l’espère tout de même en début de semaine.

A bon entendeur !

Intégration de la librairie XAJAX (admin generator) – Partie 1

Suite à l’article publié la semaine dernière sur comment intégrer la librairie FPDF à symfony, je vais vous présenter aujourd’hui comment intégrer la librairie XAJAX.

Intégration de la librairie XAJAX
- téléchargez la dernière version de la librairie XJAX (page de téléchargement officielleversion 0.5 RC2 zip utilisée dans ce tutoriel)
- décompressez le fichier puis placez le répertoire xajax_core dans le répertoire lib/ de votre projet  ce qui doit donner : /path_du_projet/lib/xajax_core
- placez le répertoire xajax_js dans le répertoire /web de votre projet ce qui doit donner : /path_du_projet/web/xajax_js
- créez le fichier xajax_symfony.php dans /path_du_projet/lib/xajax_core/ :

<?php

class sf_xajax{
  static function getXajaxObj(){
    global $xajax_symfony;
    if (!isset($xajax_symfony)){
      if(sfConfig::get('sf_app')."_".sfConfig::get('sf_environment')==sfConfig::get('app_index_conf'))       $php_file="";
      else $php_file=sfConfig::get('sf_app')."_".sfConfig::get('sf_environment').".php/";
      $xajax_symfony = new xajax("/".$php_file."xajax");
    }
    return $xajax_symfony;
  }

  static function registerFunctions($functions){
    $xajax_symfony = sf_xajax::getXajaxObj();
    foreach($functions as $function){
      $xajax_symfony->register(XAJAX_FUNCTION,$function);
    }
  }

  static function processRequest(){
    $xajax_symfony = sf_xajax::getXajaxObj();
    $xajax_symfony->processRequest();
  }

  static function printJavascript(){
    $xajax_symfony = sf_xajax::getXajaxObj();
    $xajax_symfony->printJavascript("/");
  }
}
?>

- créez le fichier xajaxHelper.php dans /path_du_projet/lib/helper/ :

<?php

  function xajax_input($type,$value,$function,$event,$funcArgs,$tagParams){
    $tmpVal = "<input type=\"$type\" value=\"$value\"";
    $fArgs = join(",",$funcArgs);
    $tmpVal .= " $event=\"xajax_$function($fArgs)\"";
    foreach($tagParams as $pKey=>$pValue){
      $tmpVal .= " $pKey=\"$pValue\"";
    }
    $tmpVal .="/>";
    return $tmpVal;
  }

  function xajax_js_get_value($objId){
    return "xajax.$('$objId').value";
  }

  function include_xajax_javascript($uri){
    sf_xajax::printJavascript($uri);
  }

  function init_xajax_javascript(){
    sf_xajax::processRequest();
  }

  function register_functions($functions=array()){
    sf_xajax::registerFunctions($functions);
  }

  function xajax_start_form($id,$function,$tagParams){
    $tmpVal = "";
    foreach($tagParams as $pKey=>$pValue){
      $tmpVal .= " $pKey=\"$pValue\"";
    }
    return "<form id=\"$id\" action=\"javascript:void(null);\" onsubmit=\"xajax_$function(xajax.getFormValues('$id'));\"$tmpVal>";
  }

  function xajax_end_form(){
    return "</form>";
  }
?>

Intégration à l’admin generator
- en ligne de commande :

./symfony generate:module mon_application tools

- dans le fichier layout.php de votre application d’admin generator :
avant le doctype :

<?php use_helper('xajax') ?>
<?php init_xajax_javascript() ?>

entre les balises head :

<?php include_xajax_javascript() ?>

- dans le fichier routing.yml de votre application d’admin generator :

xajax:
  url:  /xajax
  param:  { module: tools, action : xajax }

Il nous reste à créer les actions dans le module tools et à utiliser ces actions dans d’autres modules.

Fin de la première partie. La suite demain !

Intégration de la librairie FPDF (admin generator)

Je vais vous présenter aujourd’hui comment intégrer la librairie FPDF à symfony et surtout, comment l’intégrer proprement dans une page web.

Intégration de la librairie FPDF
- téléchargez la dernière version de la librairie FPDF (page de téléchargement officielleversion 1.6 tgz utilisée dans ce tutoriel)
- décompressez le fichier dans le répertoire lib/ de votre projet (personnellement, j’ai créé un repertoire lib/tools/) ce qui doit donner : /path_du_projet/lib/fpdf16

Intégration à l’admin generator
- dans le fichier action.class.php de votre module d’admin generator :

public function executeMonPDF(sfWebRequest $request){
  // on définit le répertoire des polices (en dur ici mais il suffit de placer le paramètre dans le fichier app.yml)
  define('FPDF_FONTPATH','/path_du_projet/lib/tools/fpdf16/font/');
  // on charge la classe FPDF
  $this->pdf = new FPDF();
  // on ajoute une page au document
  $this->pdf->AddPage();
  // j'écris un texte en arial 11 gras sur fond blanc
  $this->pdf->SetFillColor(204,204,204);
  $this->pdf->SetFont("Arial",'B',11);
  $this->pdf->Write(5,'Mon premier document PDF sous symfony !');
  // nom du fichier pdf qui sera créé
  $this->file_name = "uploads/pdf/mon_pdf_sous_symfony.pdf";
  // on exporte le fichier
  $this->pdf->Output($this->file_name, "F");
  // on définit la classe du div contenant le PDF
  $this->classe = "pdf";
  // on donne un titre <h1> à la page
  $this->h1 = "Impression de mon premier PDF";
  // on appelle le template pdfSuccess.php
  $this->setTemplate('pdf');
}

- dans le fichier pdfSuccess.php de votre module d’admin generator :

<h1><?php echo $h1 ?></h1>
<div class="sf_admin_pdf">
  <object data="<?php echo $file ?>" type="text/html" codetype="application/pdf" class="object_pdf"></object>
<div>

- dans le fichier web/css/main.css du projet :

div.sf_admin_pdf{
  margin:0 auto;
  text-align:center;
  width:95%;
  height:80%;
  border:2px solid black;
}
.object_pdf{
  width:100%;
  height:100%;
}

- dans le fichier generator.yml de votre module d’admin generator :

object_actions:
  monpdf: { label: mon PDF , action: MonPDF }

Ces quatres fichiers devraient vous permettre d’intégrer un document PDF de cette manière :

Cela permet d’éviter d’avoir directement le document à télécharger (on peut le sauvegarder ou l’imprimer par exemple) ou de l’avoir en plein écran et de devoir faire Page précédente ou même de l’avoir dans une nouvelle fenêtre.

J’ai été beaucoup plus loin dans l’intégration de FPDF, j’ai créé une classe qui étend celle de FPDF qui me permet de gérer un en-tête et/ou un pied de page ou encore de créer des fonctions d’affichage différentes, etc …

Pour ce qui est de l’utilisation de FPDF, elle est assez simple et la documentation sur le site officiel (documentation + tutoriaux) est assez explicite. Si vous avez encore des soucis, d’autres tutoriaux sont disponibles par une simple recherche sur Internet.

Petite astuce, FPDF ne gère pas l’UTF-8, pensez donc à bien utiliser utf8_decode() au besoin :)

On se retrouve bientôt pour un tutoriel sur l’intégration de XAJAX !