1<?php 2 3/* 4 * This file is part of the Symfony package. 5 * 6 * (c) Fabien Potencier <fabien@symfony.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Symfony\Component\DependencyInjection\Extension; 13 14use Symfony\Component\DependencyInjection\Container; 15use Symfony\Component\DependencyInjection\Exception\BadMethodCallException; 16use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; 17use Symfony\Component\Config\Resource\FileResource; 18use Symfony\Component\DependencyInjection\ContainerBuilder; 19use Symfony\Component\Config\Definition\Processor; 20use Symfony\Component\Config\Definition\ConfigurationInterface; 21 22/** 23 * Provides useful features shared by many extensions. 24 * 25 * @author Fabien Potencier <fabien@symfony.com> 26 */ 27abstract class Extension implements ExtensionInterface, ConfigurationExtensionInterface 28{ 29 /** 30 * Returns the base path for the XSD files. 31 * 32 * @return string The XSD base path 33 */ 34 public function getXsdValidationBasePath() 35 { 36 return false; 37 } 38 39 /** 40 * Returns the namespace to be used for this extension (XML namespace). 41 * 42 * @return string The XML namespace 43 */ 44 public function getNamespace() 45 { 46 return 'http://example.org/schema/dic/'.$this->getAlias(); 47 } 48 49 /** 50 * Returns the recommended alias to use in XML. 51 * 52 * This alias is also the mandatory prefix to use when using YAML. 53 * 54 * This convention is to remove the "Extension" postfix from the class 55 * name and then lowercase and underscore the result. So: 56 * 57 * AcmeHelloExtension 58 * 59 * becomes 60 * 61 * acme_hello 62 * 63 * This can be overridden in a sub-class to specify the alias manually. 64 * 65 * @return string The alias 66 * 67 * @throws BadMethodCallException When the extension name does not follow conventions 68 */ 69 public function getAlias() 70 { 71 $className = get_class($this); 72 if (substr($className, -9) != 'Extension') { 73 throw new BadMethodCallException('This extension does not follow the naming convention; you must overwrite the getAlias() method.'); 74 } 75 $classBaseName = substr(strrchr($className, '\\'), 1, -9); 76 77 return Container::underscore($classBaseName); 78 } 79 80 /** 81 * {@inheritdoc} 82 */ 83 public function getConfiguration(array $config, ContainerBuilder $container) 84 { 85 $reflected = new \ReflectionClass($this); 86 $namespace = $reflected->getNamespaceName(); 87 88 $class = $namespace.'\\Configuration'; 89 if (class_exists($class)) { 90 $r = new \ReflectionClass($class); 91 $container->addResource(new FileResource($r->getFileName())); 92 93 if (!method_exists($class, '__construct')) { 94 $configuration = new $class(); 95 96 return $configuration; 97 } 98 } 99 } 100 101 final protected function processConfiguration(ConfigurationInterface $configuration, array $configs) 102 { 103 $processor = new Processor(); 104 105 return $processor->processConfiguration($configuration, $configs); 106 } 107 108 /** 109 * @param ContainerBuilder $container 110 * @param array $config 111 * 112 * @return bool Whether the configuration is enabled 113 * 114 * @throws InvalidArgumentException When the config is not enableable 115 */ 116 protected function isConfigEnabled(ContainerBuilder $container, array $config) 117 { 118 if (!array_key_exists('enabled', $config)) { 119 throw new InvalidArgumentException("The config array has no 'enabled' key."); 120 } 121 122 return (bool) $container->getParameterBag()->resolveValue($config['enabled']); 123 } 124} 125