Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

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