--- /dev/null
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpKernel\Bundle;
+
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Container;
+use Symfony\Component\Console\Application;
+use Symfony\Component\Finder\Finder;
+use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
+
+/**
+ * An implementation of BundleInterface that adds a few conventions
+ * for DependencyInjection extensions and Console commands.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+abstract class Bundle implements BundleInterface
+{
+ /**
+ * @var ContainerInterface
+ */
+ protected $container;
+ protected $name;
+ protected $extension;
+ protected $path;
+
+ /**
+ * Boots the Bundle.
+ */
+ public function boot()
+ {
+ }
+
+ /**
+ * Shutdowns the Bundle.
+ */
+ public function shutdown()
+ {
+ }
+
+ /**
+ * Builds the bundle.
+ *
+ * It is only ever called once when the cache is empty.
+ *
+ * This method can be overridden to register compilation passes,
+ * other extensions, ...
+ *
+ * @param ContainerBuilder $container A ContainerBuilder instance
+ */
+ public function build(ContainerBuilder $container)
+ {
+ }
+
+ /**
+ * Sets the container.
+ *
+ * @param ContainerInterface|null $container A ContainerInterface instance or null
+ */
+ public function setContainer(ContainerInterface $container = null)
+ {
+ $this->container = $container;
+ }
+
+ /**
+ * Returns the bundle's container extension.
+ *
+ * @return ExtensionInterface|null The container extension
+ *
+ * @throws \LogicException
+ */
+ public function getContainerExtension()
+ {
+ if (null === $this->extension) {
+ $extension = $this->createContainerExtension();
+
+ if (null !== $extension) {
+ if (!$extension instanceof ExtensionInterface) {
+ throw new \LogicException(sprintf('Extension %s must implement Symfony\Component\DependencyInjection\Extension\ExtensionInterface.', get_class($extension)));
+ }
+
+ // check naming convention
+ $basename = preg_replace('/Bundle$/', '', $this->getName());
+ $expectedAlias = Container::underscore($basename);
+
+ if ($expectedAlias != $extension->getAlias()) {
+ throw new \LogicException(sprintf(
+ 'Users will expect the alias of the default extension of a bundle to be the underscored version of the bundle name ("%s"). You can override "Bundle::getContainerExtension()" if you want to use "%s" or another alias.',
+ $expectedAlias, $extension->getAlias()
+ ));
+ }
+
+ $this->extension = $extension;
+ } else {
+ $this->extension = false;
+ }
+ }
+
+ if ($this->extension) {
+ return $this->extension;
+ }
+ }
+
+ /**
+ * Gets the Bundle namespace.
+ *
+ * @return string The Bundle namespace
+ */
+ public function getNamespace()
+ {
+ $class = get_class($this);
+
+ return substr($class, 0, strrpos($class, '\\'));
+ }
+
+ /**
+ * Gets the Bundle directory path.
+ *
+ * @return string The Bundle absolute path
+ */
+ public function getPath()
+ {
+ if (null === $this->path) {
+ $reflected = new \ReflectionObject($this);
+ $this->path = dirname($reflected->getFileName());
+ }
+
+ return $this->path;
+ }
+
+ /**
+ * Returns the bundle parent name.
+ *
+ * @return string The Bundle parent name it overrides or null if no parent
+ */
+ public function getParent()
+ {
+ }
+
+ /**
+ * Returns the bundle name (the class short name).
+ *
+ * @return string The Bundle name
+ */
+ final public function getName()
+ {
+ if (null !== $this->name) {
+ return $this->name;
+ }
+
+ $name = get_class($this);
+ $pos = strrpos($name, '\\');
+
+ return $this->name = false === $pos ? $name : substr($name, $pos + 1);
+ }
+
+ /**
+ * Finds and registers Commands.
+ *
+ * Override this method if your bundle commands do not follow the conventions:
+ *
+ * * Commands are in the 'Command' sub-directory
+ * * Commands extend Symfony\Component\Console\Command\Command
+ *
+ * @param Application $application An Application instance
+ */
+ public function registerCommands(Application $application)
+ {
+ if (!is_dir($dir = $this->getPath().'/Command')) {
+ return;
+ }
+
+ if (!class_exists('Symfony\Component\Finder\Finder')) {
+ throw new \RuntimeException('You need the symfony/finder component to register bundle commands.');
+ }
+
+ $finder = new Finder();
+ $finder->files()->name('*Command.php')->in($dir);
+
+ $prefix = $this->getNamespace().'\\Command';
+ foreach ($finder as $file) {
+ $ns = $prefix;
+ if ($relativePath = $file->getRelativePath()) {
+ $ns .= '\\'.str_replace('/', '\\', $relativePath);
+ }
+ $class = $ns.'\\'.$file->getBasename('.php');
+ if ($this->container) {
+ $alias = 'console.command.'.strtolower(str_replace('\\', '_', $class));
+ if ($this->container->has($alias)) {
+ continue;
+ }
+ }
+ $r = new \ReflectionClass($class);
+ if ($r->isSubclassOf('Symfony\\Component\\Console\\Command\\Command') && !$r->isAbstract() && !$r->getConstructor()->getNumberOfRequiredParameters()) {
+ $application->add($r->newInstance());
+ }
+ }
+ }
+
+ /**
+ * Returns the bundle's container extension class.
+ *
+ * @return string
+ */
+ protected function getContainerExtensionClass()
+ {
+ $basename = preg_replace('/Bundle$/', '', $this->getName());
+
+ return $this->getNamespace().'\\DependencyInjection\\'.$basename.'Extension';
+ }
+
+ /**
+ * Creates the bundle's container extension.
+ *
+ * @return ExtensionInterface|null
+ */
+ protected function createContainerExtension()
+ {
+ if (class_exists($class = $this->getContainerExtensionClass())) {
+ return new $class();
+ }
+ }
+}