bootstrap.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. <?php
  2. namespace Symfony\Component\HttpKernel\Bundle
  3. {
  4. use Symfony\Component\DependencyInjection\ContainerAware;
  5. use Symfony\Component\DependencyInjection\ContainerBuilder;
  6. use Symfony\Component\Console\Application;
  7. use Symfony\Component\Finder\Finder;
  8. abstract class Bundle extends ContainerAware implements BundleInterface
  9. {
  10. protected $name;
  11. public function boot()
  12. {
  13. }
  14. public function shutdown()
  15. {
  16. }
  17. public function getParent()
  18. {
  19. return null;
  20. }
  21. final public function getName()
  22. {
  23. if (null !== $this->name) {
  24. return $this->name;
  25. }
  26. $pos = strrpos(get_class($this), '\\');
  27. return $this->name = substr(get_class($this), $pos ? $pos + 1 : 0);
  28. }
  29. public function registerExtensions(ContainerBuilder $container)
  30. {
  31. if (!$dir = realpath($this->getPath().'/DependencyInjection')) {
  32. return;
  33. }
  34. $finder = new Finder();
  35. $finder->files()->name('*Extension.php')->in($dir);
  36. $prefix = $this->getNamespace().'\\DependencyInjection';
  37. foreach ($finder as $file) {
  38. $class = $prefix.strtr($file->getPath(), array($dir => '', '/' => '\\')).'\\'.$file->getBasename('.php');
  39. $container->registerExtension(new $class());
  40. }
  41. }
  42. public function registerCommands(Application $application)
  43. {
  44. if (!$dir = realpath($this->getPath().'/Command')) {
  45. return;
  46. }
  47. $finder = new Finder();
  48. $finder->files()->name('*Command.php')->in($dir);
  49. $prefix = $this->getNamespace().'\\Command';
  50. foreach ($finder as $file) {
  51. $r = new \ReflectionClass($prefix.strtr($file->getPath(), array($dir => '', '/' => '\\')).'\\'.$file->getBasename('.php'));
  52. if ($r->isSubclassOf('Symfony\\Component\\Console\\Command\\Command') && !$r->isAbstract()) {
  53. $application->add($r->newInstance());
  54. }
  55. }
  56. }
  57. }
  58. }
  59. namespace Symfony\Component\HttpKernel\Bundle
  60. {
  61. interface BundleInterface
  62. {
  63. function boot();
  64. function shutdown();
  65. function getParent();
  66. function getName();
  67. function getNamespace();
  68. function getPath();
  69. }
  70. }
  71. namespace Symfony\Component\HttpKernel\Debug
  72. {
  73. class ErrorHandler
  74. {
  75. protected $levels = array(
  76. E_WARNING => 'Warning',
  77. E_NOTICE => 'Notice',
  78. E_USER_ERROR => 'User Error',
  79. E_USER_WARNING => 'User Warning',
  80. E_USER_NOTICE => 'User Notice',
  81. E_STRICT => 'Runtime Notice',
  82. E_RECOVERABLE_ERROR => 'Catchable Fatal Error',
  83. );
  84. protected $level;
  85. public function __construct($level = null)
  86. {
  87. $this->level = null === $level ? error_reporting() : $level;
  88. }
  89. public function register()
  90. {
  91. set_error_handler(array($this, 'handle'));
  92. }
  93. public function handle($level, $message, $file, $line, $context)
  94. {
  95. if (0 === $this->level) {
  96. return false;
  97. }
  98. if (error_reporting() & $level && $this->level & $level) {
  99. throw new \ErrorException(sprintf('%s: %s in %s line %d', isset($this->levels[$level]) ? $this->levels[$level] : $level, $message, $file, $line));
  100. }
  101. return false;
  102. }
  103. }
  104. }
  105. namespace Symfony\Component\HttpKernel
  106. {
  107. class ClassCollectionLoader
  108. {
  109. static protected $loaded;
  110. static public function load($classes, $cacheDir, $name, $autoReload, $adaptive = false)
  111. {
  112. if (isset(self::$loaded[$name])) {
  113. return;
  114. }
  115. self::$loaded[$name] = true;
  116. $classes = array_unique($classes);
  117. if ($adaptive) {
  118. $classes = array_diff($classes, get_declared_classes(), get_declared_interfaces());
  119. $name = $name.'-'.substr(md5(implode('|', $classes)), 0, 5);
  120. }
  121. $cache = $cacheDir.'/'.$name.'.php';
  122. $reload = false;
  123. if ($autoReload) {
  124. $metadata = $cacheDir.'/'.$name.'.meta';
  125. if (!file_exists($metadata) || !file_exists($cache)) {
  126. $reload = true;
  127. } else {
  128. $time = filemtime($cache);
  129. $meta = unserialize(file_get_contents($metadata));
  130. if ($meta[1] != $classes) {
  131. $reload = true;
  132. } else {
  133. foreach ($meta[0] as $resource) {
  134. if (!file_exists($resource) || filemtime($resource) > $time) {
  135. $reload = true;
  136. break;
  137. }
  138. }
  139. }
  140. }
  141. }
  142. if (!$reload && file_exists($cache)) {
  143. require_once $cache;
  144. return;
  145. }
  146. $files = array();
  147. $content = '';
  148. foreach ($classes as $class) {
  149. if (!class_exists($class) && !interface_exists($class)) {
  150. throw new \InvalidArgumentException(sprintf('Unable to load class "%s"', $class));
  151. }
  152. $r = new \ReflectionClass($class);
  153. $files[] = $r->getFileName();
  154. $c = preg_replace(array('/^\s*<\?php/', '/\?>\s*$/'), '', file_get_contents($r->getFileName()));
  155. if (!$r->inNamespace()) {
  156. $c = "\nnamespace\n{\n$c\n}\n";
  157. } else {
  158. $c = self::fixNamespaceDeclarations('<?php '.$c);
  159. $c = preg_replace('/^\s*<\?php/', '', $c);
  160. }
  161. $content .= $c;
  162. }
  163. if (!is_dir(dirname($cache))) {
  164. mkdir(dirname($cache), 0777, true);
  165. }
  166. self::writeCacheFile($cache, Kernel::stripComments('<?php '.$content));
  167. if ($autoReload) {
  168. self::writeCacheFile($metadata, serialize(array($files, $classes)));
  169. }
  170. }
  171. static public function fixNamespaceDeclarations($source)
  172. {
  173. if (!function_exists('token_get_all')) {
  174. return $source;
  175. }
  176. $output = '';
  177. $inNamespace = false;
  178. $tokens = token_get_all($source);
  179. while ($token = array_shift($tokens)) {
  180. if (is_string($token)) {
  181. $output .= $token;
  182. } elseif (T_NAMESPACE === $token[0]) {
  183. if ($inNamespace) {
  184. $output .= "}\n";
  185. }
  186. $output .= $token[1];
  187. while (($t = array_shift($tokens)) && is_array($t) && in_array($t[0], array(T_WHITESPACE, T_NS_SEPARATOR, T_STRING))) {
  188. $output .= $t[1];
  189. }
  190. if (is_string($t) && '{' === $t) {
  191. $inNamespace = false;
  192. array_unshift($tokens, $t);
  193. } else {
  194. $output .= "\n{";
  195. $inNamespace = true;
  196. }
  197. } else {
  198. $output .= $token[1];
  199. }
  200. }
  201. if ($inNamespace) {
  202. $output .= "}\n";
  203. }
  204. return $output;
  205. }
  206. static protected function writeCacheFile($file, $content)
  207. {
  208. $tmpFile = tempnam(dirname($file), basename($file));
  209. if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $file)) {
  210. chmod($file, 0644);
  211. return;
  212. }
  213. throw new \RuntimeException(sprintf('Failed to write cache file "%s".', $file));
  214. }
  215. }
  216. }
  217. namespace Symfony\Component\DependencyInjection
  218. {
  219. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  220. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
  221. use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
  222. class Container implements ContainerInterface
  223. {
  224. protected $parameterBag;
  225. protected $services;
  226. protected $loading = array();
  227. public function __construct(ParameterBagInterface $parameterBag = null)
  228. {
  229. $this->parameterBag = null === $parameterBag ? new ParameterBag() : $parameterBag;
  230. $this->services =
  231. $this->scopes =
  232. $this->scopeChildren =
  233. $this->scopedServices =
  234. $this->scopeStacks = array();
  235. $this->set('service_container', $this);
  236. }
  237. public function compile()
  238. {
  239. $this->parameterBag->resolve();
  240. $this->parameterBag = new FrozenParameterBag($this->parameterBag->all());
  241. }
  242. public function isFrozen()
  243. {
  244. return $this->parameterBag instanceof FrozenParameterBag;
  245. }
  246. public function getParameterBag()
  247. {
  248. return $this->parameterBag;
  249. }
  250. public function getParameter($name)
  251. {
  252. return $this->parameterBag->get($name);
  253. }
  254. public function hasParameter($name)
  255. {
  256. return $this->parameterBag->has($name);
  257. }
  258. public function setParameter($name, $value)
  259. {
  260. $this->parameterBag->set($name, $value);
  261. }
  262. public function set($id, $service, $scope = self::SCOPE_CONTAINER)
  263. {
  264. if (self::SCOPE_PROTOTYPE === $scope) {
  265. throw new \InvalidArgumentException('You cannot set services of scope "prototype".');
  266. }
  267. $id = strtolower($id);
  268. if (self::SCOPE_CONTAINER !== $scope) {
  269. if (!isset($this->scopedServices[$scope])) {
  270. throw new \RuntimeException('You cannot set services of inactive scopes.');
  271. }
  272. $this->scopedServices[$scope][$id] = $service;
  273. }
  274. $this->services[$id] = $service;
  275. }
  276. public function has($id)
  277. {
  278. $id = strtolower($id);
  279. return isset($this->services[$id]) || method_exists($this, 'get'.strtr($id, array('_' => '', '.' => '_')).'Service');
  280. }
  281. public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE)
  282. {
  283. $id = strtolower($id);
  284. if (isset($this->services[$id])) {
  285. return $this->services[$id];
  286. }
  287. if (isset($this->loading[$id])) {
  288. throw new \LogicException(sprintf('Circular reference detected for service "%s" (services currently loading: %s).', $id, implode(', ', array_keys($this->loading))));
  289. }
  290. if (method_exists($this, $method = 'get'.strtr($id, array('_' => '', '.' => '_')).'Service')) {
  291. $this->loading[$id] = true;
  292. $service = $this->$method();
  293. unset($this->loading[$id]);
  294. return $service;
  295. }
  296. if (self::EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior) {
  297. throw new \InvalidArgumentException(sprintf('The service "%s" does not exist.', $id));
  298. }
  299. }
  300. public function getServiceIds()
  301. {
  302. $ids = array();
  303. $r = new \ReflectionClass($this);
  304. foreach ($r->getMethods() as $method) {
  305. if (preg_match('/^get(.+)Service$/', $name = $method->getName(), $match)) {
  306. $ids[] = self::underscore($match[1]);
  307. }
  308. }
  309. return array_merge($ids, array_keys($this->services));
  310. }
  311. public function enterScope($name)
  312. {
  313. if (!isset($this->scopes[$name])) {
  314. throw new \InvalidArgumentException(sprintf('The scope "%s" does not exist.', $name));
  315. }
  316. if (self::SCOPE_CONTAINER !== $this->scopes[$name] && !isset($this->scopedServices[$this->scopes[$name]])) {
  317. throw new \RuntimeException(sprintf('The parent scope "%s" must be active when entering this scope.', $this->scopes[$name]));
  318. }
  319. if (isset($this->scopedServices[$name])) {
  320. $services = array($this->services, $name => $this->scopedServices[$name]);
  321. unset($this->scopedServices[$name]);
  322. foreach ($this->scopeChildren[$name] as $child) {
  323. $services[$child] = $this->scopedServices[$child];
  324. unset($this->scopedServices[$child]);
  325. }
  326. $this->services = call_user_func_array('array_diff_key', $services);
  327. array_shift($services);
  328. if (!isset($this->scopeStacks[$name])) {
  329. $this->scopeStacks[$name] = new \SplStack();
  330. }
  331. $this->scopeStacks[$name]->push($services);
  332. }
  333. $this->scopedServices[$name] = array();
  334. }
  335. public function leaveScope($name)
  336. {
  337. if (!isset($this->scopedServices[$name])) {
  338. throw new \InvalidArgumentException(sprintf('The scope "%s" is not active.', $name));
  339. }
  340. $services = array($this->services, $this->scopedServices[$name]);
  341. unset($this->scopedServices[$name]);
  342. foreach ($this->scopeChildren[$name] as $child) {
  343. if (!isset($this->scopedServices[$child])) {
  344. continue;
  345. }
  346. $services[] = $this->scopedServices[$child];
  347. unset($this->scopedServices[$child]);
  348. }
  349. $this->services = call_user_func_array('array_diff_key', $services);
  350. if (isset($this->scopeStacks[$name]) && count($this->scopeStacks[$name]) > 0) {
  351. $services = $this->scopeStacks[$name]->pop();
  352. $this->scopedServices += $services;
  353. array_unshift($services, $this->services);
  354. $this->services = call_user_func_array('array_merge', $services);
  355. }
  356. }
  357. public function addScope($name, $parentScope = self::SCOPE_CONTAINER)
  358. {
  359. if (self::SCOPE_CONTAINER === $name || self::SCOPE_PROTOTYPE === $name) {
  360. throw new \InvalidArgumentException(sprintf('The scope "%s" is reserved.', $name));
  361. }
  362. if (isset($this->scopes[$name])) {
  363. throw new \InvalidArgumentException(sprintf('A scope with name "%s" already exists.', $name));
  364. }
  365. if (self::SCOPE_CONTAINER !== $parentScope && !isset($this->scopes[$parentScope])) {
  366. throw new \InvalidArgumentException(sprintf('The parent scope "%s" does not exist, or is invalid.', $parentScope));
  367. }
  368. $this->scopes[$name] = $parentScope;
  369. $this->scopeChildren[$name] = array();
  370. if ($parentScope !== self::SCOPE_CONTAINER) {
  371. $this->scopeChildren[$parentScope][] = $name;
  372. foreach ($this->scopeChildren as $pName => $childScopes) {
  373. if (in_array($parentScope, $childScopes, true)) {
  374. $this->scopeChildren[$pName][] = $name;
  375. }
  376. }
  377. }
  378. }
  379. public function hasScope($name)
  380. {
  381. return isset($this->scopes[$name]);
  382. }
  383. public function isScopeActive($name)
  384. {
  385. return isset($this->scopedServices[$name]);
  386. }
  387. static public function camelize($id)
  388. {
  389. return preg_replace(array('/(?:^|_)+(.)/e', '/\.(.)/e'), array("strtoupper('\\1')", "'_'.strtoupper('\\1')"), $id);
  390. }
  391. static public function underscore($id)
  392. {
  393. return strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'), array('\\1_\\2', '\\1_\\2'), strtr($id, '_', '.')));
  394. }
  395. }
  396. }
  397. namespace Symfony\Component\DependencyInjection
  398. {
  399. interface ContainerAwareInterface
  400. {
  401. function setContainer(ContainerInterface $container = null);
  402. }
  403. }
  404. namespace Symfony\Component\DependencyInjection
  405. {
  406. interface ContainerInterface
  407. {
  408. const EXCEPTION_ON_INVALID_REFERENCE = 1;
  409. const NULL_ON_INVALID_REFERENCE = 2;
  410. const IGNORE_ON_INVALID_REFERENCE = 3;
  411. const SCOPE_CONTAINER = 'container';
  412. const SCOPE_PROTOTYPE = 'prototype';
  413. function set($id, $service, $scope = self::SCOPE_CONTAINER);
  414. function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE);
  415. function has($id);
  416. function enterScope($name);
  417. function leaveScope($name);
  418. function addScope($name, $parentScope = self::SCOPE_CONTAINER);
  419. function hasScope($name);
  420. function isScopeActive($name);
  421. }
  422. }
  423. namespace Symfony\Component\DependencyInjection\ParameterBag
  424. {
  425. class FrozenParameterBag extends ParameterBag
  426. {
  427. public function __construct(array $parameters = array())
  428. {
  429. $this->parameters = $parameters;
  430. }
  431. public function clear()
  432. {
  433. throw new \LogicException('Impossible to call clear() on a frozen ParameterBag.');
  434. }
  435. public function add(array $parameters)
  436. {
  437. throw new \LogicException('Impossible to call add() on a frozen ParameterBag.');
  438. }
  439. public function set($name, $value)
  440. {
  441. throw new \LogicException('Impossible to call set() on a frozen ParameterBag.');
  442. }
  443. }
  444. }
  445. namespace Symfony\Component\DependencyInjection\ParameterBag
  446. {
  447. interface ParameterBagInterface
  448. {
  449. function clear();
  450. function add(array $parameters);
  451. function all();
  452. function get($name);
  453. function set($name, $value);
  454. function has($name);
  455. }
  456. }