2016-09-08 1 views
0

Commencé à fonctionner avec Propel 2.0 ORM. Tous les tutoriels disent de travailler avec les schémas de cette façon:Comment créer un modèle, des tables, etc. SANS interface de ligne de commande

  1. Créer un schéma dans un fichier XML/JSON/YAML/PHP;
  2. Run $ propel model:build

Comment puis-je créer, ou recréer, ou modèles de mise à jour et les données sans utiliser la ligne de commande, mais à l'intérieur des scripts php? Cela peut être nécessaire pour créer des installateurs de modules CMS ou quelque chose comme ça.

Répondre

0

La réponse: Commander Classe

Une approche «Réinventer-La-roue», mais je ne l'ai pas trouvé d'autre moyen de travailler avec Propel 2 sans CLI.

use Propel\Runtime\Propel; 
use Propel\Generator\Command; 

use Symfony\Component\Console\Input\ArrayInput; 
use Symfony\Component\Console\Output\StreamOutput; 
use Symfony\Component\Console\Application; 

/** 
* Class Commander 
* 
* A script-based approach to run Propel commands without the CLI. 
* 
* Usage: 
* 
* ``` 
* $cmd = new Commander('<propel_command>', '<command_arguments>'); 
* $cmd->run(); 
* ... 
* $cmd->addCommand('<propel_command>', '<command_arguments>'); 
* $cmd->run(); 
* ``` 
* 
* In case of migration tasks you must call 
* ``` 
* ...->preMigrate(array('<path_to_schema_files_dir1>', ..., '<path_to_schema_files_dirN>'), '<temp_dir>'); 
* ``` 
* to gather all schemas together and analyze 'em with propel:diff. 
* 
* Then after the diff and migrate are complete you must call ``postMigrate()`` to remove temporary 
* schema copies. 
* 
*/ 
class Commander 
{ 
    private $command, 
      $parameters, 
      $migrationTempSource; 

    public function __construct($cmd = '', $params = '') 
    { 
     $this->addCommand($cmd, $params); 
    } 

    /** 
    * Prepare schema files to be analyzed before the migration process. 
    * @param array $schemaDirs Array of strings with schema directories 
    * @param string $tmpSchemaDir Temporary directory to copy schemas to. 
    * This path also must be used as a --schema-dir option value during the 
    * diff and migrate tasks 
    * @return boolean $result 
    */ 
    public function preMigrate($schemaDirs = array(), $tmpSchemaDir) 
    { 
     $result = false; 
     $filelist = []; 
     foreach($schemaDirs as $path) 
     { 
      if(is_dir($path)) 
      { 
       $f = $this->seekFiles($path); 
       $filelist = count($f) > 0 ? array_merge($filelist, $f) : $f; 
      } 
     } 
     if(!file_exists($tmpSchemaDir)) 
     { 
      mkdir($tmpSchemaDir, 0777, true); 
     } 
     foreach($schemaDirs as $path) 
     { 
      if(is_dir($path)) 
      { 
       $f = $this->seekFiles($path); 
       foreach($f as $file) 
       { 
        copy($path . '/' . $file, $tmpSchemaDir . '/' . $file); 
       } 
      } 
     } 
     $this->migrationTempSource = $tmpSchemaDir; 
     return $result; 
    } 

    /** 
    * Removes the temporary schema files after the diff and migrate tasks are complete. 
    * 
    * @param bool $removeTmpDir Set to true if you want to remove the whole temporary 
    * directory, not just the schema files. 
    * @return bool 
    */ 
    public function postMigrate($removeTmpDir = false) 
    { 
     $result = false; 
     $dir = scandir($this->migrationTempSource); 
     foreach($dir as $d) 
     { 
      if($d != '.' && $d != '..') 
      { 
       unlink($this->migrationTempSource . '/' . $d); 
      } 
     } 

     if($removeTmpDir === true) 
     { 
      @rmdir($this->migrationTempSource); 
     } 

     return $result; 
    } 

    private function seekFiles($dir) 
    { 
     $res = []; 
     if(is_dir($dir)) 
     { 
      $d = scandir($dir); 
      foreach($d as $dd) 
      { 
       if($dd != '.' && $dd != '..') 
       { 
        if((strpos($dd, 'schema.xml') == strlen($dd)-10) || ($dd == 'schema.xml')) 
        { 
         $res[] = $dd; 
        } 
       } 
      } 
     } 
     return $res; 
    } 

