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 tasks.
13
 *
14
 * @package    symfony
15
 * @subpackage task
16
 * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
17
 * @version    SVN: $Id: sfBaseTask.class.php 24341 2009-11-24 15:01:58Z Kris.Wallsmith $
18
 */
19
abstract class sfBaseTask extends sfCommandApplicationTask
20
{
21
  protected
22
    $configuration = null,
23
    $pluginManager = null;
24
 
25
  /**
26
   * @see sfTask
27
   */
28
  protected function doRun(sfCommandManager $commandManager, $options)
29
  {
30
    $event = $this->dispatcher->filter(new sfEvent($this, 'command.filter_options', array('command_manager' => $commandManager)), $options);
31
    $options = $event->getReturnValue();
32
 
33
    $this->process($commandManager, $options);
34
 
35
    $event = new sfEvent($this, 'command.pre_command', array('arguments' => $commandManager->getArgumentValues(), 'options' => $commandManager->getOptionValues()));
36
    $this->dispatcher->notifyUntil($event);
37
    if ($event->isProcessed())
38
    {
39
      return $event->getReturnValue();
40
    }
41
 
42
    $this->checkProjectExists();
43
 
44
    $requiresApplication = $commandManager->getArgumentSet()->hasArgument('application') || $commandManager->getOptionSet()->hasOption('application');
45
    if (null === $this->configuration || ($requiresApplication && !$this->configuration instanceof sfApplicationConfiguration))
46
    {
47
      $application = $commandManager->getArgumentSet()->hasArgument('application') ? $commandManager->getArgumentValue('application') : ($commandManager->getOptionSet()->hasOption('application') ? $commandManager->getOptionValue('application') : null);
48
      $env = $commandManager->getOptionSet()->hasOption('env') ? $commandManager->getOptionValue('env') : 'test';
49
 
50
      if (true === $application)
51
      {
52
        $application = $this->getFirstApplication();
53
 
54
        if ($commandManager->getOptionSet()->hasOption('application'))
55
        {
56
          $commandManager->setOption($commandManager->getOptionSet()->getOption('application'), $application);
57
        }
58
      }
59
 
60
      $this->configuration = $this->createConfiguration($application, $env);
61
    }
62
 
63
    if (null !== $this->commandApplication && !$this->commandApplication->withTrace())
64
    {
65
      sfConfig::set('sf_logging_enabled', false);
66
    }
67
 
68
    $ret = $this->execute($commandManager->getArgumentValues(), $commandManager->getOptionValues());
69
 
70
    $this->dispatcher->notify(new sfEvent($this, 'command.post_command'));
71
 
72
    return $ret;
73
  }
74
 
75
  /**
76
   * Sets the current task's configuration.
77
   *
78
   * @param sfProjectConfiguration $configuration
79
   */
80
  public function setConfiguration(sfProjectConfiguration $configuration = null)
81
  {
82
    $this->configuration = $configuration;
83
  }
84
 
85
  /**
86
   * Returns the filesystem instance.
87
   *
88
   * @return sfFilesystem A sfFilesystem instance
89
   */
90
  public function getFilesystem()
91
  {
92
    if (!isset($this->filesystem))
93
    {
94
      if (null === $this->commandApplication || $this->commandApplication->isVerbose())
95
      {
96
        $this->filesystem = new sfFilesystem($this->dispatcher, $this->formatter);
97
      }
98
      else
99
      {
100
        $this->filesystem = new sfFilesystem();
101
      }
102
    }
103
 
104
    return $this->filesystem;
105
  }
106
 
107
  /**
108
   * Checks if the current directory is a symfony project directory.
109
   *
110
   * @return true if the current directory is a symfony project directory, false otherwise
111
   */
112
  public function checkProjectExists()
113
  {
114
    if (!file_exists('symfony'))
115
    {
116
      throw new sfException('You must be in a symfony project directory.');
117
    }
118
  }
119
 
120
  /**
121
   * Checks if an application exists.
122
   *
123
   * @param  string $app  The application name
124
   *
125
   * @return bool true if the application exists, false otherwise
126
   */
127
  public function checkAppExists($app)
128
  {
129
    if (!is_dir(sfConfig::get('sf_apps_dir').'/'.$app))
130
    {
131
      throw new sfException(sprintf('Application "%s" does not exist', $app));
132
    }
133
  }
134
 
135
  /**
136
   * Checks if a module exists.
137
   *
138
   * @param  string $app     The application name
139
   * @param  string $module  The module name
140
   *
141
   * @return bool true if the module exists, false otherwise
142
   */
143
  public function checkModuleExists($app, $module)
144
  {
145
    if (!is_dir(sfConfig::get('sf_apps_dir').'/'.$app.'/modules/'.$module))
146
    {
147
      throw new sfException(sprintf('Module "%s/%s" does not exist.', $app, $module));
148
    }
149
  }
150
 
151
  /**
152
   * Creates a configuration object.
153
   *
154
   * @param string  $application The application name
155
   * @param string  $env         The environment name
156
   *
157
   * @return sfProjectConfiguration A sfProjectConfiguration instance
158
   */
159
  protected function createConfiguration($application, $env)
160
  {
161
    if (null !== $application)
162
    {
163
      $this->checkAppExists($application);
164
 
165
      require_once sfConfig::get('sf_config_dir').'/ProjectConfiguration.class.php';
166
 
167
      $configuration = ProjectConfiguration::getApplicationConfiguration($application, $env, true, null, $this->dispatcher);
168
    }
169
    else
170
    {
171
      if (file_exists(sfConfig::get('sf_config_dir').'/ProjectConfiguration.class.php'))
172
      {
173
        require_once sfConfig::get('sf_config_dir').'/ProjectConfiguration.class.php';
174
        $configuration = new ProjectConfiguration(null, $this->dispatcher);
175
      }
176
      else
177
      {
178
        $configuration = new sfProjectConfiguration(getcwd(), $this->dispatcher);
179
      }
180
 
181
      if (null !== $env)
182
      {
183
        sfConfig::set('sf_environment', $env);
184
      }
185
 
186
      $this->initializeAutoload($configuration);
187
    }
188
 
189
    return $configuration;
190
  }
191
 
192
  /**
193
   * Returns the first application in apps.
194
   *
195
   * @return string The Application name
196
   */
197
  protected function getFirstApplication()
198
  {
199
    if (count($dirs = sfFinder::type('dir')->maxdepth(0)->follow_link()->relative()->in(sfConfig::get('sf_apps_dir'))))
200
    {
201
      return $dirs[0];
202
    }
203
 
204
    return null;
205
  }
206
 
207
  /**
208
   * Reloads all autoloaders.
209
   *
210
   * This method should be called whenever a task generates new classes that
211
   * are to be loaded by the symfony autoloader. It clears the autoloader
212
   * cache for all applications and environments and the current execution.
213
   *
214
   * @see initializeAutoload()
215
   */
216
  protected function reloadAutoload()
217
  {
218
    $this->initializeAutoload($this->configuration, true);
219
  }
220
 
221
  /**
222
   * Initializes autoloaders.
223
   *
224
   * @param sfProjectConfiguration $configuration The current project or application configuration
225
   * @param boolean                $reload        If true, all autoloaders will be reloaded
226
   */
227
  protected function initializeAutoload(sfProjectConfiguration $configuration, $reload = false)
228
  {
229
    // sfAutoload
230
    if ($reload)
231
    {
232
      $this->logSection('autoload', 'Resetting application autoloaders');
233
 
234
      $finder = sfFinder::type('file')->name('*autoload.yml.php');
235
      $this->getFilesystem()->remove($finder->in(sfConfig::get('sf_cache_dir')));
236
      sfAutoload::getInstance()->reloadClasses(true);
237
    }
238
 
239
    // sfSimpleAutoload
240
    if (!$configuration instanceof sfApplicationConfiguration)
241
    {
242
      // plugins
243
      if ($reload)
244
      {
245
        foreach ($configuration->getPlugins() as $name)
246
        {
247
          $configuration->getPluginConfiguration($name)->initializeAutoload();
248
        }
249
      }
250
 
251
      // project
252
      $autoload = sfSimpleAutoload::getInstance(sfConfig::get('sf_cache_dir').'/project_autoload.cache');
253
      $autoload->loadConfiguration(sfFinder::type('file')->name('autoload.yml')->in(array(
254
        sfConfig::get('sf_symfony_lib_dir').'/config/config',
255
        sfConfig::get('sf_config_dir'),
256
      )));
257
      $autoload->register();
258
 
259
      if ($reload)
260
      {
261
        $this->logSection('autoload', 'Resetting CLI autoloader');
262
        $autoload->reload();
263
      }
264
    }
265
  }
266
 
267
  /**
268
   * Mirrors a directory structure inside the created project.
269
   *
270
   * @param string   $dir    The directory to mirror
271
   * @param sfFinder $finder A sfFinder instance to use for the mirroring
272
   */
273
  protected function installDir($dir, $finder = null)
274
  {
275
    if (null === $finder)
276
    {
277
      $finder = sfFinder::type('any')->discard('.sf');
278
    }
279
 
280
    $this->getFilesystem()->mirror($dir, sfConfig::get('sf_root_dir'), $finder);
281
  }
282
 
283
  /**
284
   * Replaces tokens in files contained in a given directory.
285
   *
286
   * If you don't pass a directory, it will replace in the config/ and lib/ directory.
287
   *
288
   * You can define global tokens by defining the $this->tokens property.
289
   *
290
   * @param array $dirs   An array of directory where to do the replacement
291
   * @param array $tokens An array of tokens to use
292
   */
293
  protected function replaceTokens($dirs = array(), $tokens = array())
294
  {
295
    if (!$dirs)
296
    {
297
      $dirs = array(sfConfig::get('sf_config_dir'), sfConfig::get('sf_lib_dir'));
298
    }
299
 
300
    $tokens = array_merge(isset($this->tokens) ? $this->tokens : array(), $tokens);
301
 
302
    $this->getFilesystem()->replaceTokens(sfFinder::type('file')->prune('vendor')->in($dirs), '##', '##', $tokens);
303
  }
304
 
305
  /**
306
   * Reloads tasks.
307
   *
308
   * Useful when you install plugins with tasks and if you want to use them with the runTask() method.
309
   */
310
  protected function reloadTasks()
311
  {
312
    if (null === $this->commandApplication)
313
    {
314
      return;
315
    }
316
 
317
    $this->configuration = $this->createConfiguration(null, null);
318
 
319
    $this->commandApplication->clearTasks();
320
    $this->commandApplication->loadTasks($this->configuration);
321
 
322
    $disabledPluginsRegex = sprintf('#^(%s)#', implode('|', array_diff($this->configuration->getAllPluginPaths(), $this->configuration->getPluginPaths())));
323
    $tasks = array();
324
    foreach (get_declared_classes() as $class)
325
    {
326
      $r = new Reflectionclass($class);
327
      if ($r->isSubclassOf('sfTask') && !$r->isAbstract() && !preg_match($disabledPluginsRegex, $r->getFileName()))
328
      {
329
        $tasks[] = new $class($this->dispatcher, $this->formatter);
330
      }
331
    }
332
 
333
    $this->commandApplication->registerTasks($tasks);
334
  }
335
 
336
  /**
337
   * Enables a plugin in the ProjectConfiguration class.
338
   *
339
   * @param string $plugin The name of the plugin
340
   */
341
  protected function enablePlugin($plugin)
342
  {
343
    sfSymfonyPluginManager::enablePlugin($plugin, sfConfig::get('sf_config_dir'));
344
  }
345
 
346
  /**
347
   * Disables a plugin in the ProjectConfiguration class.
348
   *
349
   * @param string $plugin The name of the plugin
350
   */
351
  protected function disablePlugin($plugin)
352
  {
353
    sfSymfonyPluginManager::disablePlugin($plugin, sfConfig::get('sf_config_dir'));
354
  }
355
 
356
  /**
357
   * Returns a plugin manager instance.
358
   *
359
   * @return sfSymfonyPluginManager A sfSymfonyPluginManager instance
360
   */
361
  protected function getPluginManager()
362
  {
363
    if (null === $this->pluginManager)
364
    {
365
      $environment = new sfPearEnvironment($this->dispatcher, array(
366
        'plugin_dir' => sfConfig::get('sf_plugins_dir'),
367
        'cache_dir'  => sfConfig::get('sf_cache_dir').'/.pear',
368
        'web_dir'    => sfConfig::get('sf_web_dir'),
369
        'config_dir' => sfConfig::get('sf_config_dir'),
370
      ));
371
 
372
      $this->pluginManager = new sfSymfonyPluginManager($this->dispatcher, $environment);
373
    }
374
 
375
    return $this->pluginManager;
376
  }
377
 
378
  /**
379
   * @see sfCommandApplicationTask
380
   */
381
  protected function createTask($name)
382
  {
383
    $task = parent::createTask($name);
384
 
385
    if ($task instanceof sfBaseTask)
386
    {
387
      $task->setConfiguration($this->configuration);
388
    }
389
 
390
    return $task;
391
  }
392
}