Génération de code avec le Zend Framework

Avec la sortie de la Release Candidate 1 du Zend Framework 1.6 est annoncé une version préliminaire des composants Zend_Tool qui incluront des classes pour la génération et la modification de code.

Lorsque que le composant sera finalisé, il sera possible de générer la structure du projet avec une commande telle que :

zf create project

pour créer un contrôleur nommé foo

zf create controller -n foo

A l'heure ou j'écris ces lignes, le composant n'est absolument pas fonctionnel, mais une bonne partie du code semble déjà écrite.

Les sources ne sont pas incluses dans l'archive que vous pouvez télécharger sur le site de Zend, mais vous pouvez le récupérer avec un checkout SVN sur http://framework.zend.com/svn/framework/laboratory/Zend_Tool/

A titre d'expérimentation, j'ai essayé de créer un script en ligne de commande nommé generate.php destiné à générer le squelette d'un modèle ZF.

Vous pouvez trouver son code ci-dessous. Pour qu'il fonctionne, vous devez avoir placé le répertoire ZendL dans le chemin d'inclusion de PHP.

<?php/**
* Pluralize a word
*
* @param string $word
* @return string
*/

function pluralize($word) {
 return $word . 's'; 
}

if ($argc == 1) {
 echo "\nSyntaxe :\n",
   "  php generate.php model model_name\n";
} else {
 switch ($argv[1]) {
     case 'model':
         if ($argc > 2) {
             $tableName = pluralize($argv[2]);
             $tableClassName = ucfirst($tableName);
          
             $rowClass = new ZendL_Tool_CodeGenerator_Php_Class(array(
                 'methods' => array(
                     new ZendL_Tool_CodeGenerator_Php_Method(array(
                         'name' => '_delete',
                         'visibility' => ZendL_Tool_CodeGenerator_Php_Member_Abstract::VISIBILITY_PROTECTED,
                         'body' => '        /* Code à exécuter avant la suppression */'
                     )),
                     new ZendL_Tool_CodeGenerator_Php_Method(array(
                         'name' => '_insert',
                         'visibility' => ZendL_Tool_CodeGenerator_Php_Member_Abstract::VISIBILITY_PROTECTED,
                         'body' => '        /* Code à exécuter avant l\'insertion */'
                     )),
                     new ZendL_Tool_CodeGenerator_Php_Method(array(
                         'name' => '_update',
                         'visibility' => ZendL_Tool_CodeGenerator_Php_Member_Abstract::VISIBILITY_PROTECTED,
                         'body' => '        /* Code à exécuter avant la mise à jour */'
                         ))
                     )
                 )
             );          
             $rowClass->setName(ucfirst($argv[2]));
             $rowClass->setExtendedClass('Zend_Db_Table_Row_Abstract');
          
             $nameProp = new ZendL_Tool_CodeGenerator_Php_Property(array(
                 'visibility' => 'protected'
             ));
             $nameProp->setName('_name');
             $nameProp->setDefaultValue($tableName);
          
             $rowClassProp = new ZendL_Tool_CodeGenerator_Php_Property(array(
                 'visibility' => 'protected'
             ));
             $rowClassProp->setName('_rowClass');
             $rowClassProp->setDefaultValue(ucfirst($argv[2]));
          
             $tableClass = new ZendL_Tool_CodeGenerator_Php_Class(array(
                 'properties' => array(
                     $nameProp,
                     $rowClassProp
                 )
             ));
             $tableClass->setName($tableClassName);
             $tableClass->setExtendedClass('Zend_Db_Table_Abstract');
                          
             $codeFile = new ZendL_Tool_CodeGenerator_Php_File();
             $codeFile->setClasses(array($rowClass, $tableClass));
          
             echo $codeFile;
         } else {
             echo "\n  ERREUR : vous devez specifier le nom d'un modele.\n";
         }
         break;

     default:
         break;
 } 
}
?>

Évidemment, vous auriez pu arriver au même résultat avec un simple système de template, mais l'intérêt du composant, c'est qu'il permettra de modifier des fichiers déjà existants à l'aide de l'API reflexion de PHP.

Le composant étant encore en cours de développement, j'ai été contraint d'implémenter moi même la méthode generate de la classe ZendL_Tool_CodeGenerator_Php_Property :

<?php
public function generate()
{
  
//return 'none';
  
$output '    ';
  
$output .= $this->_visibility;
  
$output .= ' $' $this->_name;
  if (
$this->_defaultValue) {
      
$output .= " = '" $this->_defaultValue "'";           
  }
  
$output .= ';';
  return 
$output;
}
?>
J'ai fait le minimum syndical. Ça ne fonctionne que pour les propriétés de type String. En supposant que php.exe soit dans votre PATH si vous êtes sous Windows, vous pouvez lancer le script avec la commande suivante :
php generate.php model article

Le code généré :

<?php
class Article extends Zend_Db_Table_Row_Abstract
{
    protected function 
_delete()
    {
        
/* Code à exécuter avant la suppression */
    
}

    protected function 
_insert()
    {
        
/* Code à exécuter avant l'insertion */
    
}

    protected function 
_update()
    {
        
/* Code à exécuter avant la mise à jour */
    
}
}

class 
Articles extends Zend_Db_Table_Abstract
{
    protected 
$_name 'articles';
    protected 
$_rowClass 'Article';
}
?>

Voir aussi

Poster un nouveau commentaire

Le contenu de ce champ ne sera pas montré publiquement. If you have a Gravatar account associated with the e-mail address you provide, it will be used to display your avatar.
  • Les adresses de pages web et de messagerie électronique sont transformées en liens automatiquement.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Les lignes et les paragraphes vont à la ligne automatiquement.
  • You can enable syntax highlighting of source code with the following tags: <code>, <php>.

Plus d'informations sur les options de formatage

CAPTCHA
La vérification ne tient pas compte des minuscules ou des majuscules.
Image CAPTCHA
Enter the characters shown in the image.