sfFactoryConfigHandler.class.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. <?php
  2. /*
  3. * This file is part of the symfony package.
  4. * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
  5. * (c) 2004-2006 Sean Kerr <sean@code-box.org>
  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. * sfFactoryConfigHandler allows you to specify which factory implementation the
  12. * system will use.
  13. *
  14. * @package symfony
  15. * @subpackage config
  16. * @author Fabien Potencier <fabien.potencier@symfony-project.com>
  17. * @author Sean Kerr <sean@code-box.org>
  18. * @version SVN: $Id: sfFactoryConfigHandler.class.php 11955 2008-10-05 16:11:51Z fabien $
  19. */
  20. class sfFactoryConfigHandler extends sfYamlConfigHandler
  21. {
  22. /**
  23. * Executes this configuration handler.
  24. *
  25. * @param array $configFiles An array of absolute filesystem path to a configuration file
  26. *
  27. * @return string Data to be written to a cache file
  28. *
  29. * @throws <b>sfConfigurationException</b> If a requested configuration file does not exist or is not readable
  30. * @throws <b>sfParseException</b> If a requested configuration file is improperly formatted
  31. */
  32. public function execute($configFiles)
  33. {
  34. // parse the yaml
  35. $config = self::getConfiguration($configFiles);
  36. // init our data and includes arrays
  37. $includes = array();
  38. $instances = array();
  39. // available list of factories
  40. $factories = array('logger', 'i18n', 'routing', 'controller', 'request', 'response', 'storage', 'user', 'view_cache');
  41. // let's do our fancy work
  42. foreach ($factories as $factory)
  43. {
  44. // see if the factory exists for this controller
  45. $keys = $config[$factory];
  46. if (!isset($keys['class']))
  47. {
  48. // missing class key
  49. throw new sfParseException(sprintf('Configuration file "%s" specifies category "%s" with missing class key.', $configFiles[0], $factory));
  50. }
  51. $class = $keys['class'];
  52. if (isset($keys['file']))
  53. {
  54. // we have a file to include
  55. if (!is_readable($keys['file']))
  56. {
  57. // factory file doesn't exist
  58. throw new sfParseException(sprintf('Configuration file "%s" specifies class "%s" with nonexistent or unreadable file "%s".', $configFiles[0], $class, $keys['file']));
  59. }
  60. // append our data
  61. $includes[] = sprintf("require_once('%s');", $keys['file']);
  62. }
  63. // parse parameters
  64. $parameters = array();
  65. if (isset($keys['param']))
  66. {
  67. if (!is_array($keys['param']))
  68. {
  69. throw new InvalidArgumentException(sprintf('The "param" key for the "%s" factory must be an array (in %s).', $class, $configFiles[0]));
  70. }
  71. $parameters = $keys['param'];
  72. }
  73. // append new data
  74. switch ($factory)
  75. {
  76. case 'controller':
  77. $instances[] = sprintf(" \$class = sfConfig::get('sf_factory_controller', '%s');\n \$this->factories['controller'] = new \$class(\$this);", $class);
  78. break;
  79. case 'request':
  80. $instances[] = sprintf(" \$class = sfConfig::get('sf_factory_request', '%s');\n \$this->factories['request'] = new \$class(\$this->dispatcher, array(), sfConfig::get('sf_factory_request_parameters', %s), sfConfig::get('sf_factory_request_attributes', array()));", $class, var_export($parameters, true));
  81. break;
  82. case 'response':
  83. $instances[] = sprintf(" \$class = sfConfig::get('sf_factory_response', '%s');\n \$this->factories['response'] = new \$class(\$this->dispatcher, sfConfig::get('sf_factory_response_parameters', array_merge(array('http_protocol' => isset(\$_SERVER['SERVER_PROTOCOL']) ? \$_SERVER['SERVER_PROTOCOL'] : null), %s)));", $class, var_export($parameters, true));
  84. // TODO: this is a bit ugly, as it only works for sfWebRequest & sfWebResponse combination. see #3397
  85. $instances[] = sprintf(" if (\$this->factories['request'] instanceof sfWebRequest \n && \$this->factories['response'] instanceof sfWebResponse \n && 'HEAD' == \$this->factories['request']->getMethodName())\n { \n \$this->factories['response']->setHeaderOnly(true);\n }\n");
  86. break;
  87. case 'storage':
  88. $defaultParameters = array();
  89. $defaultParameters[] = sprintf("'auto_shutdown' => false, 'session_id' => \$this->getRequest()->getParameter('%s'),", $parameters['session_name']);
  90. if (is_subclass_of($class, 'sfDatabaseSessionStorage'))
  91. {
  92. $defaultParameters[] = sprintf("'database' => \$this->getDatabaseManager()->getDatabase('%s'),", isset($parameters['database']) ? $parameters['database'] : 'default');
  93. unset($parameters['database']);
  94. }
  95. $instances[] = sprintf(" \$class = sfConfig::get('sf_factory_storage', '%s');\n \$this->factories['storage'] = new \$class(array_merge(array(\n%s\n), sfConfig::get('sf_factory_storage_parameters', %s)));", $class, implode("\n", $defaultParameters), var_export($parameters, true));
  96. break;
  97. case 'user':
  98. $instances[] = sprintf(" \$class = sfConfig::get('sf_factory_user', '%s');\n \$this->factories['user'] = new \$class(\$this->dispatcher, \$this->factories['storage'], array_merge(array('auto_shutdown' => false, 'culture' => \$this->factories['request']->getParameter('sf_culture')), sfConfig::get('sf_factory_user_parameters', %s)));", $class, var_export($parameters, true));
  99. break;
  100. case 'view_cache':
  101. $instances[] = sprintf("\n if (sfConfig::get('sf_cache'))\n {\n".
  102. " \$class = sfConfig::get('sf_factory_view_cache', '%s');\n".
  103. " \$cache = new \$class(sfConfig::get('sf_factory_view_cache_parameters', %s));\n".
  104. " \$this->factories['viewCacheManager'] = new sfViewCacheManager(\$this, \$cache);\n".
  105. " }\n".
  106. " else\n".
  107. " {\n".
  108. " \$this->factories['viewCacheManager'] = null;\n".
  109. " }\n",
  110. $class, var_export($parameters, true));
  111. break;
  112. case 'i18n':
  113. if (isset($parameters['cache']))
  114. {
  115. $cache = sprintf(" \$cache = new %s(%s);\n", $parameters['cache']['class'], var_export($parameters['cache']['param'], true));
  116. unset($parameters['cache']);
  117. }
  118. else
  119. {
  120. $cache = " \$cache = null;\n";
  121. }
  122. $instances[] = sprintf("\n if (sfConfig::get('sf_i18n'))\n {\n".
  123. " \$class = sfConfig::get('sf_factory_i18n', '%s');\n".
  124. "%s".
  125. " \$this->factories['i18n'] = new \$class(\$this->configuration, \$cache, %s);\n".
  126. " sfWidgetFormSchemaFormatter::setTranslationCallable(array(\$this->factories['i18n'], '__'));\n".
  127. " }\n"
  128. , $class, $cache, var_export($parameters, true)
  129. );
  130. break;
  131. case 'routing':
  132. if (isset($parameters['cache']))
  133. {
  134. $cache = sprintf(" \$cache = new %s(%s);\n", $parameters['cache']['class'], var_export($parameters['cache']['param'], true));
  135. unset($parameters['cache']);
  136. }
  137. else
  138. {
  139. $cache = " \$cache = null;\n";
  140. }
  141. $instances[] = sprintf(" \$class = sfConfig::get('sf_factory_routing', '%s');\n %s\n\$this->factories['routing'] = new \$class(\$this->dispatcher, \$cache, array_merge(array('auto_shutdown' => false), sfConfig::get('sf_factory_routing_parameters', %s)));", $class, $cache, var_export($parameters, true));
  142. break;
  143. case 'logger':
  144. $loggers = '';
  145. if (isset($parameters['loggers']))
  146. {
  147. foreach ($parameters['loggers'] as $name => $keys)
  148. {
  149. if (isset($keys['enabled']) && !$keys['enabled'])
  150. {
  151. continue;
  152. }
  153. if (!isset($keys['class']))
  154. {
  155. // missing class key
  156. throw new sfParseException(sprintf('Configuration file "%s" specifies logger "%s" with missing class key.', $configFiles[0], $name));
  157. }
  158. $condition = true;
  159. if (isset($keys['param']['condition']))
  160. {
  161. $condition = $keys['param']['condition'];
  162. unset($keys['param']['condition']);
  163. }
  164. if ($condition)
  165. {
  166. // create logger instance
  167. $loggers .= sprintf("\n\$logger = new %s(\$this->dispatcher, array_merge(array('auto_shutdown' => false), %s));\n\$this->factories['logger']->addLogger(\$logger);\n",
  168. $keys['class'],
  169. isset($keys['param']) ? var_export($keys['param'], true) : 'array()'
  170. );
  171. }
  172. }
  173. unset($parameters['loggers']);
  174. }
  175. $instances[] = sprintf(
  176. " \$class = sfConfig::get('sf_factory_logger', '%s');\n \$this->factories['logger'] = new \$class(\$this->dispatcher, array_merge(array('auto_shutdown' => false), sfConfig::get('sf_factory_logger_parameters', %s)));\n".
  177. " %s"
  178. , $class, var_export($parameters, true), $loggers);
  179. break;
  180. }
  181. }
  182. // compile data
  183. $retval = sprintf("<?php\n".
  184. "// auto-generated by sfFactoryConfigHandler\n".
  185. "// date: %s\n%s\n%s\n",
  186. date('Y/m/d H:i:s'), implode("\n", $includes),
  187. implode("\n", $instances));
  188. return $retval;
  189. }
  190. /**
  191. * @see sfConfigHandler
  192. */
  193. static public function getConfiguration(array $configFiles)
  194. {
  195. $config = self::replaceConstants(self::flattenConfigurationWithEnvironment(self::parseYamls($configFiles)));
  196. foreach ($config as $factory => $values)
  197. {
  198. if (isset($values['file']))
  199. {
  200. $config[$factory]['file'] = self::replacePath($values['file']);
  201. }
  202. }
  203. return $config;
  204. }
  205. }