sfContext.class.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  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. * sfContext provides information about the current application context, such as
  12. * the module and action names and the module directory. References to the
  13. * main symfony instances are also provided.
  14. *
  15. * @package symfony
  16. * @subpackage util
  17. * @author Fabien Potencier <fabien.potencier@symfony-project.com>
  18. * @author Sean Kerr <sean@code-box.org>
  19. * @version SVN: $Id: sfContext.class.php 16165 2009-03-11 07:16:24Z fabien $
  20. */
  21. class sfContext
  22. {
  23. protected
  24. $dispatcher = null,
  25. $configuration = null,
  26. $factories = array();
  27. protected static
  28. $instances = array(),
  29. $current = 'default';
  30. /**
  31. * Creates a new context instance.
  32. *
  33. * @param sfApplicationConfiguration $configuration An sfApplicationConfiguration instance
  34. * @param string $name A name for this context (application name by default)
  35. * @param string $class The context class to use (sfContext by default)
  36. *
  37. * @return sfContext An sfContext instance
  38. */
  39. static public function createInstance(sfApplicationConfiguration $configuration, $name = null, $class = __CLASS__)
  40. {
  41. if (is_null($name))
  42. {
  43. $name = $configuration->getApplication();
  44. }
  45. self::$current = $name;
  46. self::$instances[$name] = new $class();
  47. if (!self::$instances[$name] instanceof sfContext)
  48. {
  49. throw new sfFactoryException(sprintf('Class "%s" is not of the type sfContext.', $class));
  50. }
  51. self::$instances[$name]->initialize($configuration);
  52. return self::$instances[$name];
  53. }
  54. /**
  55. * Initializes the current sfContext instance.
  56. *
  57. * @param sfApplicationConfiguration $configuration An sfApplicationConfiguration instance
  58. */
  59. public function initialize(sfApplicationConfiguration $configuration)
  60. {
  61. $this->configuration = $configuration;
  62. $this->dispatcher = $configuration->getEventDispatcher();
  63. try
  64. {
  65. $this->loadFactories();
  66. }
  67. catch (sfException $e)
  68. {
  69. $e->printStackTrace();
  70. }
  71. catch (Exception $e)
  72. {
  73. sfException::createFromException($e)->printStackTrace();
  74. }
  75. $this->dispatcher->connect('template.filter_parameters', array($this, 'filterTemplateParameters'));
  76. // register our shutdown function
  77. register_shutdown_function(array($this, 'shutdown'));
  78. }
  79. /**
  80. * Retrieves the singleton instance of this class.
  81. *
  82. * @param string $name The name of the sfContext to retrieve.
  83. * @param string $class The context class to use (sfContext by default)
  84. *
  85. * @return sfContext An sfContext implementation instance.
  86. */
  87. static public function getInstance($name = null, $class = __CLASS__)
  88. {
  89. if (is_null($name))
  90. {
  91. $name = self::$current;
  92. }
  93. if (!isset(self::$instances[$name]))
  94. {
  95. throw new sfException(sprintf('The "%s" context does not exist.', $name));
  96. }
  97. return self::$instances[$name];
  98. }
  99. /**
  100. * Checks to see if there has been a context created
  101. *
  102. * @param string $name The name of the sfContext to check for
  103. *
  104. * @return bool true is instanced, otherwise false
  105. */
  106. public static function hasInstance($name = null)
  107. {
  108. if (is_null($name))
  109. {
  110. $name = self::$current;
  111. }
  112. return isset(self::$instances[$name]);
  113. }
  114. /**
  115. * Loads the symfony factories.
  116. */
  117. public function loadFactories()
  118. {
  119. if (sfConfig::get('sf_use_database'))
  120. {
  121. // setup our database connections
  122. $this->factories['databaseManager'] = new sfDatabaseManager($this->configuration, array('auto_shutdown' => false));
  123. }
  124. // create a new action stack
  125. $this->factories['actionStack'] = new sfActionStack();
  126. // include the factories configuration
  127. require($this->configuration->getConfigCache()->checkConfig('config/factories.yml'));
  128. $this->dispatcher->notify(new sfEvent($this, 'context.load_factories'));
  129. }
  130. /**
  131. * Dispatches the current request.
  132. */
  133. public function dispatch()
  134. {
  135. $this->getController()->dispatch();
  136. }
  137. /**
  138. * Sets the current context to something else
  139. *
  140. * @param string $name The name of the context to switch to
  141. *
  142. */
  143. public static function switchTo($name)
  144. {
  145. if (!isset(self::$instances[$name]))
  146. {
  147. $currentConfiguration = sfContext::getInstance()->getConfiguration();
  148. sfContext::createInstance(ProjectConfiguration::getApplicationConfiguration($name, $currentConfiguration->getEnvironment(), $currentConfiguration->isDebug()));
  149. }
  150. self::$current = $name;
  151. sfContext::getInstance()->getConfiguration()->activate();
  152. }
  153. /**
  154. * Returns the configuration instance.
  155. *
  156. * @return sfApplicationConfiguration The current application configuration instance
  157. */
  158. public function getConfiguration()
  159. {
  160. return $this->configuration;
  161. }
  162. /**
  163. * Retrieves the current event dispatcher.
  164. *
  165. * @return sfEventDispatcher An sfEventDispatcher instance
  166. */
  167. public function getEventDispatcher()
  168. {
  169. return $this->dispatcher;
  170. }
  171. /**
  172. * Retrieve the action name for this context.
  173. *
  174. * @return string The currently executing action name, if one is set,
  175. * otherwise null.
  176. */
  177. public function getActionName()
  178. {
  179. // get the last action stack entry
  180. if ($this->factories['actionStack'] && $lastEntry = $this->factories['actionStack']->getLastEntry())
  181. {
  182. return $lastEntry->getActionName();
  183. }
  184. }
  185. /**
  186. * Retrieve the ActionStack.
  187. *
  188. * @return sfActionStack the sfActionStack instance
  189. */
  190. public function getActionStack()
  191. {
  192. return $this->factories['actionStack'];
  193. }
  194. /**
  195. * Retrieve the controller.
  196. *
  197. * @return sfController The current sfController implementation instance.
  198. */
  199. public function getController()
  200. {
  201. return isset($this->factories['controller']) ? $this->factories['controller'] : null;
  202. }
  203. /**
  204. * Retrieve the logger.
  205. *
  206. * @return sfLogger The current sfLogger implementation instance.
  207. */
  208. public function getLogger()
  209. {
  210. if (!isset($this->factories['logger']))
  211. {
  212. $this->factories['logger'] = new sfNoLogger($this->dispatcher);
  213. }
  214. return $this->factories['logger'];
  215. }
  216. /**
  217. * Retrieve a database connection from the database manager.
  218. *
  219. * This is a shortcut to manually getting a connection from an existing
  220. * database implementation instance.
  221. *
  222. * If the [sf_use_database] setting is off, this will return null.
  223. *
  224. * @param name $name A database name.
  225. *
  226. * @return mixed A database instance.
  227. *
  228. * @throws sfDatabaseException if the requested database name does not exist.
  229. */
  230. public function getDatabaseConnection($name = 'default')
  231. {
  232. if (!is_null($this->factories['databaseManager']))
  233. {
  234. return $this->factories['databaseManager']->getDatabase($name)->getConnection();
  235. }
  236. return null;
  237. }
  238. public function retrieveObjects($class, $peerMethod)
  239. {
  240. $retrievingClass = 'sf'.ucfirst(sfConfig::get('sf_orm', 'propel')).'DataRetriever';
  241. return call_user_func(array($retrievingClass, 'retrieveObjects'), $class, $peerMethod);
  242. }
  243. /**
  244. * Retrieve the database manager.
  245. *
  246. * @return sfDatabaseManager The current sfDatabaseManager instance.
  247. */
  248. public function getDatabaseManager()
  249. {
  250. return isset($this->factories['databaseManager']) ? $this->factories['databaseManager'] : null;
  251. }
  252. /**
  253. * Retrieve the module directory for this context.
  254. *
  255. * @return string An absolute filesystem path to the directory of the
  256. * currently executing module, if one is set, otherwise null.
  257. */
  258. public function getModuleDirectory()
  259. {
  260. // get the last action stack entry
  261. if (isset($this->factories['actionStack']) && $lastEntry = $this->factories['actionStack']->getLastEntry())
  262. {
  263. return sfConfig::get('sf_app_module_dir').'/'.$lastEntry->getModuleName();
  264. }
  265. }
  266. /**
  267. * Retrieve the module name for this context.
  268. *
  269. * @return string The currently executing module name, if one is set,
  270. * otherwise null.
  271. */
  272. public function getModuleName()
  273. {
  274. // get the last action stack entry
  275. if (isset($this->factories['actionStack']) && $lastEntry = $this->factories['actionStack']->getLastEntry())
  276. {
  277. return $lastEntry->getModuleName();
  278. }
  279. }
  280. /**
  281. * Retrieve the request.
  282. *
  283. * @return sfRequest The current sfRequest implementation instance.
  284. */
  285. public function getRequest()
  286. {
  287. return isset($this->factories['request']) ? $this->factories['request'] : null;
  288. }
  289. /**
  290. * Retrieve the response.
  291. *
  292. * @return sfResponse The current sfResponse implementation instance.
  293. */
  294. public function getResponse()
  295. {
  296. return isset($this->factories['response']) ? $this->factories['response'] : null;
  297. }
  298. /**
  299. * Set the response object.
  300. *
  301. * @param sfResponse $response An sfResponse instance.
  302. *
  303. * @return void
  304. */
  305. public function setResponse($response)
  306. {
  307. $this->factories['response'] = $response;
  308. }
  309. /**
  310. * Retrieve the storage.
  311. *
  312. * @return sfStorage The current sfStorage implementation instance.
  313. */
  314. public function getStorage()
  315. {
  316. return isset($this->factories['storage']) ? $this->factories['storage'] : null;
  317. }
  318. /**
  319. * Retrieve the view cache manager
  320. *
  321. * @return sfViewCacheManager The current sfViewCacheManager implementation instance.
  322. */
  323. public function getViewCacheManager()
  324. {
  325. return isset($this->factories['viewCacheManager']) ? $this->factories['viewCacheManager'] : null;
  326. }
  327. /**
  328. * Retrieve the i18n instance
  329. *
  330. * @return sfI18N The current sfI18N implementation instance.
  331. */
  332. public function getI18N()
  333. {
  334. if (!sfConfig::get('sf_i18n'))
  335. {
  336. throw new sfConfigurationException('You must enabled i18n support in your settings.yml configuration file.');
  337. }
  338. return $this->factories['i18n'];
  339. }
  340. /**
  341. * Retrieve the routing instance.
  342. *
  343. * @return sfRouting The current sfRouting implementation instance.
  344. */
  345. public function getRouting()
  346. {
  347. return isset($this->factories['routing']) ? $this->factories['routing'] : null;
  348. }
  349. /**
  350. * Retrieve the user.
  351. *
  352. * @return sfUser The current sfUser implementation instance.
  353. */
  354. public function getUser()
  355. {
  356. return isset($this->factories['user']) ? $this->factories['user'] : null;
  357. }
  358. /**
  359. * Returns the configuration cache.
  360. *
  361. * @return sfConfigCache A sfConfigCache instance
  362. */
  363. public function getConfigCache()
  364. {
  365. return $this->configuration->getConfigCache();
  366. }
  367. /**
  368. * Gets an object from the current context.
  369. *
  370. * @param string $name The name of the object to retrieve
  371. *
  372. * @return object The object associated with the given name
  373. */
  374. public function get($name)
  375. {
  376. if (!$this->has($name))
  377. {
  378. throw new sfException(sprintf('The "%s" object does not exist in the current context.', $name));
  379. }
  380. return $this->factories[$name];
  381. }
  382. /**
  383. * Puts an object in the current context.
  384. *
  385. * @param string $name The name of the object to store
  386. * @param object $object The object to store
  387. */
  388. public function set($name, $object)
  389. {
  390. $this->factories[$name] = $object;
  391. }
  392. /**
  393. * Returns true if an object is currently stored in the current context with the given name, false otherwise.
  394. *
  395. * @param string $name The object name
  396. *
  397. * @return bool true if the object is not null, false otherwise
  398. */
  399. public function has($name)
  400. {
  401. return isset($this->factories[$name]);
  402. }
  403. /**
  404. * Listens to the template.filter_parameters event.
  405. *
  406. * @param sfEvent $event An sfEvent instance
  407. * @param array $parameters An array of template parameters to filter
  408. *
  409. * @return array The filtered parameters array
  410. */
  411. public function filterTemplateParameters(sfEvent $event, $parameters)
  412. {
  413. $parameters['sf_context'] = $this;
  414. $parameters['sf_request'] = $this->factories['request'];
  415. $parameters['sf_params'] = $this->factories['request']->getParameterHolder();
  416. $parameters['sf_response'] = $this->factories['response'];
  417. $parameters['sf_user'] = $this->factories['user'];
  418. return $parameters;
  419. }
  420. /**
  421. * Execute the shutdown procedure.
  422. *
  423. * @return void
  424. */
  425. public function shutdown()
  426. {
  427. // shutdown all factories
  428. if($this->has('user'))
  429. {
  430. $this->getUser()->shutdown();
  431. $this->getStorage()->shutdown();
  432. }
  433. if ($this->has('routing'))
  434. {
  435. $this->getRouting()->shutdown();
  436. }
  437. if (sfConfig::get('sf_use_database'))
  438. {
  439. $this->getDatabaseManager()->shutdown();
  440. }
  441. if (sfConfig::get('sf_logging_enabled'))
  442. {
  443. $this->getLogger()->shutdown();
  444. }
  445. }
  446. }