Development

Changeset 7614

You must first sign up to be able to contribute.

Changeset 7614

Show
Ignore:
Timestamp:
02/26/08 18:38:26 (4 months ago)
Author:
fabien
Message:

added a new configuration system

  • added a new sfProjectConfiguration and sfApplicationConfiguration classes
  • all config.php file are gone and replaced with ProjectConfiguration? and #APP_NAME#Configuration classes
  • sfCore has been removed
  • sfLoader static methods have been moved to sfProjectConfiguration and sfApplicationConfiguration
  • sfI18N now takes a configuration object as its first argument
  • sfGeneratorManager now takes a configuration object as its first argument
  • sfConfigCache is not a singleton anymore
  • SF_* constants are gone
  • sfDatabaseManager now takes a configuration object as its first argument

Please read the UPGRADE file to upgrade your projects

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/1.1/UPGRADE

    r7518 r7614  
    1212To upgrade a project: 
    1313 
    14   * Upgrade symfony via PEAR or change your `config/config.php` 
    15     to update the symfony directory. 
     14  * If you don't use a SCM tool, please make a backup of your project. 
     15    As symfony replaces some files during the upgrade 
     16    (front controllers for example), you need a way to merge your 
     17    customizations after the upgrade. 
    1618 
    1719  * Update the `symfony` file located in the project root directory 
    18     by changing the line: 
    19  
     20    by changing those three lines: 
     21 
     22        [php] 
     23        chdir(dirname(__FILE__)); 
     24        include('config/config.php'); 
    2025        include($sf_symfony_data_dir.'/bin/symfony.php'); 
    2126 
    2227    to 
    2328 
    24         include($sf_symfony_lib_dir.'/command/cli.php'); 
     29        [php] 
     30        chdir(dirname(__FILE__)); 
     31        require_once(dirname(__FILE__).'/lib/ProjectConfiguration.class.php'); 
     32        $configuration = new ProjectConfiguration(); 
     33        include($configuration->getSymfonyLibDir().'/command/cli.php'); 
     34 
     35    You can also copy the skeleton file from the symfony project skeleton directly: 
     36 
     37        $ cp /path/to/symfony/lib/task/generator/skeleton/project/symfony symfony 
     38 
     39  * Create a `lib/ProjectConfiguration.class.php` file with the following content: 
     40 
     41        [php] 
     42        <?php 
     43 
     44        require_once '##SYMFONY_LIB_DIR##/autoload/sfCoreAutoload.class.php'; 
     45        sfCoreAutoload::register(); 
     46 
     47        class ProjectConfiguration extends sfProjectConfiguration 
     48        { 
     49          public function setup() 
     50          { 
     51          } 
     52        } 
     53 
     54    Then, replace `##SYMFONY_LIB_DIR##` with the path to the symfony 1.1 
     55    `lib/` directory. This is the new way to change the symfony version used 
     56    for your project. 
     57 
     58    You can also copy the skeleton file from the symfony project skeleton directly: 
     59 
     60        $ cp /path/to/symfony/lib/task/generator/skeleton/project/lib/ProjectConfiguration.class.php lib/ProjectConfiguration.class.php 
    2561 
    2662  * Launch the `project:upgrade1.1` task from your project directory 
     
    213249 
    214250The `autoloading_function` setting in `settings.yml` is not used anymore. 
    215 You can register autoloading callables in the application `config.php`. 
    216 Here is the new default `config.php`: 
    217  
    218     [php] 
    219     <?php 
    220      
    221     // include project configuration 
    222     include(SF_ROOT_DIR.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php'); 
    223      
    224     // symfony bootstraping 
    225     require_once($sf_symfony_lib_dir.'/util/sfCore.class.php'); 
    226     sfCore::bootstrap($sf_symfony_lib_dir, $sf_symfony_data_dir); 
    227      
    228     // insert your own autoloading callables here 
    229      
    230     if (sfConfig::get('sf_debug')) 
    231     { 
    232       spl_autoload_register(array('sfAutoload', 'autoloadAgain')); 
    233     } 
     251You can register autoloading callables in your application configuration class. 
    234252 
    235253Thanks to the new `sfAutoload::autoloadAgain()` method, you won't need to clear 
    236254the cache when you add or move classes in your project. This method will 
    237255automatically find the changes and flush the autoloading cache. 
    238  
    239 The `project:upgrade1.1` task makes all those changes for you. 
    240256 
    241257VERSION 
     
    466482 
    467483The symfony core has been upgraded to take these changes into account. 
     484 
     485sfLoader 
     486-------- 
     487 
     488All `sfLoader` static methods (except `::getHelperDirs()` and `::loadHelpers()`) 
     489have been moved to the `sfProjectConfiguration` and `sfApplicationConfiguration` 
     490classes: 
     491 
     492  * `sfProjectConfiguration`: 
     493      * `->getGeneratorSkeletonDirs()` 
     494      * `->getGeneratorTemplate()` 
     495      * `->getGeneratorTemplateDirs()` 
     496      * `->getModelDirs()` 
     497 
     498  * `sfApplicationConfiguration`: 
     499      * `->getControllerDirs()` 
     500      * `->getTemplateDirs()` 
     501      * `->getTemplateDir()` 
     502      * `->getTemplatePath()` 
     503      * `->getI18NGlobalDirs()` 
     504      * `->getI18NDirs()` 
     505      * `->getConfigPaths()` 
     506 
     507sfCore 
     508------ 
     509 
     510The `sfCore` has been removed. The code has been moved to `sfProjectConfiguration`, 
     511`sfApplicationConfiguration`, and `sfContext` classes. 
     512 
     513Front Controllers 
     514----------------- 
     515 
     516All front controllers have to be upgraded. The SF_DEBUG, SF_APP, SF_ENVIRONMENT, 
     517and SF_ROOT_DIR constants are gone. If you use some of these constants in your 
     518project, please use their sfConfig::get('') counterparts: 
     519 
     520 *Old*             | *New* 
     521 ----------------- | --------------------------------- 
     522 `SF_ROOT_DIR`     | `sfConfig::get('sf_root_dir')` 
     523 `SF_ENVIRONMENT`  | `sfConfig::get('sf_environment')` 
     524 `SF_APP`          | `sfConfig::get('sf_app')` 
     525 `SF_DEBUG`        | `sfConfig::get('sf_debug')` 
     526 
     527The `project:upgrade1.1` task upgrades all front controllers for you. 
     528If you made some customizations, symfony will issue a warning and won't 
     529upgrade them automatically. You can then copy the default skeleton from 
     530symfony: /path/to/symfony/lib/task/generator/skeleton/app/web/index.php 
     531 
     532config.php 
     533---------- 
     534 
     535All `config.php` files have been removed. The are replaced by the `ProjectConfiguration` 
     536class and the application configuration classes. 
     537 
     538If you've added some cutomizations in `config.php` files, you will have to migrate them 
     539to those new classes. 
  • branches/1.1/lib/action/sfAction.class.php

    r6668 r7614  
    3636 
    3737    // include security configuration 
    38     if($file = sfConfigCache::getInstance()->checkConfig(sfConfig::get('sf_app_module_dir_name').'/'.$this->getModuleName().'/'.sfConfig::get('sf_app_module_config_dir_name').'/security.yml', true)) 
     38    if ($file = $context->getConfigCache()->checkConfig(sfConfig::get('sf_app_module_dir_name').'/'.$this->getModuleName().'/'.sfConfig::get('sf_app_module_config_dir_name').'/security.yml', true)) 
    3939    { 
    4040      require($file); 
  • branches/1.1/lib/autoload/sfAutoload.class.php

    r7247 r7614  
    8787  public function reloadClasses($force = false) 
    8888  { 
    89     if ($force) 
     89    $configuration = sfProjectConfiguration::getActive(); 
     90    if (!$configuration || !$configuration instanceof sfApplicationConfiguration) 
    9091    { 
    91       @unlink(sfConfigCache::getInstance()->getCacheName(sfConfig::get('sf_app_config_dir_name').'/autoload.yml'))
     92      return
    9293    } 
    9394 
    94     $file = sfConfigCache::getInstance()->checkConfig(sfConfig::get('sf_app_config_dir_name').'/autoload.yml'); 
     95    if ($force && file_exists($configuration->getConfigCache()->getCacheName('config/autoload.yml'))) 
     96    { 
     97      unlink($configuration->getConfigCache()->getCacheName('config/autoload.yml')); 
     98    } 
     99 
     100    $file = $configuration->getConfigCache()->checkConfig('config/autoload.yml'); 
    95101 
    96102    $this->classes = include($file); 
     
    125131  } 
    126132 
    127   function autoloadAgain($class) 
     133  public function autoloadAgain($class) 
    128134  { 
    129135    self::reloadClasses(true); 
  • branches/1.1/lib/autoload/sfCoreAutoload.class.php

    r7452 r7614  
    158158  'sfFormatter' => 'command', 
    159159  'sfSymfonyCommandApplication' => 'command', 
     160  'sfApplicationConfiguration' => 'config', 
    160161  'sfAutoloadConfigHandler' => 'config', 
    161162  'sfCacheConfigHandler' => 'config', 
     
    170171  'sfGeneratorConfigHandler' => 'config', 
    171172  'sfLoader' => 'config', 
     173  'sfProjectConfiguration' => 'config', 
    172174  'sfRootConfigHandler' => 'config', 
    173175  'sfRoutingConfigHandler' => 'config', 
     
    315317  'sfProjectUnfreezeTask' => 'task/project', 
    316318  'sfUpgradeTo11Task' => 'task/project', 
    317   'sfAutoloadingUpgrade' => 'task/project/upgrade1.1', 
    318319  'sfComponentUpgrade' => 'task/project/upgrade1.1', 
    319320  'sfConfigFileUpgrade' => 'task/project/upgrade1.1', 
     
    325326  'sfPropelUpgrade' => 'task/project/upgrade1.1', 
    326327  'sfSingletonUpgrade' => 'task/project/upgrade1.1', 
     328  'sfTestUpgrade' => 'task/project/upgrade1.1', 
    327329  'sfUpgrade' => 'task/project/upgrade1.1', 
    328330  'sfWebDebugUpgrade' => 'task/project/upgrade1.1', 
     
    341343  'sfCallable' => 'util', 
    342344  'sfContext' => 'util', 
    343   'sfCore' => 'util', 
    344345  'sfDomCssSelector' => 'util', 
    345346  'sfFinder' => 'util', 
  • branches/1.1/lib/command/sfSymfonyCommandApplication.class.php

    r7467 r7614  
    3131    } 
    3232 
    33     // initialize symfony core autoloading 
    34     require_once($this->options['symfony_lib_dir'].'/autoload/sfCoreAutoload.class.php'); 
    35     sfCoreAutoload::getInstance()->register(); 
     33    $configuration = new sfProjectConfiguration(getcwd()); 
    3634 
    3735    // application 
     
    3937    $this->setVersion(SYMFONY_VERSION); 
    4038 
    41     $this->initializeEnvironment($this->options['symfony_lib_dir']); 
    4239    $this->initializeTasks(); 
    4340  } 
     
    7471 
    7572  /** 
    76    * Initializes the environment variables and include path. 
    77    * 
    78    * @param string The symfony lib directory 
    79    */ 
    80   protected function initializeEnvironment($symfonyLibDir) 
    81   { 
    82     sfConfig::set('sf_symfony_lib_dir', $symfonyLibDir); 
    83  
    84     // directory layout 
    85     sfCore::initDirectoryLayout(getcwd()); 
    86  
    87     // include path 
    88     set_include_path( 
    89       sfConfig::get('sf_lib_dir').PATH_SEPARATOR. 
    90       sfConfig::get('sf_app_lib_dir').PATH_SEPARATOR. 
    91       sfConfig::get('sf_model_dir').PATH_SEPARATOR. 
    92       get_include_path() 
    93     ); 
    94   } 
    95  
    96   /** 
    9773   * Loads all available tasks. 
    9874   * 
     
    10278  { 
    10379    $dirs = array( 
    104       sfConfig::get('sf_symfony_lib_dir').'/task',                // symfony tasks 
    105       sfConfig::get('sf_symfony_lib_dir').'/plugins/*/lib/task', // bundled plugin tasks 
    106       sfConfig::get('sf_plugins_dir').'/*/lib/task',              // plugin tasks 
    107       sfConfig::get('sf_lib_dir').'/task',                        // project tasks 
     80      sfConfig::get('sf_symfony_lib_dir').'/task',               // symfony tasks 
     81      sfConfig::get('sf_symfony_lib_dir').'/plugins/*/lib/task', // bundled plugin tasks 
     82      sfConfig::get('sf_plugins_dir').'/*/lib/task',             // plugin tasks 
     83      sfConfig::get('sf_lib_dir').'/task',                       // project tasks 
    10884    ); 
    10985    $finder = sfFinder::type('file')->name('*Task.class.php'); 
     86 
    11087    foreach ($dirs as $globDir) 
    11188    { 
  • branches/1.1/lib/config/config/core_compile.yml

    r5320 r7614  
    44- %SF_SYMFONY_LIB_DIR%/action/sfActionStack.class.php 
    55- %SF_SYMFONY_LIB_DIR%/action/sfActionStackEntry.class.php 
    6 #- %SF_SYMFONY_LIB_DIR%/config/sfLoader.class.php 
    76- %SF_SYMFONY_LIB_DIR%/controller/sfController.class.php 
    87- %SF_SYMFONY_LIB_DIR%/database/sfDatabaseManager.class.php 
    9 - %SF_SYMFONY_LIB_DIR%/event/sfEvent.class.php 
    10 - %SF_SYMFONY_LIB_DIR%/event/sfEventDispatcher.class.php 
    118- %SF_SYMFONY_LIB_DIR%/filter/sfFilter.class.php 
    129- %SF_SYMFONY_LIB_DIR%/filter/sfCommonFilter.class.php 
     
    1815- %SF_SYMFONY_LIB_DIR%/storage/sfStorage.class.php 
    1916- %SF_SYMFONY_LIB_DIR%/user/sfUser.class.php 
    20 #- %SF_SYMFONY_LIB_DIR%/util/sfContext.class.php 
    21 #- %SF_SYMFONY_LIB_DIR%/validator/sfValidatorManager.class.php 
    22 #- %SF_SYMFONY_LIB_DIR%/util/sfParameterHolder.class.php 
    2317- %SF_SYMFONY_LIB_DIR%/view/sfView.class.php 
    2418 
    2519# these classes are optionals but very likely to be used (in web context) 
    26 #- %SF_SYMFONY_LIB_DIR%/controller/sfRouting.class.php 
    2720- %SF_SYMFONY_LIB_DIR%/controller/sfWebController.class.php 
    2821- %SF_SYMFONY_LIB_DIR%/controller/sfFrontWebController.class.php 
  • branches/1.1/lib/config/sfCompileConfigHandler.class.php

    r7370 r7614  
    6565 
    6666      // insert configuration files 
    67       $contents = preg_replace_callback(array('#(require|include)(_once)?\((sfConfigCache::getInstance\(\)|\$configCache)->checkConfig\([^_]+sf_app_config_dir_name[^\.]*\.\'/([^\']+)\'\)\);#m', 
    68                                           '#()()(sfConfigCache::getInstance\(\)|\$configCache)->import\(.sf_app_config_dir_name\.\'/([^\']+)\'(, false)?\);#m'), 
     67/*      $contents = preg_replace_callback(array('#(require|include)(_once)?\((sfContext::getInstance\(\)\->getConfigCache\(\)|\$configCache)->checkConfig\(\'config/([^\']+)\'\)\);#m', 
     68                                          '#()()(sfContext::getInstance\(\)\->getConfigCache\(\)|\$configCache)->import\(\'config/([^\']+)\'(, false)?\);#m'), 
    6969                                        array($this, 'insertConfigFileCallback'), $contents); 
    70  
     70*/ 
    7171      // strip php tags 
    7272      $contents = sfToolkit::pregtr($contents, array('/^\s*<\?(php)?/m' => '', 
     
    103103    $configFile = sfConfig::get('sf_app_config_dir_name').'/'.$matches[4]; 
    104104 
    105     sfConfigCache::getInstance()->checkConfig($configFile); 
     105    $configCache = sfContext::getInstance()->getConfigCache(); 
     106    $configCache->checkConfig($configFile); 
    106107 
    107     $config = "// '$configFile' config file\n". 
    108               file_get_contents(sfConfigCache::getInstance()->getCacheName($configFile)); 
     108    $config = "// '$configFile' config file\n".file_get_contents($configCache->getCacheName($configFile)); 
    109109 
    110110    return $config; 
  • branches/1.1/lib/config/sfConfigCache.class.php

    r7436 r7614  
    2424{ 
    2525  protected 
    26     $handlers = array(), 
    27     $userHandlers = array(); 
    28  
    29   protected static 
    30     $instance = null; 
    31  
    32   /** 
    33    * Retrieves the singleton instance of this class. 
    34    * 
    35    * @return sfConfigCache A sfConfigCache instance 
    36    */ 
    37   public static function getInstance() 
    38   { 
    39     if (!self::$instance) 
    40     { 
    41       self::$instance = new sfConfigCache(); 
    42     } 
    43  
    44     return self::$instance; 
     26    $configuration = null, 
     27    $handlers      = array(), 
     28    $userHandlers  = array(); 
     29 
     30  /** 
     31   * Constructor 
     32   * 
     33   * @param sfApplicationConfiguration A sfApplicationConfiguration instance 
     34   */ 
     35  public function __construct(sfApplicationConfiguration $configuration) 
     36  { 
     37    $this->configuration = $configuration; 
    4538  } 
    4639 
     
    140133   * 
    141134   * If the configuration file path is relative, symfony will look in directories  
    142    * defined in the sfLoader::getConfigPaths() method. 
     135   * defined in the sfConfiguration::getConfigPaths() method. 
    143136   * 
    144137   * @param string A filesystem path to a configuration file 
     
    148141   * @throws <b>sfConfigurationException</b> If a requested configuration file does not exist 
    149142   * 
    150    * @see sfLoader::getConfigPaths() 
     143   * @see sfConfiguration::getConfigPaths() 
    151144   */ 
    152145  public function checkConfig($configPath, $optional = false) 
     
    167160    if (!sfToolkit::isPathAbsolute($configPath)) 
    168161    { 
    169       $files = sfLoader::getConfigPaths($configPath); 
     162      $files = $this->configuration->getConfigPaths($configPath); 
    170163    } 
    171164    else 
  • branches/1.1/lib/config/sfFactoryConfigHandler.class.php

    r7518 r7614  
    155155                     "    \$class = sfConfig::get('sf_factory_i18n', '%s');\n". 
    156156                     "%s". 
    157                      "    \$this->factories['i18n'] = new \$class(\$this->dispatcher, \$cache, %s);\n". 
     157                     "    \$this->factories['i18n'] = new \$class(\$this->configuration, \$cache, %s);\n". 
    158158                     "  }\n" 
    159159                     , $class, $cache, var_export($parameters, true) 
  • branches/1.1/lib/config/sfGeneratorConfigHandler.class.php

    r6457 r7614  
    6060 
    6161    // generate class and add a reference to it 
    62     $generatorManager = new sfGeneratorManager(); 
     62    $generatorManager = new sfGeneratorManager(sfContext::getInstance()->getConfiguration()); 
    6363 
    6464    // generator parameters 
  • branches/1.1/lib/config/sfLoader.class.php

    r7302 r7614  
    1919class sfLoader 
    2020{ 
    21   /** 
    22    * Gets directories where model classes are stored. 
    23    * 
    24    * @return array An array of directories 
    25    */ 
    26   static public function getModelDirs() 
    27   { 
    28     $dirs = array(sfConfig::get('sf_lib_dir').'/model' ? sfConfig::get('sf_lib_dir').'/model' : 'lib/model'); // project 
    29     if ($pluginDirs = glob(sfConfig::get('sf_plugins_dir').'/*/lib/model')) 
    30     { 
    31       $dirs = array_merge($dirs, $pluginDirs);                                                                // plugins 
    32     } 
    33  
    34     return $dirs; 
    35   } 
    36  
    37   /** 
    38    * Gets directories where controller classes are stored for a given module. 
    39    * 
    40    * @param string The module name 
    41    * 
    42    * @return array An array of directories 
    43    */ 
    44   static public function getControllerDirs($moduleName) 
    45   { 
    46     $suffix = $moduleName.'/'.sfConfig::get('sf_app_module_action_dir_name'); 
    47  
    48     $dirs = array(); 
    49     foreach (sfConfig::get('sf_module_dirs', array()) as $key => $value) 
    50     { 
    51       $dirs[$key.'/'.$suffix] = $value; 
    52     } 
    53  
    54     $dirs[sfConfig::get('sf_app_module_dir').'/'.$suffix] = false;                                     // application 
    55  
    56     if ($pluginDirs = glob(sfConfig::get('sf_plugins_dir').'/*/modules/'.$suffix)) 
    57     { 
    58       $dirs = array_merge($dirs, array_combine($pluginDirs, array_fill(0, count($pluginDirs), true))); // plugins 
    59     } 
    60  
    61     $dirs[sfConfig::get('sf_symfony_lib_dir').'/controller/'.$suffix] = true;                          // core modules 
    62  
    63     return $dirs; 
    64   } 
    65  
    66   /** 
    67    * Gets directories where template files are stored for a given module. 
    68    * 
    69    * @param string The module name 
    70    * 
    71    * @return array An array of directories 
    72    */ 
    73   static public function getTemplateDirs($moduleName) 
    74   { 
    75     $suffix = $moduleName.'/'.sfConfig::get('sf_app_module_template_dir_name'); 
    76  
    77     $dirs = array(); 
    78     foreach (sfConfig::get('sf_module_dirs', array()) as $key => $value) 
    79     { 
    80       $dirs[] = $key.'/'.$suffix; 
    81     } 
    82  
    83     $dirs[] = sfConfig::get('sf_app_module_dir').'/'.$suffix;                        // application 
    84  
    85     if ($pluginDirs = glob(sfConfig::get('sf_plugins_dir').'/*/modules/'.$suffix)) 
    86     { 
    87       $dirs = array_merge($dirs, $pluginDirs);                                       // plugins 
    88     } 
    89  
    90     $dirs[] = sfConfig::get('sf_symfony_lib_dir').'/controller/'.$suffix;            // core modules 
    91     $dirs[] = sfConfig::get('sf_module_cache_dir').'/auto'.ucfirst($suffix);         // generated templates in cache 
    92  
    93     return $dirs; 
    94   } 
    95  
    96   /** 
    97    * Gets the template directory to use for a given module and template file. 
    98    * 
    99    * @param string The module name 
    100    * @param string The template file 
    101    * 
    102    * @return string A template directory 
    103    */ 
    104   static public function getTemplateDir($moduleName, $templateFile) 
    105   { 
    106     $dirs = self::getTemplateDirs($moduleName); 
    107     foreach ($dirs as $dir) 
    108     { 
    109       if (is_readable($dir.'/'.$templateFile)) 
    110       { 
    111         return $dir; 
    112       } 
    113     } 
    114  
    115     return null; 
    116   } 
    117  
    118   /** 
    119    * Gets the template to use for a given module and template file. 
    120    * 
    121    * @param string The module name 
    122    * @param string The template file 
    123    * 
    124    * @return string A template path 
    125    */ 
    126   static public function getTemplatePath($moduleName, $templateFile) 
    127   { 
    128     $dir = self::getTemplateDir($moduleName, $templateFile); 
    129  
    130     return $dir ? $dir.'/'.$templateFile : null; 
    131   } 
    132  
    133   /** 
    134    * Gets the i18n directories to use globally. 
    135    * 
    136    * @return array An array of i18n directories 
    137    */ 
    138   static public function getI18NGlobalDirs() 
    139   { 
    140     $dirs = array(); 
    141  
    142     // application 
    143     if (is_dir($dir = sfConfig::get('sf_app_dir').'/'.sfConfig::get('sf_app_module_i18n_dir_name'))) 
    144     { 
    145       $dirs[] = $dir; 
    146     } 
    147  
    148     // plugins 
    149     $pluginDirs = glob(sfConfig::get('sf_plugins_dir').'/*/'.sfConfig::get('sf_app_module_i18n_dir_name')); 
    150     if (isset($pluginDirs[0])) 
    151     { 
    152       $dirs[] = $pluginDirs[0]; 
    153     } 
    154  
    155     return $dirs; 
    156   } 
    157  
    158   /** 
    159    * Gets the i18n directories to use for a given module. 
    160    * 
    161    * @param string The module name 
    162    * 
    163    * @return array An array of i18n directories 
    164    */ 
    165   static public function getI18NDirs($moduleName) 
    166   { 
    167     $dirs = array(); 
    168  
    169     // module 
    170     if (is_dir($dir = sfConfig::get('sf_app_module_dir').'/'.$moduleName.'/'.sfConfig::get('sf_app_module_i18n_dir_name'))) 
    171     { 
    172       $dirs[] = $dir; 
    173     } 
    174  
    175     // application 
    176     if (is_dir($dir = sfConfig::get('sf_app_dir').'/'.sfConfig::get('sf_app_module_i18n_dir_name'))) 
    177     { 
    178       $dirs[] = $dir; 
    179     } 
    180  
    181     // module in plugins 
    182     $pluginDirs = glob(sfConfig::get('sf_plugins_dir').'/*/modules/'.$moduleName.'/'.sfConfig::get('sf_app_module_i18n_dir_name')); 
    183     if (isset($pluginDirs[0])) 
    184     { 
    185       $dirs[] = $pluginDirs[0]; 
    186     } 
    187  
    188     // plugins 
    189     $pluginDirs = glob(sfConfig::get('sf_plugins_dir').'/*/'.sfConfig::get('sf_app_module_i18n_dir_name')); 
    190     if (isset($pluginDirs[0])) 
    191     { 
    192       $dirs[] = $pluginDirs[0]; 
    193     } 
    194  
    195     return $dirs; 
    196   } 
    197  
    198   /** 
    199    * Gets directories where template files are stored for a generator class and a specific theme. 
    200    * 
    201    * @param string The generator class name 
    202    * @param string The theme name 
    203    * 
    204    * @return array An array of directories 
    205    */ 
    206   static public function getGeneratorTemplateDirs($class, $theme) 
    207   { 
    208     $dirs = array(sfConfig::get('sf_data_dir').'/generator/'.$class.'/'.$theme.'/template');                  // project 
    209  
    210     if ($pluginDirs = glob(sfConfig::get('sf_plugins_dir').'/*/data/generator/'.$class.'/'.$theme.'/template')) 
    211     { 
    212       $dirs = array_merge($dirs, $pluginDirs);                                                                // plugin 
    213     } 
    214  
    215     if ($bundledPluginDirs = glob(sfConfig::get('sf_symfony_lib_dir').'/plugins/*/data/generator/'.$class.'/'.$theme.'/template')) 
    216     { 
    217       $dirs = array_merge($dirs, $bundledPluginDirs);                                                         // bundled plugin 
    218     } 
    219  
    220     return $dirs; 
    221   } 
    222  
    223   /** 
    224    * Gets directories where the skeleton is stored for a generator class and a specific theme. 
    225    * 
    226    * @param string The generator class name 
    227    * @param string The theme name 
    228    * 
    229    * @return array An array of directories 
    230    */ 
    231   static public function getGeneratorSkeletonDirs($class, $theme) 
    232   { 
    233     $dirs = array(sfConfig::get('sf_data_dir').'/generator/'.$class.'/'.$theme.'/skeleton');                  // project 
    234  
    235     if ($pluginDirs = glob(sfConfig::get('sf_plugins_dir').'/*/data/generator/'.$class.'/'.$theme.'/skeleton')) 
    236     { 
    237       $dirs = array_merge($dirs, $pluginDirs);                                                                // plugin 
    238     } 
    239  
    240     if ($bundledPluginDirs = glob(sfConfig::get('sf_symfony_lib_dir').'/plugins/*/data/generator/'.$class.'/'.$theme.'/skeleton')) 
    241     { 
    242       $dirs = array_merge($dirs, $bundledPluginDirs);                                                         // bundled plugin 
    243     } 
    244  
    245     return $dirs; 
    246   } 
    247  
    248   /** 
    249    * Gets the template to use for a generator class. 
    250    * 
    251    * @param string The generator class name 
    252    * @param string The theme name 
    253    * @param string The template path 
    254    * 
    255    * @return string A template path 
    256    * 
    257    * @throws sfException 
    258    */ 
    259   static public function getGeneratorTemplate($class, $theme, $path) 
    260   { 
    261     $dirs = self::getGeneratorTemplateDirs($class, $theme); 
    262     foreach ($dirs as $dir) 
    263     { 
    264       if (is_readable($dir.'/'.$path)) 
    265       { 
    266         return $dir.'/'.$path; 
    267       } 
    268     } 
    269  
    270     throw new sfException(sprintf('Unable to load "%s" generator template in: %s.', $path, implode(', ', $dirs))); 
    271