Development

/branches/1.2/lib/plugins/sfPropelPlugin/lib/task/sfPropelBaseTask.class.php

You must first sign up to be able to contribute.

root/branches/1.2/lib/plugins/sfPropelPlugin/lib/task/sfPropelBaseTask.class.php

Revision 15727, 10.7 kB (checked in by fabien, 5 years ago)

[1.2, 1.3] enhanced an error message (closes #5898)

  • Property svn:mime-type set to text/x-php
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1 <?php
2
3 /*
4  * This file is part of the symfony package.
5  * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
6  *
7  * For the full copyright and license information, please view the LICENSE
8  * file that was distributed with this source code.
9  */
10
11 require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'config/config.php');
12
13 /**
14  * Base class for all symfony Propel tasks.
15  *
16  * @package    symfony
17  * @subpackage propel
18  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
19  * @version    SVN: $Id$
20  */
21 abstract class sfPropelBaseTask extends sfBaseTask
22 {
23   const CHECK_SCHEMA = true;
24   const DO_NOT_CHECK_SCHEMA = false;
25
26   static protected $done = false;
27
28   protected $additionalPhingArgs = array();
29
30   public function initialize(sfEventDispatcher $dispatcher, sfFormatter $formatter)
31   {
32     parent::initialize($dispatcher, $formatter);
33
34     if (!self::$done)
35     {
36       sfToolkit::addIncludePath(array(
37         realpath(dirname(__FILE__).'/../vendor'),
38         dirname(__FILE__),
39       ));
40
41       self::$done = true;
42     }
43   }
44
45   protected function createConfiguration($application, $env)
46   {
47     $configuration = parent::createConfiguration($application, $env);
48
49     $autoloader = sfSimpleAutoload::getInstance();
50     $config = new sfAutoloadConfigHandler();
51     $mapping = $config->evaluate($configuration->getConfigPaths('config/autoload.yml'));
52     foreach ($mapping as $class => $file)
53     {
54       $autoloader->setClassPath($class, $file);
55     }
56     $autoloader->register();
57
58     return $configuration;
59   }
60
61   protected function process(sfCommandManager $commandManager, $options)
62   {
63     parent::process($commandManager, $options);
64
65     // capture phing-arg options
66     if ($commandManager->getOptionSet()->hasOption('phing-arg'))
67     {
68       $this->additionalPhingArgs = $commandManager->getOptionValue('phing-arg');
69     }
70   }
71
72   protected function schemaToYML($checkSchema = self::CHECK_SCHEMA, $prefix = '')
73   {
74     $finder = sfFinder::type('file')->name('*schema.xml')->prune('doctrine');
75
76     $schemas = array_unique(array_merge($finder->in(sfConfig::get('sf_config_dir')), $finder->in($this->configuration->getPluginSubPaths('/config'))));
77     if (self::CHECK_SCHEMA === $checkSchema && !count($schemas))
78     {
79       throw new sfCommandException('You must create a schema.xml file.');
80     }
81
82     $dbSchema = new sfPropelDatabaseSchema();
83     foreach ($schemas as $schema)
84     {
85       $dbSchema->loadXML($schema);
86
87       $this->logSection('schema', sprintf('converting "%s" to YML', $schema));
88
89       $localprefix = $prefix;
90
91       // change prefix for plugins
92       if (preg_match('#plugins[/\\\\]([^/\\\\]+)[/\\\\]#', $schema, $match))
93       {
94         $localprefix = $prefix.$match[1].'-';
95       }
96
97       // save converted xml files in original directories
98       $yml_file_name = str_replace('.xml', '.yml', basename($schema));
99
100       $file = str_replace(basename($schema), $prefix.$yml_file_name$schema);
101       $this->logSection('schema', sprintf('putting %s', $file));
102       file_put_contents($file, $dbSchema->asYAML());
103     }
104   }
105
106   protected function schemaToXML($checkSchema = self::CHECK_SCHEMA, $prefix = '')
107   {
108     $finder = sfFinder::type('file')->name('*schema.yml')->prune('doctrine');
109     $dirs = array_merge(array(sfConfig::get('sf_config_dir')), $this->configuration->getPluginSubPaths('/config'));
110     $schemas = $finder->in($dirs);
111     if (self::CHECK_SCHEMA === $checkSchema && !count($schemas))
112     {
113       throw new sfCommandException('You must create a schema.yml file.');
114     }
115
116     $dbSchema = new sfPropelDatabaseSchema();
117
118     foreach ($schemas as $schema)
119     {
120       $schemaArray = sfYaml::load($schema);
121
122       if (!is_array($schemaArray))
123       {
124         continue; // No defined schema here, skipping
125       }
126
127       if (!isset($schemaArray['classes']))
128       {
129         // Old schema syntax: we convert it
130         $schemaArray = $dbSchema->convertOldToNewYaml($schemaArray);
131       }
132
133       $customSchemaFilename = str_replace(array(
134         str_replace(DIRECTORY_SEPARATOR, '/', sfConfig::get('sf_root_dir')).'/',
135         'plugins/',
136         'config/',
137         '/',
138         'schema.yml'
139       ), array('', '', '', '_', 'schema.custom.yml'), $schema);
140       $customSchemas = sfFinder::type('file')->name($customSchemaFilename)->in($dirs);
141
142       foreach ($customSchemas as $customSchema)
143       {
144         $this->logSection('schema', sprintf('found custom schema %s', $customSchema));
145
146         $customSchemaArray = sfYaml::load($customSchema);
147         if (!isset($customSchemaArray['classes']))
148         {
149           // Old schema syntax: we convert it
150           $customSchemaArray = $dbSchema->convertOldToNewYaml($customSchemaArray);
151         }
152         $schemaArray = sfToolkit::arrayDeepMerge($schemaArray, $customSchemaArray);
153       }
154
155       $dbSchema->loadArray($schemaArray);
156
157       $this->logSection('schema', sprintf('converting "%s" to XML', $schema));
158
159       $localprefix = $prefix;
160
161       // change prefix for plugins
162       if (preg_match('#plugins[/\\\\]([^/\\\\]+)[/\\\\]#', $schema, $match))
163       {
164         $localprefix = $prefix.$match[1].'-';
165       }
166
167       // save converted xml files in original directories
168       $xml_file_name = str_replace('.yml', '.xml', basename($schema));
169
170       $file = str_replace(basename($schema), $localprefix.$xml_file_name$schema);
171       $this->logSection('schema', sprintf('putting %s', $file));
172       file_put_contents($file, $dbSchema->asXML());
173     }
174   }
175
176   protected function copyXmlSchemaFromPlugins($prefix = '')
177   {
178     if (!$dirs = $this->configuration->getPluginSubPaths('/config'))
179     {
180       return;
181     }
182
183     $schemas = sfFinder::type('file')->name('*schema.xml')->prune('doctrine')->in($dirs);
184     foreach ($schemas as $schema)
185     {
186       // reset local prefix
187       $localprefix = '';
188
189       // change prefix for plugins
190       if (preg_match('#plugins[/\\\\]([^/\\\\]+)[/\\\\]#', $schema, $match))
191       {
192         // if the plugin name is not in the schema filename, add it
193         if (!strstr(basename($schema), $match[1]))
194         {
195           $localprefix = $match[1].'-';
196         }
197       }
198
199       // if the prefix is not in the schema filename, add it
200       if (!strstr(basename($schema), $prefix))
201       {
202         $localprefix = $prefix.$localprefix;
203       }
204
205       $this->getFilesystem()->copy($schema, 'config'.DIRECTORY_SEPARATOR.$localprefix.basename($schema));
206       if ('' === $localprefix)
207       {
208         $this->getFilesystem()->remove($schema);
209       }
210     }
211   }
212
213   protected function cleanup()
214   {
215     if (is_null($this->commandApplication) || !$this->commandApplication->withTrace())
216     {
217       $finder = sfFinder::type('file')->name('/^generated-.*schema(-transformed)?.xml$/');
218       $this->getFilesystem()->remove($finder->in(array('config', 'plugins')));
219     }
220   }
221
222   protected function callPhing($taskName, $checkSchema, $properties = array())
223   {
224     $schemas = sfFinder::type('file')->name('*schema.xml')->relative()->follow_link()->in(sfConfig::get('sf_config_dir'));
225     if (self::CHECK_SCHEMA === $checkSchema && !$schemas)
226     {
227       throw new sfCommandException('You must create a schema.yml or schema.xml file.');
228     }
229
230     // Call phing targets
231     sfToolkit::addIncludePath(array(
232       sfConfig::get('sf_root_dir'),
233       realpath(dirname(__FILE__).'/../vendor/propel-generator/classes'),
234     ));
235
236     $args = array();
237     $bufferPhingOutput = is_null($this->commandApplication) || !$this->commandApplication->withTrace();
238
239     $properties = array_merge(array(
240       'build.properties'  => 'propel.ini',
241       'project.dir'       => sfConfig::get('sf_config_dir'),
242       'propel.output.dir' => sfConfig::get('sf_root_dir'),
243     ), $properties);
244     foreach ($properties as $key => $value)
245     {
246       $args[] = "-D$key=$value";
247     }
248
249     // Build file
250     $args[] = '-f';
251     $args[] = realpath(dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'vendor'.DIRECTORY_SEPARATOR.'propel-generator'.DIRECTORY_SEPARATOR.'build.xml');
252
253     // Logger
254     if (DIRECTORY_SEPARATOR != '\\' && (function_exists('posix_isatty') && @posix_isatty(STDOUT)))
255     {
256       $args[] = '-logger';
257       $args[] = 'phing.listener.AnsiColorLogger';
258     }
259
260     // Add our listener to detect errors
261     $args[] = '-listener';
262     $args[] = 'sfPhingListener';
263
264     // Add any arbitrary arguments last
265     foreach ($this->additionalPhingArgs as $arg)
266     {
267       if (in_array($arg, array('verbose', 'debug')))
268       {
269         $bufferPhingOutput = false;
270       }
271
272       $args[] = '-'.$arg;
273     }
274
275     $args[] = $taskName;
276
277     require_once dirname(__FILE__).'/sfPhing.class.php';
278
279     // enable output buffering
280     Phing::setOutputStream(new OutputStream(fopen('php://output', 'w')));
281     Phing::startup();
282     Phing::setProperty('phing.home', getenv('PHING_HOME'));
283
284     $this->logSection('propel', 'Running "'.$taskName.'" phing task');
285
286     if ($bufferPhingOutput)
287     {
288       ob_start();
289     }
290
291     $m = new sfPhing();
292     $m->execute($args);
293     $m->runBuild();
294
295     if ($bufferPhingOutput)
296     {
297       ob_end_clean();
298     }
299
300     chdir(sfConfig::get('sf_root_dir'));
301
302     // any errors?
303     $ret = true;
304     if (sfPhingListener::hasErrors())
305     {
306       $messages = array('Some problems occurred when executing the task:');
307
308       foreach (sfPhingListener::getExceptions() as $exception)
309       {
310         $messages[] = '  '.preg_replace('/^.*build\-propel\.xml/', 'build-propel.xml', $exception->getMessage());
311       }
312
313       if (count(sfPhingListener::getErrors()))
314       {
315         $messages[] = '  If the exception message is not clear enough, read the output of the task for more information';
316       }
317
318       $this->logBlock($messages, 'ERROR');
319
320       $ret = false;
321     }
322
323     return $ret;
324   }
325
326   protected function getPhingPropertiesForConnection($databaseManager, $connection)
327   {
328     $database = $databaseManager->getDatabase($connection);
329
330     return array(
331       'propel.database'          => $database->getParameter('phptype'),
332       'propel.database.driver'   => $database->getParameter('phptype'),
333       'propel.database.url'      => $database->getParameter('dsn'),
334       'propel.database.user'     => $database->getParameter('username'),
335       'propel.database.password' => $database->getParameter('password'),
336       'propel.database.encoding' => $database->getParameter('encoding'),
337     );
338   }
339
340   protected function getProperties($file)
341   {
342     $properties = array();
343
344     if (false === $lines = @file($file))
345     {
346       throw new sfCommandException('Unable to parse contents of the "sqldb.map" file.');
347     }
348
349     foreach ($lines as $line)
350     {
351       $line = trim($line);
352
353       if ('' == $line)
354       {
355         continue;
356       }
357
358       if (in_array($line[0], array('#', ';')))
359       {
360         continue;
361       }
362
363       $pos = strpos($line, '=');
364       $properties[trim(substr($line, 0, $pos))] = trim(substr($line, $pos + 1));
365     }
366
367     return $properties;
368   }
369 }
370
Note: See TracBrowser for help on using the browser.