From 099b9dee1f4ad0ef411bb16fb38ab3a1ac91d1bb Mon Sep 17 00:00:00 2001 From: Jeremy Mikola Date: Sun, 6 Feb 2011 04:29:16 -0500 Subject: [PATCH] [FrameworkBundle] Integrate Configuration\Builder class for config merging and normalization This fixes some BC problems introduced in f9138d313b83f951cf82a2f7f902a2d6dd14fbb3. Some top-level can now be simply enabled by providing true/null in PHP/YAML. Additionally, the Configuration\Builder allows options to be unset by providing "false" (helpful for overriding activation in a previous config file). All options supporting these behaviors can be found in the Configuration.php file (look for canBeUnset() and treatNull/TrueLike()). Major changes: * Removed "enabled" option for profiler config. Profiler is now enabled if its config is true, null or a map. * Restore original config structure for validation namespaces. In PHP/YAML, namespaces are defined under annotations as an alternative to false (disabled) and true/null (enabled). For XML, annotation remains a boolean attribute for validation and a one or more optional namespace tags may appear within . During config normalization, namespace tags under validation will be moved to annotations to conform to the PHP/YAML structure (this occurs transparently to the user). * Restore behavior for router/templating config sections being optional (as shown in changes to session/validation test fixtures). If either top-level section is unset in the configuration, neither feature will be enabled and the user will no longer receive exceptions due to missing a resource option (router) or engines (templating). Resource/engines will still be properly required if the respective feature is enabled. * Remove unused router type option from XML config XSD. Type is only relevant for import statements, so this option is likely useless. Additional small changes: * Added isset()'s, since config options may be unset * Wrap registerXxxConfiguration() calls in isset() checks * Load translation.xml in configLoad(), since it's always required * Default cache_warmer value (!kernel.debug) is determined via Configuration class Things to be fixed: * Configuration\Builder doesn't seem to respect isRequired() and requiresAtLeastOneElement() (or I haven't set it properly); this should replace the need for FrameworkExtension to throw exceptions for bad router/templating configs * The config nodes for session options don't have the "pdo." prefix, as dots are not allowed in node names. To preserve BC for now, the "pdo." prefix is still allowed (and mandated by XSD) in configuration files. In the future, we may just want to do away with the "pdo." prefix. * Translator has an "enabled" option. If there's no use case for setting "fallback" independently (when "enabled" is false), perhaps "enabled" should be removed entirely and translator should function like profiler currently does. * Profiler matcher merging might need to be adjusted so multiple configs simply overwrite matcher instead of merging its array keys. --- .../DependencyInjection/Configuration.php | 220 ++++++++++ .../FrameworkExtension.php | 383 +++++------------- .../Resources/config/schema/symfony-1.0.xsd | 1 - .../Fixtures/php/session_pdo.php | 6 - .../Fixtures/php/validation_annotations.php | 13 +- .../Fixtures/xml/session_pdo.xml | 4 - .../Fixtures/xml/validation_annotations.xml | 4 - .../DependencyInjection/Fixtures/yml/full.yml | 2 +- .../Fixtures/yml/session_pdo.yml | 4 - .../Fixtures/yml/validation_annotations.yml | 10 +- 10 files changed, 339 insertions(+), 308 deletions(-) create mode 100644 src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php new file mode 100644 index 000000000000..418a7544144c --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php @@ -0,0 +1,220 @@ + + */ +class Configuration +{ + /** + * Generates the configuration tree. + * + * @param boolean $kernelDebug The kernel.debug DIC parameter + * @return \Symfony\Component\DependencyInjection\Configuration\NodeInterface + */ + public function getConfigTree($kernelDebug) + { + $treeBuilder = new TreeBuilder(); + $rootNode = $treeBuilder->root('app:config', 'array'); + + $rootNode + ->scalarNode('cache_warmer')->defaultValue(!$kernelDebug)->end() + ->scalarNode('charset')->end() + ->scalarNode('document_root')->end() + ->scalarNode('error_handler')->end() + ->scalarNode('ide')->end() + ->booleanNode('test')->end() + ; + + $this->addCsrfProtectionSection($rootNode); + $this->addEsiSection($rootNode); + $this->addProfilerSection($rootNode); + $this->addRouterSection($rootNode); + $this->addSessionSection($rootNode); + $this->addTemplatingSection($rootNode); + $this->addTranslatorSection($rootNode); + $this->addValidationSection($rootNode); + + return $treeBuilder->buildTree(); + } + + private function addCsrfProtectionSection(NodeBuilder $rootNode) + { + $rootNode + ->arrayNode('csrf_protection') + ->canBeUnset() + ->treatNullLike(array('enabled' => true)) + ->treatTrueLike(array('enabled' => true)) + ->booleanNode('enabled')->end() + ->scalarNode('field_name')->end() + ->scalarNode('secret')->end() + ->end() + ; + } + + private function addEsiSection(NodeBuilder $rootNode) + { + $rootNode + ->arrayNode('esi') + ->canBeUnset() + ->treatNullLike(array('enabled' => true)) + ->treatTrueLike(array('enabled' => true)) + ->booleanNode('enabled')->end() + ->end() + ; + } + + private function addProfilerSection(NodeBuilder $rootNode) + { + $rootNode + ->arrayNode('profiler') + ->canBeUnset() + ->treatNullLike(array()) + ->treatTrueLike(array()) + ->booleanNode('only_exceptions')->end() + ->arrayNode('matcher') + ->canBeUnset() + ->scalarNode('ip')->end() + ->scalarNode('path')->end() + ->scalarNode('service')->end() + ->end() + ->end() + ; + } + + private function addRouterSection(NodeBuilder $rootNode) + { + $rootNode + ->arrayNode('router') + ->canBeUnset() + ->scalarNode('cache_warmer')->end() + ->scalarNode('resource')->isRequired()->end() + ->end() + ; + } + + private function addSessionSection(NodeBuilder $rootNode) + { + $rootNode + ->arrayNode('session') + ->canBeUnset() + ->treatNullLike(array()) + ->treatTrueLike(array()) + // Strip "pdo." prefix from option keys, since dots cannot appear in node names + ->beforeNormalization() + ->ifArray() + ->then(function($v){ + foreach ($v as $key => $value) { + if (0 === strncmp('pdo.', $key, 4)) { + $v[substr($key, 4)] = $value; + unset($v[$key]); + } + } + return $v; + }) + ->end() + ->booleanNode('auto_start')->end() + ->scalarNode('class')->end() + ->scalarNode('default_locale')->end() + ->scalarNode('storage_id')->defaultValue('native')->end() + // NativeSessionStorage options + ->scalarNode('name')->end() + ->scalarNode('lifetime')->end() + ->scalarNode('path')->end() + ->scalarNode('domain')->end() + ->booleanNode('secure')->end() + ->booleanNode('httponly')->end() + // PdoSessionStorage options + ->scalarNode('db_table')->end() + ->scalarNode('db_id_col')->end() + ->scalarNode('db_data_col')->end() + ->scalarNode('db_time_col')->end() + ->end() + ; + } + + private function addTemplatingSection(NodeBuilder $rootNode) + { + $rootNode + ->arrayNode('templating') + ->canBeUnset() + ->scalarNode('assets_version')->end() + ->scalarNode('assets_base_urls')->end() + ->scalarNode('cache')->end() + ->scalarNode('cache_warmer')->end() + ->fixXmlConfig('engine') + ->arrayNode('engines') + ->requiresAtLeastOneElement() + ->beforeNormalization() + ->ifTrue(function($v){ return !is_array($v); }) + ->then(function($v){ return array($v); }) + ->end() + ->prototype('scalar') + ->beforeNormalization() + ->ifTrue(function($v) { return is_array($v) && isset($v['id']); }) + ->then(function($v){ return $v['id']; }) + ->end() + ->end() + ->end() + ->fixXmlConfig('loader') + ->arrayNode('loaders') + ->beforeNormalization() + ->ifTrue(function($v){ return !is_array($v); }) + ->then(function($v){ return array($v); }) + ->end() + ->prototype('scalar')->end() + ->end() + ->end() + ; + } + + private function addTranslatorSection(NodeBuilder $rootNode) + { + $rootNode + ->arrayNode('translator') + ->canBeUnset() + ->booleanNode('enabled')->defaultTrue()->end() + ->scalarNode('fallback')->end() + ->end() + ; + } + + private function addValidationSection(NodeBuilder $rootNode) + { + $rootNode + ->arrayNode('validation') + ->canBeUnset() + // For XML, namespace is a child of validation, so it must be moved under annotations + ->beforeNormalization() + ->ifTrue(function($v) { return is_array($v) && !empty($v['annotations']) && !empty($v['namespace']); }) + ->then(function($v){ + $v['annotations'] = array('namespace' => $v['namespace']); + return $v; + }) + ->end() + ->booleanNode('enabled')->end() + ->arrayNode('annotations') + ->canBeUnset() + ->treatNullLike(array()) + ->treatTrueLike(array()) + ->fixXmlConfig('namespace') + ->arrayNode('namespaces') + ->containsNameValuePairsWithKeyAttribute('prefix') + ->prototype('scalar') + ->beforeNormalization() + ->ifTrue(function($v) { return is_array($v) && isset($v['namespace']); }) + ->then(function($v){ return $v['namespace']; }) + ->end() + ->end() + ->end() + ->end() + ->end() + ; + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 28606232411b..411835221d3d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -15,10 +15,10 @@ use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Parameter; use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Configuration\Processor; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; use Symfony\Component\DependencyInjection\Resource\FileResource; use Symfony\Component\Finder\Finder; -use Symfony\Component\HttpFoundation\RequestMatcher; use Symfony\Component\HttpKernel\DependencyInjection\Extension; /** @@ -43,16 +43,23 @@ public function configLoad(array $configs, ContainerBuilder $container) $loader->load('form.xml'); $loader->load('services.xml'); + // A translator must always be registered (as support is included by + // default in the Form component). If disabled, an identity translator + // will be used and everything will still work as expected. + $loader->load('translation.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'); } - $config = $this->mergeConfigs($configs); + $processor = new Processor(); + $configuration = new Configuration(); + + $config = $processor->process($configuration->getConfigTree($container->getParameter('kernel.debug')), $configs); - $warmer = isset($config['cache_warmer']) ? $config['cache_warmer'] : !$container->getParameter('kernel.debug'); - $container->setParameter('kernel.cache_warmup', $warmer); + $container->setParameter('kernel.cache_warmup', $config['cache_warmer']); if (isset($config['charset'])) { $container->setParameter('kernel.charset', $config['charset']); @@ -80,19 +87,42 @@ public function configLoad(array $configs, ContainerBuilder $container) $container->setParameter('debug.file_link_format', $pattern); } - if ($config['test']) { + if (isset($config['test']) && $config['test']) { $loader->load('test.xml'); $config['session']['storage_id'] = 'array'; } - $this->registerCsrfProtectionConfiguration($config['csrf_protection'], $container); - $this->registerEsiConfiguration($config['esi'], $loader); - $this->registerProfilerConfiguration($config['profiler'], $container, $loader); - $this->registerRouterConfiguration($config['router'], $container, $loader); - $this->registerSessionConfiguration($config['session'], $container, $loader); - $this->registerTemplatingConfiguration($config['templating'], $container, $loader); - $this->registerTranslatorConfiguration($config['translator'], $container, $loader); - $this->registerValidationConfiguration($config['validation'], $container, $loader); + if (isset($config['csrf_protection'])) { + $this->registerCsrfProtectionConfiguration($config['csrf_protection'], $container); + } + + if (isset($config['esi'])) { + $this->registerEsiConfiguration($config['esi'], $loader); + } + + if (isset($config['profiler'])) { + $this->registerProfilerConfiguration($config['profiler'], $container, $loader); + } + + if (isset($config['router'])) { + $this->registerRouterConfiguration($config['router'], $container, $loader); + } + + if (isset($config['session'])) { + $this->registerSessionConfiguration($config['session'], $container, $loader); + } + + if (isset($config['templating'])) { + $this->registerTemplatingConfiguration($config['templating'], $container, $loader); + } + + if (isset($config['translator'])) { + $this->registerTranslatorConfiguration($config['translator'], $container); + } + + if (isset($config['validation'])) { + $this->registerValidationConfiguration($config['validation'], $container, $loader); + } $this->addClassesToCompile(array( 'Symfony\\Component\\HttpFoundation\\ParameterBag', @@ -119,195 +149,13 @@ public function configLoad(array $configs, ContainerBuilder $container) )); } - /** - * Merges a set of configuration arrays and returns the result. - * - * This method internally specifies the available options and their - * default values. Given an array of configuration arrays, this method - * intelligently merges those configuration values and returns the final, - * flattened product. - * - * @param array $configs An array of configuration arrays to merge - * @return array The merged configuration array - */ - protected function mergeConfigs(array $configs) - { - $defaultOptions = array( - 'cache_warmer' => null, - 'charset' => null, - 'csrf_protection' => array( - 'enabled' => null, - 'field_name' => null, - 'secret' => null, - ), - 'document_root' => null, - 'error_handler' => null, - // TODO: consolidate into a scalar unless future options are planned - 'esi' => array( - 'enabled' => null, - ), - 'ide' => null, - 'profiler' => array( - 'enabled' => false, - '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', - // NativeSessionStorage options - 'name' => null, - 'lifetime' => null, - 'path' => null, - 'domain' => null, - 'secure' => null, - 'httponly' => null, - // PdoSessionStorage options - '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' => null, - 'namespaces' => array(), - ), - ); - - $mergedConfig = $defaultOptions; - - foreach ($configs as $config) { - $config = $this->normalizeKeys($config); - - if (isset($config['profiler'])) { - $config['profiler']['enabled'] = true; - } - - 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']) && is_array($config['validation'])) { - $config['validation']['namespaces'] = $this->normalizeConfig($config['validation'], 'namespace'); - unset($config['validation']['namespace']); - } - - $mergedConfig = $this->mergeOptions($mergedConfig, $config, $defaultOptions); - } - - return $mergedConfig; - } - - /** - * Merges a single level of configuration options. - * - * @param array $current The value of the options before merging - * @param array $new The new values to be merged - * @param array $default The corresponding default values for the option level - * @param string $basePath Base property path for the option level - * @return array The merged options - * @throws InvalidArgumentException When an unsupported is found - */ - protected function mergeOptions(array $current, array $new, array $default, $basePath = null) - { - if ($unsupportedOptions = array_diff_key($new, $default)) { - throw new \InvalidArgumentException('The following options are not supported: '.implode(', ', array_keys($unsupportedOptions))); - } - - foreach ($default as $key => $defaultValue) { - if (array_key_exists($key, $new)) { - $optionPath = $basePath ? $basePath.'.'.$key : $key; - $current[$key] = $this->mergeOptionValue($current[$key], $new[$key], $defaultValue, $optionPath); - } - } - - return $current; - } - - /** - * Merges an option value. - * - * @param mixed $current The value of the option before merging - * @param mixed $new The new value to be merged - * @param mixed $default The corresponding default value for the option - * @param string $optionPath Property path for the option - * @return mixed The merged value - * @throws InvalidArgumentException When an invalid option is found - */ - protected function mergeOptionValue($current, $new, $defaultValue, $optionPath) - { - // Allow profiler.matcher array to be overridden with any value. This - // option requires no merge logic and would not benefit from the type - // validation below. - if ('profiler.matcher' === $optionPath) { - return $new; - } - - // Ensure that the new value's type is an array if expected - if (is_array($defaultValue) && !is_array($new)) { - throw new \InvalidArgumentException(sprintf('Expected array type for option "%s", %s given', $optionPath, gettype($new))); - } - - switch ($optionPath) { - // Engine options are arrays of strings, although XML configurations - // store the engine ID in an attribute. Dedupe after merging. - case 'templating.engines': - $new = array_map(function($engine) { return is_array($engine) ? $engine['id'] : $engine; }, $new); - return array_unique(array_merge($current, $new)); - - // Loader options are arrays of strings, so dedupe after merging - case 'templating.loaders': - return array_unique(array_merge($current, $new)); - - // The namespace options' keys are used for the annotation prefix - // and are significant, so do not dedupe array values. Be mindful - // of XML configurations, which store the prefix in an attribute. - case 'validation.namespaces': - foreach ($new as $prefix => $namespace) { - if (is_array($namespace)) { - $new[$namespace['prefix']] = $namespace['namespace']; - unset($new[$prefix]); - } - } - return array_merge($current, $new); - } - - return is_array($defaultValue) ? $this->mergeOptions($current, $new, $defaultValue, $optionPath) : $new; - } - /** * Loads the CSRF protection configuration. * * @param array $config A CSRF protection configuration array * @param ContainerBuilder $container A ContainerBuilder instance */ - protected function registerCsrfProtectionConfiguration(array $config, ContainerBuilder $container) + private function registerCsrfProtectionConfiguration(array $config, ContainerBuilder $container) { foreach (array('enabled', 'field_name', 'secret') as $key) { if (isset($config[$key])) { @@ -322,9 +170,9 @@ protected function registerCsrfProtectionConfiguration(array $config, ContainerB * @param array $config An ESI configuration array * @param XmlFileLoader $loader An XmlFileLoader instance */ - protected function registerEsiConfiguration(array $config, XmlFileLoader $loader) + private function registerEsiConfiguration(array $config, XmlFileLoader $loader) { - if ($config['enabled']) { + if (isset($config['enabled']) && $config['enabled']) { $loader->load('esi.xml'); } } @@ -336,12 +184,8 @@ protected function registerEsiConfiguration(array $config, XmlFileLoader $loader * @param ContainerBuilder $container A ContainerBuilder instance * @param XmlFileLoader $loader An XmlFileLoader instance */ - protected function registerProfilerConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader) + private function registerProfilerConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader) { - if (!$config['enabled']) { - return; - } - $loader->load('profiling.xml'); $loader->load('collectors.xml'); @@ -349,7 +193,7 @@ protected function registerProfilerConfiguration(array $config, ContainerBuilder $container->setParameter('profiler_listener.only_exceptions', $config['only_exceptions']); } - if ($config['matcher']) { + if (isset($config['matcher'])) { if (isset($config['matcher']['service'])) { $container->setAlias('profiler.request_matcher', $config['matcher']['service']); } elseif (isset($config['matcher']['ip']) || isset($config['matcher']['path'])) { @@ -373,8 +217,9 @@ protected function registerProfilerConfiguration(array $config, ContainerBuilder * @param array $config A router configuration array * @param ContainerBuilder $container A ContainerBuilder instance * @param XmlFileLoader $loader An XmlFileLoader instance + * @throws \InvalidArgumentException if resource option is not set */ - protected function registerRouterConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader) + private function registerRouterConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader) { $loader->load('routing.xml'); @@ -384,7 +229,7 @@ protected function registerRouterConfiguration(array $config, ContainerBuilder $ $container->setParameter('routing.resource', $config['resource']); - if ($config['cache_warmer']) { + if (isset($config['cache_warmer']) && $config['cache_warmer']) { $container->getDefinition('router.cache_warmer')->addTag('kernel.cache_warmer'); $container->setAlias('router', 'router.cached'); } @@ -395,7 +240,7 @@ protected function registerRouterConfiguration(array $config, ContainerBuilder $ 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher', 'Symfony\\Component\\Routing\\Generator\\UrlGeneratorInterface', 'Symfony\\Component\\Routing\\Generator\\UrlGenerator', - $container->findDefinition('router')->getClass() + $container->findDefinition('router')->getClass(), )); } @@ -406,11 +251,11 @@ protected function registerRouterConfiguration(array $config, ContainerBuilder $ * @param ContainerBuilder $container A ContainerBuilder instance * @param XmlFileLoader $loader An XmlFileLoader instance */ - protected function registerSessionConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader) + private function registerSessionConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader) { $loader->load('session.xml'); - if ($config['auto_start']) { + if (isset($config['auto_start']) && $config['auto_start']) { $container->getDefinition('session')->addMethodCall('start'); } @@ -425,9 +270,9 @@ protected function registerSessionConfiguration(array $config, ContainerBuilder $container->setAlias('session.storage', 'session.storage.'.$config['storage_id']); $options = $container->getParameter('session.storage.'.$config['storage_id'].'.options'); - foreach (array('name', 'lifetime', 'path', 'domain', 'secure', 'httponly', 'pdo.db_table', 'pdo.db_id_col', 'pdo.db_data_col', 'pdo.db_time_col') as $key) { + foreach (array('name', 'lifetime', 'path', 'domain', 'secure', 'httponly', 'db_table', 'db_id_col', 'db_data_col', 'db_time_col') as $key) { if (isset($config[$key])) { - $options[str_replace('pdo.', '', $key)] = $config[$key]; + $options[$key] = $config[$key]; } } $container->setParameter('session.storage.'.$config['storage_id'].'.options', $options); @@ -445,8 +290,9 @@ protected function registerSessionConfiguration(array $config, ContainerBuilder * @param array $config A templating configuration array * @param ContainerBuilder $container A ContainerBuilder instance * @param XmlFileLoader $loader An XmlFileLoader instance + * @throws \LogicException if no engines are defined */ - protected function registerTemplatingConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader) + private function registerTemplatingConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader) { $loader->load('templating.xml'); $loader->load('templating_php.xml'); @@ -463,7 +309,7 @@ protected function registerTemplatingConfiguration(array $config, ContainerBuild $container->setParameter('templating.assets.base_urls', $config['assets_base_urls']); } - if ($config['loaders']) { + if (isset($config['loaders'])) { $loaders = array_map(function($loader) { return new Reference($loader); }, $config['loaders']); // Use a deligation unless only a single loader was registered @@ -475,7 +321,7 @@ protected function registerTemplatingConfiguration(array $config, ContainerBuild } } - if ($config['cache']) { + if (isset($config['cache'])) { // Wrap the existing loader with cache (must happen after loaders are registered) $container->setDefinition('templating.loader.wrapped', $container->findDefinition('templating.loader')); $container->setDefinition('templating.loader', $container->getDefinition('templating.loader.cache')); @@ -484,12 +330,12 @@ protected function registerTemplatingConfiguration(array $config, ContainerBuild $container->setParameter('templating.loader.cache.path', null); } - if ($config['cache_warmer']) { + if (isset($config['cache_warmer'])) { $container->getDefinition('templating.cache_warmer.template_paths')->addTag('kernel.cache_warmer'); $container->setAlias('templating.locator', 'templating.locator.cached'); } - if (!$config['engines']) { + if (empty($config['engines'])) { throw new \LogicException('You must register at least one templating engine.'); } @@ -523,26 +369,17 @@ protected function registerTemplatingConfiguration(array $config, ContainerBuild $container->getDefinition('templating.engine.delegating')->setArgument(1, $engines); $container->setAlias('templating', 'templating.engine.delegating'); } - - } /** * Loads the translator configuration. * - * A translator must always be registered (as support is included by default - * in the forms component). If disabled, an identity translator will be - * used and everything will still work as expected. - * * @param array $config A translator configuration array * @param ContainerBuilder $container A ContainerBuilder instance - * @param XmlFileLoader $loader An XmlFileLoader instance */ - protected function registerTranslatorConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader) + private function registerTranslatorConfiguration(array $config, ContainerBuilder $container) { - $loader->load('translation.xml'); - - if ($config['enabled']) { + if (isset($config['enabled']) && $config['enabled']) { // Use the "real" translator instead of the identity default $container->setDefinition('translator', $container->findDefinition('translator.real')); @@ -585,65 +422,67 @@ protected function registerTranslatorConfiguration(array $config, ContainerBuild * @param ContainerBuilder $container A ContainerBuilder instance * @param XmlFileLoader $loader An XmlFileLoader instance */ - protected function registerValidationConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader) + private function registerValidationConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader) { - if ($config['enabled']) { - $loader->load('validator.xml'); + if (empty($config['enabled'])) { + return; + } - $xmlMappingFiles = array(); - $yamlMappingFiles = array(); + $loader->load('validator.xml'); - // Include default entries from the framework - $xmlMappingFiles[] = __DIR__.'/../../../Component/Form/Resources/config/validation.xml'; + $xmlMappingFiles = array(); + $yamlMappingFiles = array(); - foreach ($container->getParameter('kernel.bundles') as $bundle) { - $reflection = new \ReflectionClass($bundle); - if (file_exists($file = dirname($reflection->getFilename()).'/Resources/config/validation.xml')) { - $xmlMappingFiles[] = realpath($file); - } - if (file_exists($file = dirname($reflection->getFilename()).'/Resources/config/validation.yml')) { - $yamlMappingFiles[] = realpath($file); - } + // Include default entries from the framework + $xmlMappingFiles[] = __DIR__.'/../../../Component/Form/Resources/config/validation.xml'; + + foreach ($container->getParameter('kernel.bundles') as $bundle) { + $reflection = new \ReflectionClass($bundle); + if (file_exists($file = dirname($reflection->getFilename()).'/Resources/config/validation.xml')) { + $xmlMappingFiles[] = realpath($file); } + if (file_exists($file = dirname($reflection->getFilename()).'/Resources/config/validation.yml')) { + $yamlMappingFiles[] = realpath($file); + } + } - $xmlFilesLoader = new Definition('%validator.mapping.loader.xml_files_loader.class%', array($xmlMappingFiles)); - $xmlFilesLoader->setPublic(false); + $xmlFilesLoader = new Definition('%validator.mapping.loader.xml_files_loader.class%', array($xmlMappingFiles)); + $xmlFilesLoader->setPublic(false); - $yamlFilesLoader = new Definition('%validator.mapping.loader.yaml_files_loader.class%', array($yamlMappingFiles)); - $yamlFilesLoader->setPublic(false); + $yamlFilesLoader = new Definition('%validator.mapping.loader.yaml_files_loader.class%', array($yamlMappingFiles)); + $yamlFilesLoader->setPublic(false); - $container->setDefinition('validator.mapping.loader.xml_files_loader', $xmlFilesLoader); - $container->setDefinition('validator.mapping.loader.yaml_files_loader', $yamlFilesLoader); + $container->setDefinition('validator.mapping.loader.xml_files_loader', $xmlFilesLoader); + $container->setDefinition('validator.mapping.loader.yaml_files_loader', $yamlFilesLoader); - foreach ($xmlMappingFiles as $file) { - $container->addResource(new FileResource($file)); - } + foreach ($xmlMappingFiles as $file) { + $container->addResource(new FileResource($file)); + } - foreach ($yamlMappingFiles as $file) { - $container->addResource(new FileResource($file)); - } + foreach ($yamlMappingFiles as $file) { + $container->addResource(new FileResource($file)); + } - if ($config['annotations']) { - // Register prefixes for constraint namespaces - if ($namespaces = $config['namespaces']) { - $container->setParameter('validator.annotations.namespaces', array_merge( - $container->getParameter('validator.annotations.namespaces'), - $namespaces - )); - } + if (isset($config['annotations'])) { + // Register prefixes for constraint namespaces + if (!empty($config['annotations']['namespaces'])) { + $container->setParameter('validator.annotations.namespaces', array_merge( + $container->getParameter('validator.annotations.namespaces'), + $config['annotations']['namespaces'] + )); + } - // Register annotation loader - $annotationLoader = new Definition('%validator.mapping.loader.annotation_loader.class%'); - $annotationLoader->setPublic(false); - $annotationLoader->addArgument(new Parameter('validator.annotations.namespaces')); + // Register annotation loader + $annotationLoader = new Definition('%validator.mapping.loader.annotation_loader.class%'); + $annotationLoader->setPublic(false); + $annotationLoader->addArgument(new Parameter('validator.annotations.namespaces')); - $container->setDefinition('validator.mapping.loader.annotation_loader', $annotationLoader); + $container->setDefinition('validator.mapping.loader.annotation_loader', $annotationLoader); - $loaderChain = $container->getDefinition('validator.mapping.loader.loader_chain'); - $arguments = $loaderChain->getArguments(); - array_unshift($arguments[0], new Reference('validator.mapping.loader.annotation_loader')); - $loaderChain->setArguments($arguments); - } + $loaderChain = $container->getDefinition('validator.mapping.loader.loader_chain'); + $arguments = $loaderChain->getArguments(); + array_unshift($arguments[0], new Reference('validator.mapping.loader.annotation_loader')); + $loaderChain->setArguments($arguments); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd index a32d10a06650..689185a4610c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd @@ -63,7 +63,6 @@ - diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/session_pdo.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/session_pdo.php index edeca35e98da..eb8deb9d1f01 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/session_pdo.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/session_pdo.php @@ -1,9 +1,6 @@ loadFromExtension('app', 'config', array( - 'router' => array( - 'resource' => '%kernel.root_dir%/config/routing.xml', - ), 'session' => array( 'storage_id' => 'pdo', 'pdo.db_table' => 'table', @@ -11,7 +8,4 @@ 'pdo.db_data_col' => 'data', 'pdo.db_time_col' => 'time', ), - 'templating' => array( - 'engine' => 'php' - ), )); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/validation_annotations.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/validation_annotations.php index 90de412f3220..bed6c991b44d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/validation_annotations.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/validation_annotations.php @@ -1,17 +1,12 @@ loadFromExtension('app', 'config', array( - 'router' => array( - 'resource' => '%kernel.root_dir%/config/routing.xml', - ), 'validation' => array( 'enabled' => true, - 'annotations' => true, - 'namespaces' => array( - 'app' => 'Application\\Validator\\Constraints\\', + 'annotations' => array( + 'namespaces' => array( + 'app' => 'Application\\Validator\\Constraints\\', + ), ), ), - 'templating' => array( - 'engine' => 'php' - ), )); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/session_pdo.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/session_pdo.xml index eeb918e8ccaf..84455afff6d0 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/session_pdo.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/session_pdo.xml @@ -7,10 +7,6 @@ http://www.symfony-project.org/schema/dic/symfony http://www.symfony-project.org/schema/dic/symfony/symfony-1.0.xsd"> - - - - diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_annotations.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_annotations.xml index 13da91605a60..1af18e148f7f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_annotations.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_annotations.xml @@ -7,12 +7,8 @@ http://www.symfony-project.org/schema/dic/symfony http://www.symfony-project.org/schema/dic/symfony/symfony-1.0.xsd"> - - - - diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml index 1aecd8ce48d6..bb8d3bc3bc90 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml @@ -28,7 +28,7 @@ app.config: engines: [php, twig] loader: [loader.foo, loader.bar] translator: - enabled: true, + enabled: true fallback: fr validation: enabled: true diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/session_pdo.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/session_pdo.yml index ae8f6ad96130..06323d53de9b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/session_pdo.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/session_pdo.yml @@ -1,11 +1,7 @@ app.config: - router: - resource: %kernel.root_dir%/config/routing.xml session: storage_id: pdo pdo.db_table: table pdo.db_id_col: id pdo.db_data_col: data pdo.db_time_col: time - templating: - engine: php diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/validation_annotations.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/validation_annotations.yml index 3b029f6b6415..1ff2545facb9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/validation_annotations.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/validation_annotations.yml @@ -1,10 +1,6 @@ app.config: - router: - resource: %kernel.root_dir%/config/routing.xml validation: enabled: true - annotations: true - namespaces: - app: Application\Validator\Constraints\ - templating: - engine: php + annotations: + namespaces: + app: Application\Validator\Constraints\