    public function addCommand($cmd = '', $params = '') 
    { 
     $this->command = $cmd; 
     $this->parameters = explode(' --', $params); 
    } 

    public function run() 
    { 
     if($this->command == '') return false; 

     $callCommandClass = ''; 
     $cmdParts = explode(':', $this->command); 
     switch($cmdParts[0]) 
     { 
      case 'config': 
       switch($cmdParts[1]) 
       { 
        case 'convert': 
         $callCommandClass = 'ConfigConvertCommand'; 
        break; 
       } 
      break; 

      case 'diff': 
       $callCommandClass = 'MigrationDiffCommand'; 
      break; 

      case 'migration': 
       switch($cmdParts[1]) 
       { 
        case 'create': 
         $callCommandClass = 'MigrationCreateCommand'; 
        break; 

        case 'diff': 
         $callCommandClass = 'MigrationDiffCommand'; 
        break; 

        case 'up': 
         $callCommandClass = 'MigrationUpCommand'; 
        break; 

        case 'down': 
         $callCommandClass = 'MigrationDownCommand'; 
        break; 

        case 'status': 
         $callCommandClass = 'MigrationStatusCommand'; 
        break; 

        case 'migrate': 
         $callCommandClass = 'MigrationMigrateCommand'; 
        break; 
       } 
      break; 

      case 'model': 
       switch($cmdParts[1]) 
       { 
        case 'build': 
         $callCommandClass = 'ModelBuildCommand'; 
        break; 
       } 
      break; 

      case 'sql': 
       switch($cmdParts[1]) 
       { 
        case 'build': 
         $callCommandClass = 'SqlBuildCommand'; 
        break; 

        case 'insert': 
         $callCommandClass = 'SqlInsertCommand'; 
        break; 
       } 
      break; 
     } 

     $a = []; 
     foreach($this->parameters as $p) 
     { 
      $x = explode('=', $p); 
      if(count($x) > 1) 
      { 
       $a['--'.str_replace('--', '', $x[0])] = trim($x[1]); 
      } 
      else 
      { 
       $a['--'.str_replace('--', '', $x[0])] = true; 
      } 
     } 

     $commandLine = array('command' => $this->command) + $a; 

     $app = new Application('Propel', Propel::VERSION); 
     $cls = '\Propel\Generator\Command'.'\\'.$callCommandClass; 
     /** @noinspection PhpParamsInspection */ 
     $app->add(new $cls()); 
     $app->setAutoExit(false); 
     $output = new StreamOutput(fopen("php://temp", 'r+')); 
     $result = $app->run(new ArrayInput($commandLine), $output); 

     if(0 !== $result) 
     { 
      rewind($output->getStream()); 
      return stream_get_contents($output->getStream()); 
     } 
     else 
     { 
      return true; 
     } 
    } 
} 

Et l'exemple d'utilisation:

//Convert the configuration file  
$cmd = new Commander('config:convert', '--config-dir='.$_SERVER['DOCUMENT_ROOT'].'/propeltest/config --output-dir='.$_SERVER['DOCUMENT_ROOT'].'/propeltest/config'); 
$cmd->run(); 

//... or (re)build models 
$cmd = new Commander('model:build', '--schema-dir='.$_SERVER['DOCUMENT_ROOT'].'/propeltest/module/schema --output-dir='.$_SERVER['DOCUMENT_ROOT'].'/propeltest/module/models'); 
$cmd->run(); 

//... or perform database migration (actually not tested yet :/) 
$cmd = new Commander('migration:diff', '--schema-dir='.$_SERVER['DOCUMENT_ROOT'].'/propeltest/cache/schemacache'); 
$cmd->preMigrate([$_SERVER['DOCUMENT_ROOT'].'/propeltest/schema', $_SERVER['DOCUMENT_ROOT'].'/propeltest/module/schema'], $_SERVER['DOCUMENT_ROOT'].'/propeltest/cache/schemacache'); 
$cmd->run(); // runs migrate:diff 
$cmd->addCommand('migration:diff', '--schema-dir='.$_SERVER['DOCUMENT_ROOT'].'/propeltest/cache/schemacache'); // prepare to actually migration 
$cmd->run(); // perform migration:migrate 
$cmd->postMigrate();