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

Ajouter un commentaire