Configuration.php 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  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\Bundle\FrameworkBundle\DependencyInjection;
  11. use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
  12. use Symfony\Component\Config\Definition\Builder\TreeBuilder;
  13. use Symfony\Component\Config\Definition\ConfigurationInterface;
  14. /**
  15. * FrameworkExtension configuration structure.
  16. *
  17. * @author Jeremy Mikola <jmikola@gmail.com>
  18. */
  19. class Configuration implements ConfigurationInterface
  20. {
  21. private $debug;
  22. /**
  23. * @param bool $debug Whether debugging is enabled or not
  24. */
  25. public function __construct($debug)
  26. {
  27. $this->debug = (bool) $debug;
  28. }
  29. /**
  30. * Generates the configuration tree builder.
  31. *
  32. * @return TreeBuilder The tree builder
  33. */
  34. public function getConfigTreeBuilder()
  35. {
  36. $treeBuilder = new TreeBuilder();
  37. $rootNode = $treeBuilder->root('framework');
  38. $rootNode
  39. // Check deprecations before the config is processed to ensure
  40. // the setting has been explicitly defined in a configuration file.
  41. ->beforeNormalization()
  42. ->ifTrue(function ($v) { return isset($v['csrf_protection']['field_name']); })
  43. ->then(function ($v) {
  44. @trigger_error('The framework.csrf_protection.field_name configuration key is deprecated since Symfony 2.4 and will be removed in 3.0. Use the framework.form.csrf_protection.field_name configuration key instead', E_USER_DEPRECATED);
  45. return $v;
  46. })
  47. ->end()
  48. ->validate()
  49. ->ifTrue(function ($v) { return !isset($v['assets']); })
  50. ->then(function ($v) {
  51. if (!isset($v['templating'])
  52. || !$v['templating']['assets_version']
  53. && !\count($v['templating']['assets_base_urls']['http'])
  54. && !\count($v['templating']['assets_base_urls']['ssl'])
  55. && !\count($v['templating']['packages'])
  56. ) {
  57. $v['assets'] = array(
  58. 'version' => null,
  59. 'version_format' => '%%s?%%s',
  60. 'base_path' => '',
  61. 'base_urls' => array(),
  62. 'packages' => array(),
  63. );
  64. }
  65. return $v;
  66. })
  67. ->end()
  68. ->validate()
  69. ->ifTrue(function ($v) { return isset($v['templating']); })
  70. ->then(function ($v) {
  71. if ($v['templating']['assets_version']
  72. || \count($v['templating']['assets_base_urls']['http'])
  73. || \count($v['templating']['assets_base_urls']['ssl'])
  74. || \count($v['templating']['packages'])
  75. ) {
  76. @trigger_error('The assets settings under framework.templating are deprecated since Symfony 2.7 and will be removed in 3.0. Use the framework.assets configuration key instead', E_USER_DEPRECATED);
  77. // convert the old configuration to the new one
  78. if (isset($v['assets'])) {
  79. throw new \LogicException('You cannot use assets settings under "framework.templating" and "assets" configurations in the same project.');
  80. }
  81. $v['assets'] = array(
  82. 'version' => $v['templating']['assets_version'],
  83. 'version_format' => $v['templating']['assets_version_format'],
  84. 'base_path' => '',
  85. 'base_urls' => array_values(array_unique(array_merge($v['templating']['assets_base_urls']['http'], $v['templating']['assets_base_urls']['ssl']))),
  86. 'packages' => array(),
  87. );
  88. foreach ($v['templating']['packages'] as $name => $config) {
  89. $v['assets']['packages'][$name] = array(
  90. 'version' => null === $config['version'] ? null : (string) $config['version'],
  91. 'version_format' => $config['version_format'],
  92. 'base_path' => '',
  93. 'base_urls' => array_values(array_unique(array_merge($config['base_urls']['http'], $config['base_urls']['ssl']))),
  94. );
  95. }
  96. }
  97. unset($v['templating']['assets_version'], $v['templating']['assets_version_format'], $v['templating']['assets_base_urls'], $v['templating']['packages']);
  98. return $v;
  99. })
  100. ->end()
  101. ->beforeNormalization()
  102. ->ifTrue(function ($v) { return isset($v['validation']['api']); })
  103. ->then(function ($v) {
  104. @trigger_error('The validation.api configuration key is deprecated since Symfony 2.7 and will be removed in 3.0', E_USER_DEPRECATED);
  105. return $v;
  106. })
  107. ->end()
  108. ->children()
  109. ->scalarNode('secret')->end()
  110. ->scalarNode('http_method_override')
  111. ->info("Set true to enable support for the '_method' request parameter to determine the intended HTTP method on POST requests. Note: When using the HttpCache, you need to call the method in your front controller instead")
  112. ->defaultTrue()
  113. ->end()
  114. ->arrayNode('trusted_proxies')
  115. ->beforeNormalization()
  116. ->ifTrue(function ($v) { return !\is_array($v) && null !== $v; })
  117. ->then(function ($v) { return \is_bool($v) ? array() : preg_split('/\s*,\s*/', $v); })
  118. ->end()
  119. ->prototype('scalar')
  120. ->validate()
  121. ->ifTrue(function ($v) {
  122. if (empty($v)) {
  123. return false;
  124. }
  125. if (false !== strpos($v, '/')) {
  126. if ('0.0.0.0/0' === $v) {
  127. return false;
  128. }
  129. list($v, $mask) = explode('/', $v, 2);
  130. if (strcmp($mask, (int) $mask) || $mask < 1 || $mask > (false !== strpos($v, ':') ? 128 : 32)) {
  131. return true;
  132. }
  133. }
  134. return !filter_var($v, FILTER_VALIDATE_IP);
  135. })
  136. ->thenInvalid('Invalid proxy IP "%s"')
  137. ->end()
  138. ->end()
  139. ->end()
  140. ->scalarNode('ide')->defaultNull()->end()
  141. ->booleanNode('test')->end()
  142. ->scalarNode('default_locale')->defaultValue('en')->end()
  143. ->arrayNode('trusted_hosts')
  144. ->beforeNormalization()->ifString()->then(function ($v) { return array($v); })->end()
  145. ->prototype('scalar')->end()
  146. ->end()
  147. ->end()
  148. ;
  149. $this->addCsrfSection($rootNode);
  150. $this->addFormSection($rootNode);
  151. $this->addEsiSection($rootNode);
  152. $this->addSsiSection($rootNode);
  153. $this->addFragmentsSection($rootNode);
  154. $this->addProfilerSection($rootNode);
  155. $this->addRouterSection($rootNode);
  156. $this->addSessionSection($rootNode);
  157. $this->addRequestSection($rootNode);
  158. $this->addTemplatingSection($rootNode);
  159. $this->addAssetsSection($rootNode);
  160. $this->addTranslatorSection($rootNode);
  161. $this->addValidationSection($rootNode);
  162. $this->addAnnotationsSection($rootNode);
  163. $this->addSerializerSection($rootNode);
  164. $this->addPropertyAccessSection($rootNode);
  165. $this->addPropertyInfoSection($rootNode);
  166. return $treeBuilder;
  167. }
  168. private function addCsrfSection(ArrayNodeDefinition $rootNode)
  169. {
  170. $rootNode
  171. ->children()
  172. ->arrayNode('csrf_protection')
  173. ->canBeEnabled()
  174. ->children()
  175. ->scalarNode('field_name')
  176. ->defaultValue('_token')
  177. ->info('Deprecated since version 2.4, to be removed in 3.0. Use form.csrf_protection.field_name instead')
  178. ->end()
  179. ->end()
  180. ->end()
  181. ->end()
  182. ;
  183. }
  184. private function addFormSection(ArrayNodeDefinition $rootNode)
  185. {
  186. $rootNode
  187. ->children()
  188. ->arrayNode('form')
  189. ->info('form configuration')
  190. ->canBeEnabled()
  191. ->children()
  192. ->arrayNode('csrf_protection')
  193. ->treatFalseLike(array('enabled' => false))
  194. ->treatTrueLike(array('enabled' => true))
  195. ->treatNullLike(array('enabled' => true))
  196. ->addDefaultsIfNotSet()
  197. ->children()
  198. ->booleanNode('enabled')->defaultNull()->end() // defaults to framework.csrf_protection.enabled
  199. ->scalarNode('field_name')->defaultNull()->end()
  200. ->end()
  201. ->end()
  202. ->end()
  203. ->end()
  204. ->end()
  205. ;
  206. }
  207. private function addEsiSection(ArrayNodeDefinition $rootNode)
  208. {
  209. $rootNode
  210. ->children()
  211. ->arrayNode('esi')
  212. ->info('esi configuration')
  213. ->canBeEnabled()
  214. ->end()
  215. ->end()
  216. ;
  217. }
  218. private function addSsiSection(ArrayNodeDefinition $rootNode)
  219. {
  220. $rootNode
  221. ->children()
  222. ->arrayNode('ssi')
  223. ->info('ssi configuration')
  224. ->canBeEnabled()
  225. ->end()
  226. ->end();
  227. }
  228. private function addFragmentsSection(ArrayNodeDefinition $rootNode)
  229. {
  230. $rootNode
  231. ->children()
  232. ->arrayNode('fragments')
  233. ->info('fragments configuration')
  234. ->canBeEnabled()
  235. ->children()
  236. ->scalarNode('path')->defaultValue('/_fragment')->end()
  237. ->end()
  238. ->end()
  239. ->end()
  240. ;
  241. }
  242. private function addProfilerSection(ArrayNodeDefinition $rootNode)
  243. {
  244. $rootNode
  245. ->children()
  246. ->arrayNode('profiler')
  247. ->info('profiler configuration')
  248. ->canBeEnabled()
  249. ->children()
  250. ->booleanNode('collect')->defaultTrue()->end()
  251. ->booleanNode('only_exceptions')->defaultFalse()->end()
  252. ->booleanNode('only_master_requests')->defaultFalse()->end()
  253. ->scalarNode('dsn')
  254. ->defaultValue('file:%kernel.cache_dir%/profiler')
  255. ->beforeNormalization()
  256. ->ifTrue(function ($v) { return 'file:' !== substr($v, 0, 5); })
  257. ->then(function ($v) {
  258. @trigger_error('The profiler.dsn configuration key must start with "file:" because all the storages except the filesystem are deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
  259. return $v;
  260. })
  261. ->end()
  262. ->end()
  263. ->scalarNode('username')
  264. ->defaultValue('')
  265. ->beforeNormalization()
  266. ->always()
  267. ->then(function ($v) {
  268. @trigger_error('The profiler.username configuration key is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
  269. return $v;
  270. })
  271. ->end()
  272. ->end()
  273. ->scalarNode('password')
  274. ->defaultValue('')
  275. ->beforeNormalization()
  276. ->always()
  277. ->then(function ($v) {
  278. @trigger_error('The profiler.password configuration key is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
  279. return $v;
  280. })
  281. ->end()
  282. ->end()
  283. ->scalarNode('lifetime')
  284. ->defaultValue(86400)
  285. ->beforeNormalization()
  286. ->always()
  287. ->then(function ($v) {
  288. @trigger_error('The profiler.lifetime configuration key is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
  289. return $v;
  290. })
  291. ->end()
  292. ->end()
  293. ->arrayNode('matcher')
  294. ->canBeUnset()
  295. ->performNoDeepMerging()
  296. ->fixXmlConfig('ip')
  297. ->children()
  298. ->scalarNode('path')
  299. ->info('use the urldecoded format')
  300. ->example('^/path to resource/')
  301. ->end()
  302. ->scalarNode('service')->end()
  303. ->arrayNode('ips')
  304. ->beforeNormalization()->ifString()->then(function ($v) { return array($v); })->end()
  305. ->prototype('scalar')->end()
  306. ->end()
  307. ->end()
  308. ->end()
  309. ->end()
  310. ->end()
  311. ->end()
  312. ;
  313. }
  314. private function addRouterSection(ArrayNodeDefinition $rootNode)
  315. {
  316. $rootNode
  317. ->children()
  318. ->arrayNode('router')
  319. ->info('router configuration')
  320. ->canBeUnset()
  321. ->children()
  322. ->scalarNode('resource')->isRequired()->end()
  323. ->scalarNode('type')->end()
  324. ->scalarNode('http_port')->defaultValue(80)->end()
  325. ->scalarNode('https_port')->defaultValue(443)->end()
  326. ->scalarNode('strict_requirements')
  327. ->info(
  328. "set to true to throw an exception when a parameter does not match the requirements\n".
  329. "set to false to disable exceptions when a parameter does not match the requirements (and return null instead)\n".
  330. "set to null to disable parameter checks against requirements\n".
  331. "'true' is the preferred configuration in development mode, while 'false' or 'null' might be preferred in production"
  332. )
  333. ->defaultTrue()
  334. ->end()
  335. ->end()
  336. ->end()
  337. ->end()
  338. ;
  339. }
  340. private function addSessionSection(ArrayNodeDefinition $rootNode)
  341. {
  342. $rootNode
  343. ->children()
  344. ->arrayNode('session')
  345. ->info('session configuration')
  346. ->canBeUnset()
  347. ->children()
  348. ->scalarNode('storage_id')->defaultValue('session.storage.native')->end()
  349. ->scalarNode('handler_id')->defaultValue('session.handler.native_file')->end()
  350. ->scalarNode('name')
  351. ->validate()
  352. ->ifTrue(function ($v) {
  353. parse_str($v, $parsed);
  354. return implode('&', array_keys($parsed)) !== (string) $v;
  355. })
  356. ->thenInvalid('Session name %s contains illegal character(s)')
  357. ->end()
  358. ->end()
  359. ->scalarNode('cookie_lifetime')->end()
  360. ->scalarNode('cookie_path')->end()
  361. ->scalarNode('cookie_domain')->end()
  362. ->booleanNode('cookie_secure')->end()
  363. ->booleanNode('cookie_httponly')->defaultTrue()->end()
  364. ->booleanNode('use_cookies')->end()
  365. ->scalarNode('gc_divisor')->end()
  366. ->scalarNode('gc_probability')->defaultValue(1)->end()
  367. ->scalarNode('gc_maxlifetime')->end()
  368. ->booleanNode('use_strict_mode')->end()
  369. ->scalarNode('save_path')->defaultValue('%kernel.cache_dir%/sessions')->end()
  370. ->integerNode('metadata_update_threshold')
  371. ->defaultValue('0')
  372. ->info('seconds to wait between 2 session metadata updates, it will also prevent the session handler to write if the session has not changed')
  373. ->end()
  374. ->end()
  375. ->end()
  376. ->end()
  377. ;
  378. }
  379. private function addRequestSection(ArrayNodeDefinition $rootNode)
  380. {
  381. $rootNode
  382. ->children()
  383. ->arrayNode('request')
  384. ->info('request configuration')
  385. ->canBeUnset()
  386. ->fixXmlConfig('format')
  387. ->children()
  388. ->arrayNode('formats')
  389. ->useAttributeAsKey('name')
  390. ->prototype('array')
  391. ->beforeNormalization()
  392. ->ifTrue(function ($v) { return \is_array($v) && isset($v['mime_type']); })
  393. ->then(function ($v) { return $v['mime_type']; })
  394. ->end()
  395. ->beforeNormalization()
  396. ->ifTrue(function ($v) { return !\is_array($v); })
  397. ->then(function ($v) { return array($v); })
  398. ->end()
  399. ->prototype('scalar')->end()
  400. ->end()
  401. ->end()
  402. ->end()
  403. ->end()
  404. ->end()
  405. ;
  406. }
  407. private function addTemplatingSection(ArrayNodeDefinition $rootNode)
  408. {
  409. $organizeUrls = function ($urls) {
  410. $urls += array(
  411. 'http' => array(),
  412. 'ssl' => array(),
  413. );
  414. foreach ($urls as $i => $url) {
  415. if (\is_int($i)) {
  416. if (0 === strpos($url, 'https://') || 0 === strpos($url, '//')) {
  417. $urls['http'][] = $urls['ssl'][] = $url;
  418. } else {
  419. $urls['http'][] = $url;
  420. }
  421. unset($urls[$i]);
  422. }
  423. }
  424. return $urls;
  425. };
  426. $rootNode
  427. ->children()
  428. ->arrayNode('templating')
  429. ->info('templating configuration')
  430. ->canBeUnset()
  431. ->children()
  432. ->scalarNode('assets_version')->defaultNull()->info('Deprecated since 2.7, will be removed in 3.0. Use the new assets entry instead.')->end()
  433. ->scalarNode('assets_version_format')->defaultValue('%%s?%%s')->info('Deprecated since 2.7, will be removed in 3.0. Use the new assets entry instead.')->end()
  434. ->scalarNode('hinclude_default_template')->defaultNull()->end()
  435. ->arrayNode('form')
  436. ->addDefaultsIfNotSet()
  437. ->fixXmlConfig('resource')
  438. ->children()
  439. ->arrayNode('resources')
  440. ->addDefaultChildrenIfNoneSet()
  441. ->prototype('scalar')->defaultValue('FrameworkBundle:Form')->end()
  442. ->validate()
  443. ->ifTrue(function ($v) {return !\in_array('FrameworkBundle:Form', $v); })
  444. ->then(function ($v) {
  445. return array_merge(array('FrameworkBundle:Form'), $v);
  446. })
  447. ->end()
  448. ->end()
  449. ->end()
  450. ->end()
  451. ->end()
  452. ->fixXmlConfig('assets_base_url')
  453. ->children()
  454. ->arrayNode('assets_base_urls')
  455. ->info('Deprecated since 2.7, will be removed in 3.0. Use the new assets entry instead.')
  456. ->performNoDeepMerging()
  457. ->addDefaultsIfNotSet()
  458. ->beforeNormalization()
  459. ->ifTrue(function ($v) { return !\is_array($v); })
  460. ->then(function ($v) { return array($v); })
  461. ->end()
  462. ->beforeNormalization()
  463. ->always()
  464. ->then($organizeUrls)
  465. ->end()
  466. ->children()
  467. ->arrayNode('http')
  468. ->prototype('scalar')->end()
  469. ->end()
  470. ->arrayNode('ssl')
  471. ->prototype('scalar')->end()
  472. ->end()
  473. ->end()
  474. ->end()
  475. ->scalarNode('cache')->end()
  476. ->end()
  477. ->fixXmlConfig('engine')
  478. ->children()
  479. ->arrayNode('engines')
  480. ->example(array('twig'))
  481. ->isRequired()
  482. ->requiresAtLeastOneElement()
  483. ->beforeNormalization()
  484. ->ifTrue(function ($v) { return !\is_array($v); })
  485. ->then(function ($v) { return array($v); })
  486. ->end()
  487. ->prototype('scalar')->end()
  488. ->end()
  489. ->end()
  490. ->fixXmlConfig('loader')
  491. ->children()
  492. ->arrayNode('loaders')
  493. ->beforeNormalization()
  494. ->ifTrue(function ($v) { return !\is_array($v); })
  495. ->then(function ($v) { return array($v); })
  496. ->end()
  497. ->prototype('scalar')->end()
  498. ->end()
  499. ->end()
  500. ->fixXmlConfig('package')
  501. ->children()
  502. ->arrayNode('packages')
  503. ->info('Deprecated since 2.7, will be removed in 3.0. Use the new assets entry instead.')
  504. ->useAttributeAsKey('name')
  505. ->prototype('array')
  506. ->fixXmlConfig('base_url')
  507. ->children()
  508. ->scalarNode('version')
  509. ->defaultNull()
  510. ->beforeNormalization()
  511. ->ifTrue(function ($v) { return '' === $v; })
  512. ->then(function ($v) { return; })
  513. ->end()
  514. ->end()
  515. ->scalarNode('version_format')->defaultValue('%%s?%%s')->end()
  516. ->arrayNode('base_urls')
  517. ->performNoDeepMerging()
  518. ->addDefaultsIfNotSet()
  519. ->beforeNormalization()
  520. ->ifTrue(function ($v) { return !\is_array($v); })
  521. ->then(function ($v) { return array($v); })
  522. ->end()
  523. ->beforeNormalization()
  524. ->always()
  525. ->then($organizeUrls)
  526. ->end()
  527. ->children()
  528. ->arrayNode('http')
  529. ->prototype('scalar')->end()
  530. ->end()
  531. ->arrayNode('ssl')
  532. ->prototype('scalar')->end()
  533. ->end()
  534. ->end()
  535. ->end()
  536. ->end()
  537. ->end()
  538. ->end()
  539. ->end()
  540. ->end()
  541. ->end()
  542. ;
  543. }
  544. private function addAssetsSection(ArrayNodeDefinition $rootNode)
  545. {
  546. $rootNode
  547. ->children()
  548. ->arrayNode('assets')
  549. ->info('assets configuration')
  550. ->canBeUnset()
  551. ->fixXmlConfig('base_url')
  552. ->children()
  553. ->scalarNode('version')->defaultNull()->end()
  554. ->scalarNode('version_format')->defaultValue('%%s?%%s')->end()
  555. ->scalarNode('base_path')->defaultValue('')->end()
  556. ->arrayNode('base_urls')
  557. ->requiresAtLeastOneElement()
  558. ->beforeNormalization()
  559. ->ifTrue(function ($v) { return !\is_array($v); })
  560. ->then(function ($v) { return array($v); })
  561. ->end()
  562. ->prototype('scalar')->end()
  563. ->end()
  564. ->end()
  565. ->fixXmlConfig('package')
  566. ->children()
  567. ->arrayNode('packages')
  568. ->useAttributeAsKey('name')
  569. ->prototype('array')
  570. ->fixXmlConfig('base_url')
  571. ->children()
  572. ->scalarNode('version')
  573. ->beforeNormalization()
  574. ->ifTrue(function ($v) { return '' === $v; })
  575. ->then(function ($v) { return; })
  576. ->end()
  577. ->end()
  578. ->scalarNode('version_format')->defaultNull()->end()
  579. ->scalarNode('base_path')->defaultValue('')->end()
  580. ->arrayNode('base_urls')
  581. ->requiresAtLeastOneElement()
  582. ->beforeNormalization()
  583. ->ifTrue(function ($v) { return !\is_array($v); })
  584. ->then(function ($v) { return array($v); })
  585. ->end()
  586. ->prototype('scalar')->end()
  587. ->end()
  588. ->end()
  589. ->end()
  590. ->end()
  591. ->end()
  592. ->end()
  593. ->end()
  594. ;
  595. }
  596. private function addTranslatorSection(ArrayNodeDefinition $rootNode)
  597. {
  598. $rootNode
  599. ->children()
  600. ->arrayNode('translator')
  601. ->info('translator configuration')
  602. ->canBeEnabled()
  603. ->fixXmlConfig('fallback')
  604. ->fixXmlConfig('path')
  605. ->children()
  606. ->arrayNode('fallbacks')
  607. ->beforeNormalization()->ifString()->then(function ($v) { return array($v); })->end()
  608. ->prototype('scalar')->end()
  609. ->defaultValue(array('en'))
  610. ->end()
  611. ->booleanNode('logging')->defaultValue($this->debug)->end()
  612. ->arrayNode('paths')
  613. ->prototype('scalar')->end()
  614. ->end()
  615. ->end()
  616. ->end()
  617. ->end()
  618. ;
  619. }
  620. private function addValidationSection(ArrayNodeDefinition $rootNode)
  621. {
  622. $rootNode
  623. ->children()
  624. ->arrayNode('validation')
  625. ->info('validation configuration')
  626. ->canBeEnabled()
  627. ->children()
  628. ->scalarNode('cache')
  629. ->beforeNormalization()
  630. // Can be removed in 3.0, once ApcCache support is dropped
  631. ->ifString()->then(function ($v) {
  632. if ('apc' === $v) {
  633. @trigger_error('The ability to pass "apc" as the framework.validation.cache configuration key value is deprecated since Symfony 2.8 and will be removed in 3.0. Use the "validator.mapping.cache.doctrine.apc" service id instead.', E_USER_DEPRECATED);
  634. return 'validator.mapping.cache.apc';
  635. }
  636. return $v;
  637. })
  638. ->end()
  639. ->end()
  640. ->booleanNode('enable_annotations')->defaultFalse()->end()
  641. ->arrayNode('static_method')
  642. ->defaultValue(array('loadValidatorMetadata'))
  643. ->prototype('scalar')->end()
  644. ->treatFalseLike(array())
  645. ->validate()
  646. ->ifTrue(function ($v) { return !\is_array($v); })
  647. ->then(function ($v) { return (array) $v; })
  648. ->end()
  649. ->end()
  650. ->scalarNode('translation_domain')->defaultValue('validators')->end()
  651. ->booleanNode('strict_email')->defaultFalse()->end()
  652. ->enumNode('api')
  653. ->info('Deprecated since version 2.7, to be removed in 3.0')
  654. ->values(array('2.4', '2.5', '2.5-bc', 'auto'))
  655. ->beforeNormalization()
  656. // XML/YAML parse as numbers, not as strings
  657. ->ifTrue(function ($v) { return is_scalar($v); })
  658. ->then(function ($v) { return (string) $v; })
  659. ->end()
  660. ->end()
  661. ->end()
  662. ->end()
  663. ->end()
  664. ;
  665. }
  666. private function addAnnotationsSection(ArrayNodeDefinition $rootNode)
  667. {
  668. $rootNode
  669. ->children()
  670. ->arrayNode('annotations')
  671. ->info('annotation configuration')
  672. ->addDefaultsIfNotSet()
  673. ->children()
  674. ->scalarNode('cache')->defaultValue('file')->end()
  675. ->scalarNode('file_cache_dir')->defaultValue('%kernel.cache_dir%/annotations')->end()
  676. ->booleanNode('debug')->defaultValue($this->debug)->end()
  677. ->end()
  678. ->end()
  679. ->end()
  680. ;
  681. }
  682. private function addSerializerSection(ArrayNodeDefinition $rootNode)
  683. {
  684. $rootNode
  685. ->children()
  686. ->arrayNode('serializer')
  687. ->info('serializer configuration')
  688. ->canBeEnabled()
  689. ->children()
  690. ->booleanNode('enable_annotations')->defaultFalse()->end()
  691. ->scalarNode('cache')->end()
  692. ->scalarNode('name_converter')->end()
  693. ->end()
  694. ->end()
  695. ->end()
  696. ;
  697. }
  698. private function addPropertyAccessSection(ArrayNodeDefinition $rootNode)
  699. {
  700. $rootNode
  701. ->children()
  702. ->arrayNode('property_access')
  703. ->addDefaultsIfNotSet()
  704. ->info('Property access configuration')
  705. ->children()
  706. ->booleanNode('magic_call')->defaultFalse()->end()
  707. ->booleanNode('throw_exception_on_invalid_index')->defaultFalse()->end()
  708. ->end()
  709. ->end()
  710. ->end()
  711. ;
  712. }
  713. private function addPropertyInfoSection(ArrayNodeDefinition $rootNode)
  714. {
  715. $rootNode
  716. ->children()
  717. ->arrayNode('property_info')
  718. ->info('Property info configuration')
  719. ->canBeEnabled()
  720. ->end()
  721. ->end()
  722. ;
  723. }
  724. }