Created
January 28, 2011 20:35
-
-
Save jmikola/800893 to your computer and use it in GitHub Desktop.
Adding intelligent configuration merging to FrameworkExtension
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| class FrameworkExtension extends Extension | |
| { | |
| public function configLoad(array $configs, ContainerBuilder $container) | |
| { | |
| $loader = new XmlFileLoader($container, __DIR__.'/../Resources/config'); | |
| $loader->load('web.xml'); | |
| $loader->load('form.xml'); | |
| $loader->load('services.xml'); | |
| if ($container->getParameter('kernel.debug')) { | |
| $loader->load('debug.xml'); | |
| $container->setDefinition('event_dispatcher', $container->findDefinition('debug.event_dispatcher')); | |
| $container->setAlias('debug.event_dispatcher', 'event_dispatcher'); | |
| } | |
| $this->doConfigLoad($this->configMerge($configs), $container); | |
| $this->addClassesToCompile(array( | |
| 'Symfony\\Component\\HttpFoundation\\ParameterBag', | |
| 'Symfony\\Component\\HttpFoundation\\HeaderBag', | |
| 'Symfony\\Component\\HttpFoundation\\Request', | |
| 'Symfony\\Component\\HttpFoundation\\Response', | |
| 'Symfony\\Component\\HttpFoundation\\ResponseHeaderBag', | |
| 'Symfony\\Component\\HttpKernel\\HttpKernel', | |
| 'Symfony\\Component\\HttpKernel\\ResponseListener', | |
| 'Symfony\\Component\\HttpKernel\\Controller\\ControllerResolver', | |
| 'Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface', | |
| 'Symfony\\Bundle\\FrameworkBundle\\RequestListener', | |
| 'Symfony\\Bundle\\FrameworkBundle\\Controller\\ControllerNameParser', | |
| 'Symfony\\Bundle\\FrameworkBundle\\Controller\\ControllerResolver', | |
| 'Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller', | |
| 'Symfony\\Component\\EventDispatcher\\EventInterface', | |
| 'Symfony\\Component\\EventDispatcher\\Event', | |
| 'Symfony\\Component\\EventDispatcher\\EventDispatcherInterface', | |
| 'Symfony\\Component\\EventDispatcher\\EventDispatcher', | |
| 'Symfony\\Bundle\\FrameworkBundle\\EventDispatcher', | |
| 'Symfony\\Component\\Form\\FormContext', | |
| 'Symfony\\Component\\Form\\FormContextInterface', | |
| )); | |
| } | |
| /** | |
| * Merges a set of configurations into one, normalized array. | |
| * | |
| * @param array $configs An array of option arrays to merge | |
| * @return array | |
| */ | |
| protected function configMerge(array $configs) | |
| { | |
| // The default and available options. These are very specific to this method. | |
| $options = array( | |
| 'cache_warmer' => null, | |
| 'charset' => null, | |
| 'csrf_protection' => array( | |
| 'enabled' => null, | |
| 'field_name' => null, | |
| 'secret' => null, | |
| ), | |
| 'document_root' => null, | |
| 'error_handler' => null, | |
| 'esi' => array( | |
| 'enabled' => null, | |
| ), | |
| 'i18n' => null, | |
| 'ide' => null, | |
| 'param_converter' => null, | |
| 'profiler' => array( | |
| 'only_exceptions' => null, | |
| 'matcher' => array( | |
| 'ip' => null, | |
| 'path' => null, | |
| 'service' => null, | |
| ), | |
| ), | |
| 'router' => array( | |
| 'cache_warmer' => null, | |
| 'resource' => null, | |
| ), | |
| 'session' => array( | |
| 'auto_start' => null, | |
| 'class' => null, | |
| 'default_locale' => null, | |
| 'storage_id' => 'native', | |
| // Storage driver options | |
| 'name' => null, | |
| 'lifetime' => null, | |
| 'path' => null, | |
| 'domain' => null, | |
| 'secure' => null, | |
| 'httponly' => null, | |
| 'pdo.db_table' => null, | |
| 'pdo.db_id_col' => null, | |
| 'pdo.db_data_col' => null, | |
| 'pdo.db_time_col' => null, | |
| ), | |
| 'templating' => array( | |
| 'assets_version' => null, | |
| 'assets_base_urls' => null, | |
| 'cache' => null, | |
| 'cache_warmer' => null, | |
| 'engines' => array(), | |
| 'loaders' => array(), | |
| ), | |
| 'test' => null, | |
| 'translator' => array( | |
| 'enabled' => null, | |
| 'fallback' => null, | |
| ), | |
| 'validation' => array( | |
| 'enabled' => null, | |
| 'annotations' => array( | |
| 'enabled' => null, | |
| 'namespaces' => array(), | |
| ), | |
| ), | |
| ); | |
| foreach ($configs as $config) { | |
| $config = $this->normalizeKeys($config); | |
| if (isset($config['templating']) && is_array($config['templating'])) { | |
| $config['templating']['engines'] = $this->normalizeConfig($config['templating'], 'engine'); | |
| $config['templating']['loaders'] = $this->normalizeConfig($config['templating'], 'loader'); | |
| unset($config['templating']['engine'], $config['templating']['loader']); | |
| } | |
| if (isset($config['validation']['annotations']) && is_array($config['validation']['annotations'])) { | |
| $config['validation']['annotations']['namespaces'] = $this->normalizeConfig($config['validation']['annotations'], 'namespace'); | |
| unset($config['validation']['annotations']['namespace']); | |
| } | |
| $options = $this->mergeOptions($options, $config); | |
| } | |
| return $options; | |
| } | |
| /** | |
| * Merges a single option level. | |
| * | |
| * @param array $options The array that will be modified and returned | |
| * @param array $config The array to be merged in | |
| * @param string $path The base path for this option level | |
| * @throw InvalidArgumentException When an unsupported option is found | |
| */ | |
| protected function mergeOptions(array $options, array $config, $path = null) | |
| { | |
| if ($unsupportedOptions = array_diff_key($config, $options)) { | |
| throw new \InvalidArgumentException('The following options are not supported: '.implode(', ', $unsupportedOptions)); | |
| } | |
| foreach ($options as $key => $value) { | |
| if (array_key_exists($key, $config)) { | |
| $optionPath = $path ? $path . '.' . $key : $key; | |
| if (is_array($value) && !is_array($config[$key])) { | |
| throw new \InvalidArgumentException(sprintf('Expected array type for option "%s", %s given', $optionPath, gettype($config[$key]))); | |
| } | |
| switch ($optionPath) { | |
| case 'templating.engines': | |
| case 'templating.loaders': | |
| $options[$key] = array_unique(array_merge($value, $config[$key])); | |
| break; | |
| case 'validation.annotations.namespaces': | |
| $options[$key] = array_merge($value, $config[$key]); | |
| break; | |
| default: | |
| if (is_array($value)) { | |
| $options[$key] = $this->mergeOptions($value, $config[$key], $optionPath); | |
| } else { | |
| $options[$key] = $config[$key]; | |
| } | |
| } | |
| } | |
| } | |
| return $options; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment