lundi 30 mai 2011

CGridView : les colonnes à la une

Le composant CGridView (son nom complet est zii.widgets.grid.CGridView) fait partie des widgets de base du framework Yii. Il est utilisé notamment par Gii, le générateur de code intégré, lors de la création des fameux CRUD (Create, Read, Update, Delete). Si vous ne voyez toujours pas de qui je parle, allez faire un tour du côté de la démo Blog (pour vous connecter c'est demo/demo).
Ce joli tableau présente donc les valeurs des objets lus depuis la base de données par pages de 10 (défaut). Voyons un peu comment personnaliser le rendu des colonnes.
Pour cet exemple, nous allons nous baser sur une classe dérivée de CActiveRecord que nous appellerons MyRecord. Cette classe (hypothétique) comportera plusieurs attributs, qui devront apparaître dans chaque colonne du CGridView : 'id', 'name', 'create_time', etc ....

<?php $this->widget('zii.widgets.grid.CGridView', array(
   'id'=>'myrecord-grid',
   'dataProvider'  => $model->search(),
   'filter'        => $model,
   'columns'       => array(
      // 'id' et 'name' seront affichés normalement
      'id',
      'name',

      // Si MyRecord contient une relation nommée 'my_relation' et que l'objet 
      // en relation contient lui même un attribut nommé 'code', on peut
      // directement écrire :
      'my_relation.code'

      // 'create_time' est du type DATETIME : il sera affiché automatiquement
      // comme une date
      'create_time',

      // 'website_url' est ... une url ! il sera affiché en tant que lien
      // hypertexte
      array(
         'name' => 'website_url',
         'type' => 'url'
      ),

      // 'color' est une couleur (ex: #555343). Nous voulons l'utiliser pour
      // pour l'affichage de la valeur. Par exemple, la valeur 'red' sera 
      // affichée en rouge.
      array(
         'header' => 'Ma Couleur'   // nom de la colonne (entête)
         'name'   => 'color',       // nom de l'attribut
         'filter' => '',            // pas de filtre de colonne
         'type'   => 'raw',         // pas de conversion des caractères 
                                    // spéciaux
         'value'  => '"<span style=\"color:$data->color\">$data->color</span>"'     
      ),
      array(
         'class'=>'CButtonColumn',
      ),
   ),
)); ?>
Les valeurs disponibles pour le 'type' sont définies au niveau de la classe CFormatter


Modifier le nombre de lignes
Pour que votre CGridView affiche le nombre de ligne que vous souhaitez (par défaut : 10), il vous faudra intervenir au niveau du data provider. La ligne 03 affecte le data provider renvoyé par la méthode search(), à votre grid. C'est donc dans la méthode search() que nous allons changer les paramètres d'initialisation du data provider.

return new CActiveDataProvider(get_class($this), array(
         'criteria'=>$criteria,
          'pagination'=>array(
              // on va choisir d'afficher 20 lignes par page
              'pageSize'=>20,
          ),
      ));

Notons que le data provider prend en charge tout ce qui concerne la pagination

Voilà pour un premier aperçu de cette widget standard Yii. Il y a encore beaucoup à dire sur le sujet et les possibilités de personnalisation sont légions. Ce sera l'objet d'un prochain post (peut-être).
Pour aller plus loin, voici quelques liens utiles :

vendredi 27 mai 2011

Intégration Eclipse

Eclipse est un EDI puissant, qui permet entre autres de rajouter par différents mécanismes, la prise en charge de Yii. Par "prise en charge", il faut comprendre que certaines fonctionnalités standard d'Eclipse peuvent être mises à contribution, pour faciliter (et surtout accélérer) le développement d'une application basée sur Yii.


Installation

Pour mettre en place un tel environnement, il faut commencer par télécharger la version PDT d'Eclipse (PDT = PHP Developer Tools .. juste ce qu'il nous faut !). Une fois l'installation terminée nous allons déclarer le framework Yii comme librairie utilisateur.

  • menu Window > Preferences ... + PHP Librairies
  • cliquez sur le bouton New et nommez la librairie (par exemple Yii-1.1.7 si c'est de cette version dont vous disposez). Cliquez ensuite sur OK
  • sélectionnez ensuite la librairie que vous venez de déclarer et cliquez sur 'Add External Folder'
  • sélectionnez le répertoire framework de distribution Yii, puis cliquez sur OK
Désormais, lors de la création de votre prochain projet, vous serez en mesure de l'associer à votre librairie Yii, et donc d'accéder en lecture seule aux fichiers du framework Yii directement depuis le projet.

Outils personnaliés

Une autre fonction bien pratique offerte par Eclipse, est la possibilité de définir des outils personnalisés, que nous allons mettre à profit pour éxécuter des commandes Yii. La plus intéressante (à mon sens) permet de créer un squelette d'application Yii, en un click, directement depuis Eclipse. Pour cela, nous allons commencer par définir une structure type pour notre projet. La seule règle sera que l'application web à proprement parlé devra systématiquement se trouver dans le répertoire 'www', lui même placé à la racine du projet Eclipse. A partir de là c'est tout simple, mais quelques conditions doivent être satisfaites :
  1. rajoutez une variable d'environnement YII_HOME et initialisez avec le nom du répertoire d'installation du framework Yii (par exemple YII_HOME=G:\home\project\lib\php\yii\yii-1.1.7.r3135\framework)
  2. assurez-vous que PHP.exe est bien accessible depuis la variable PATH
  3. on suppose que PHPUnit est installé dans le répertoire PEAR, lui même placé dans le répertoire qui contient PHP.exe
  4. redémarrez Eclipse
  5. Menu Run > External Tools > External Tools Configuration ... 
On peut ensuite rajouter les commandes suivantes, avec les ajustements qui s'imposent en fonction des répertoires d'installations de php.exe et de phpunit :

// création d'une webapp Yii dans le répertoire sélectionné
// dans Eclipse
name              : webapp
location          : ${env_var:YII_HOME}\yiic.bat
working directory : ${workspace_loc}
argument          : webapp ${resource_loc}

// Exécution du test PHPUnit pour la classe sélectionnée
name              : PHPUnit  Unit (single)
location          : ${system_path:php.exe}
working directory : ${project_loc}/www/protected/tests
argument          : ${system_path:PEAR\phpunit} --verbose "${selected_resource_loc}"

// Exécution du test PHPUnit pour la classe sélectionnée
// Création du rapport correspondant
name              : PHPUnit  Unit (single) + rapport
location          : ${system_path:php.exe}
working directory : ${project_loc}/www/protected/tests
argument          : ${system_path:PEAR\phpunit} --coverage-html  "${project_loc}/www/protected/tests/report"  --verbose "${selected_resource_loc}"

// Exécution de tous les tests unitaire définis pour le projet sélectionné
// Création du rapport correspondant
name              : PHPUnit - Unit (all tests) + report
location          : ${system_path:php.exe}
working directory : ${project_loc}/www/protected/tests
argument          : ${system_path:PEAR\phpunit} --coverage-html  "${project_loc}/www/protected/tests/report" --verbose "${project_loc}/www/protected/tests/unit"

La création d'un nouveau projet Yii sous Eclipse est alors (presque) instantanée :

  • Menu File > New ... > PHP Project
  • Entrez le nom de projet puis Next 
  • cliquez sur l'onglet 'Librairies' puis sur 'Add Librairy ...'
  • sélectionnez la librairie Yii préalablement déclarée, puis terminez la création du projet
Pour se conformer à notre modèle de projet, créez le répertoire 'www' à la racine, et tout en le gardant sélectionnez lancez la commande que nous venons de rajouter (webapp) : le répertoire www est maintenant prêt pour votre nouvelle application Yii !!

Quelques liens :


jeudi 19 mai 2011

Fichier de Log

Yii dispose d'un système de log complet et extensible permettant d'écrire dans un fichier, une table de la base de données, la page web elle même, et potentiellement vers différents autres supports. Commençons par le plus simple : le fichier texte.

Le composant dédié à la gestion des logs est initialisé de la façon habituelle, dans le fichier de configuration protected/config/main.php. Par défaut, la commande 'webapp' qui créé automatiquement une application Yii de base (un squelette), inclus déjà la déclaration du composant de log. On va partir de là.

Déclarons un route menant au fichier 'my_log.txt', que nous voulons placer dans le répertoire './protected/data'. De plus, nous souhaitons que seuls les messages de niveau ERROR et WARNING soient rajoutés dans ce fichier, les autres seront simplement ignorés (ou enregistrés dans une autre route que nous aurions défini par ailleurs. Un filtre sur les catégories est également défini par le paramètre 'category'. Enfin, il est possible d'indiquer la taille maximale autorisée pour un fichier log, ainsi que le nombre de fichiers logs que nous souhaitons conserver dans la roation.

Voyons ce que cela donne :

'log'=>array(
      'class'=>'CLogRouter',
         'routes'=>array(
            array(
               'class'  => 'CFileLogRoute',
               // niveaux disponibles : trace, info, profile, warning, error
               'levels' => 'error, warning',
               'logFile'=> 'my_log.txt',

               'logPath'=> 'protected/data',
               // logPath peut aussi être défini comme cela :
               //'logPath'=> dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'runtime'

               'categories' => 'yiiexemple.*, category.app',

               // un fichier log ne devra pas faire plus de 2Mo. 
               // Lorsqu'il les dépasse Yii le renomme en rajoutant
               // un numéro d'index à la fin du fichier.
               // Par exemple : my_log.txt.1, my_log.txt.2 etc...
               'maxFileSize' => 2048,

               // Yii ne conservera que 5 fichiers log
               'maxLogFiles' => 5
            ),
         ),
      ),


On notera que le paramètre logPath ne peut pas être initialisé par la méthode Yii::getPathOfAlias(...) car au moment ou le composant log est initialisé, cette méthode n'est pas opérationnelle.
Notre log est déclaré, voici maintenant quelques exemples d'utilisation au travers de la fonction Yii::log().

// les messages suivants seront enregistrés dans notre log
   Yii::log('message1',CLogger::LEVEL_ERROR,'yiiexemple.app.logger');
   Yii::log('message2',CLogger::LEVEL_ERROR,'yiiexemple.app');
   Yii::log('message3',CLogger::LEVEL_WARNING,'category.app');

   // les messages suivants ne seront PAS enregistrés dans notre log
   // la catégorie 'application.test' n'est pas prise en compte par notre 
   // filtre qui n'autorise que les catégories 'yiiexemple.*' ainsi que
   // 'category.app'

   Yii::log('message4',CLogger::LEVEL_ERROR,'category.app.test');
   Yii::log('message5',CLogger::LEVEL_ERROR,'application.test');

   // pas de catégorie = pas de log non plus !
   Yii::log('message6',CLogger::LEVEL_ERROR);

   // Dans ce cas, la catégorie est acceptée, mais c'est le niveau de 
   // trace (LEVEL_INFO) n'est pas suffisant pour notre log
   Yii::log('message7',CLogger::LEVEL_INFO,'yiiexemple.app');



Liens :