Bundle.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.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. namespace Symfony\Component\HttpKernel\Bundle;
  11. use Symfony\Component\DependencyInjection\ContainerAware;
  12. use Symfony\Component\DependencyInjection\ContainerBuilder;
  13. use Symfony\Component\DependencyInjection\Container;
  14. use Symfony\Component\Console\Application;
  15. use Symfony\Component\Finder\Finder;
  16. use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
  17. /**
  18. * An implementation of BundleInterface that adds a few conventions
  19. * for DependencyInjection extensions and Console commands.
  20. *
  21. * @author Fabien Potencier <fabien@symfony.com>
  22. *
  23. * @api
  24. */
  25. abstract class Bundle extends ContainerAware implements BundleInterface
  26. {
  27. protected $name;
  28. protected $reflected;
  29. protected $extension;
  30. /**
  31. * Boots the Bundle.
  32. */
  33. public function boot()
  34. {
  35. }
  36. /**
  37. * Shutdowns the Bundle.
  38. */
  39. public function shutdown()
  40. {
  41. }
  42. /**
  43. * Builds the bundle.
  44. *
  45. * It is only ever called once when the cache is empty.
  46. *
  47. * This method can be overridden to register compilation passes,
  48. * other extensions, ...
  49. *
  50. * @param ContainerBuilder $container A ContainerBuilder instance
  51. */
  52. public function build(ContainerBuilder $container)
  53. {
  54. }
  55. /**
  56. * Returns the bundle's container extension.
  57. *
  58. * @return ExtensionInterface|null The container extension
  59. *
  60. * @throws \LogicException
  61. *
  62. * @api
  63. */
  64. public function getContainerExtension()
  65. {
  66. if (null === $this->extension) {
  67. $basename = preg_replace('/Bundle$/', '', $this->getName());
  68. $class = $this->getNamespace().'\\DependencyInjection\\'.$basename.'Extension';
  69. if (class_exists($class)) {
  70. $extension = new $class();
  71. // check naming convention
  72. $expectedAlias = Container::underscore($basename);
  73. if ($expectedAlias != $extension->getAlias()) {
  74. throw new \LogicException(sprintf(
  75. 'The extension alias for the default extension of a '.
  76. 'bundle must be the underscored version of the '.
  77. 'bundle name ("%s" instead of "%s")',
  78. $expectedAlias, $extension->getAlias()
  79. ));
  80. }
  81. $this->extension = $extension;
  82. } else {
  83. $this->extension = false;
  84. }
  85. }
  86. if ($this->extension) {
  87. return $this->extension;
  88. }
  89. }
  90. /**
  91. * Gets the Bundle namespace.
  92. *
  93. * @return string The Bundle namespace
  94. *
  95. * @api
  96. */
  97. public function getNamespace()
  98. {
  99. if (null === $this->reflected) {
  100. $this->reflected = new \ReflectionObject($this);
  101. }
  102. return $this->reflected->getNamespaceName();
  103. }
  104. /**
  105. * Gets the Bundle directory path.
  106. *
  107. * @return string The Bundle absolute path
  108. *
  109. * @api
  110. */
  111. public function getPath()
  112. {
  113. if (null === $this->reflected) {
  114. $this->reflected = new \ReflectionObject($this);
  115. }
  116. return dirname($this->reflected->getFileName());
  117. }
  118. /**
  119. * Returns the bundle parent name.
  120. *
  121. * @return string The Bundle parent name it overrides or null if no parent
  122. *
  123. * @api
  124. */
  125. public function getParent()
  126. {
  127. return null;
  128. }
  129. /**
  130. * Returns the bundle name (the class short name).
  131. *
  132. * @return string The Bundle name
  133. *
  134. * @api
  135. */
  136. final public function getName()
  137. {
  138. if (null !== $this->name) {
  139. return $this->name;
  140. }
  141. $name = get_class($this);
  142. $pos = strrpos($name, '\\');
  143. return $this->name = false === $pos ? $name : substr($name, $pos + 1);
  144. }
  145. /**
  146. * Finds and registers Commands.
  147. *
  148. * Override this method if your bundle commands do not follow the conventions:
  149. *
  150. * * Commands are in the 'Command' sub-directory
  151. * * Commands extend Symfony\Component\Console\Command\Command
  152. *
  153. * @param Application $application An Application instance
  154. */
  155. public function registerCommands(Application $application)
  156. {
  157. if (!is_dir($dir = $this->getPath().'/Command')) {
  158. return;
  159. }
  160. $finder = new Finder();
  161. $finder->files()->name('*Command.php')->in($dir);
  162. $prefix = $this->getNamespace().'\\Command';
  163. foreach ($finder as $file) {
  164. $ns = $prefix;
  165. if ($relativePath = $file->getRelativePath()) {
  166. $ns .= '\\'.strtr($relativePath, '/', '\\');
  167. }
  168. $r = new \ReflectionClass($ns.'\\'.$file->getBasename('.php'));
  169. if ($r->isSubclassOf('Symfony\\Component\\Console\\Command\\Command') && !$r->isAbstract() && !$r->getConstructor()->getNumberOfRequiredParameters()) {
  170. $application->add($r->newInstance());
  171. }
  172. }
  173. }
  174. }