diff --git a/ChillMainBundle.php b/ChillMainBundle.php
index ba3afd7af..bb4c675a7 100644
--- a/ChillMainBundle.php
+++ b/ChillMainBundle.php
@@ -5,6 +5,7 @@ namespace Chill\MainBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Chill\MainBundle\DependencyInjection\SearchableServicesCompilerPass;
+use Chill\MainBundle\DependencyInjection\ConfigConsistencyCompilerPass;
class ChillMainBundle extends Bundle
{
@@ -12,5 +13,6 @@ class ChillMainBundle extends Bundle
{
parent::build($container);
$container->addCompilerPass(new SearchableServicesCompilerPass());
+ $container->addCompilerPass(new ConfigConsistencyCompilerPass());
}
}
diff --git a/DependencyInjection/ConfigConsistencyCompilerPass.php b/DependencyInjection/ConfigConsistencyCompilerPass.php
new file mode 100644
index 000000000..ba7e0052b
--- /dev/null
+++ b/DependencyInjection/ConfigConsistencyCompilerPass.php
@@ -0,0 +1,61 @@
+
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+namespace Chill\MainBundle\DependencyInjection;
+
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+
+/**
+ * Description of ConfigConsistencyCompilerPass
+ *
+ * @author Julien Fastré
+ */
+class ConfigConsistencyCompilerPass implements CompilerPassInterface
+{
+ public function process(ContainerBuilder $container)
+ {
+ $availableLanguages = $container
+ ->getParameter('chill_main.available_languages');
+ $methodCallsTranslator = $container
+ ->findDefinition('translator.default')
+ ->getMethodCalls();
+
+ $fallbackLocales = array();
+ foreach($methodCallsTranslator as $call) {
+ if ($call[0] === 'setFallbackLocales') {
+ $fallbackLocales = array_merge($fallbackLocales,
+ $call[1][0]);
+ }
+ }
+
+ if (count($fallbackLocales) === 0) {
+ throw new \LogicException('the fallback locale are not defined. '
+ . 'The framework config should not allow this.');
+ }
+
+ $diff = array_diff($fallbackLocales, $availableLanguages);
+ if (count($diff) > 0) {
+ throw new \RuntimeException(sprintf('The chill_main.available_languages'
+ . ' parameter does not contains fallback locales. The languages %s'
+ . ' are missing.', implode(', ', $diff)));
+ }
+ }
+}
diff --git a/Tests/DependencyInjection/ConfigConsistencyCompilerPassTest.php b/Tests/DependencyInjection/ConfigConsistencyCompilerPassTest.php
new file mode 100644
index 000000000..bf0906266
--- /dev/null
+++ b/Tests/DependencyInjection/ConfigConsistencyCompilerPassTest.php
@@ -0,0 +1,179 @@
+
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+namespace Chill\MainBundle\Tests\DependencyInjection;
+
+use Chill\MainBundle\DependencyInjection\ConfigConsistencyCompilerPass;
+use Symfony\Component\DependencyInjection\ContainerBuilderInterface;
+
+/**
+ * Description of ConfigConsistencyCompilerPassTest
+ *
+ * @author Julien Fastré
+ */
+class ConfigConsistencyCompilerPassTest extends \PHPUnit_Framework_TestCase
+{
+
+ /**
+ *
+ *
+ * @var \Chill\MainBundle\DependencyInjection\ConfigConsistencyCompilerPass
+ */
+ private $configConsistencyCompilerPass;
+
+ public function setUp()
+ {
+ $this->configConsistencyCompilerPass = new ConfigConsistencyCompilerPass();
+ }
+
+ /**
+ * Test that everything is fine is configuration is correct
+ *
+ */
+ public function testLanguagesArePresent()
+ {
+ try {
+ $this ->configConsistencyCompilerPass
+ ->process(
+ $this->mockContainer(
+ $this->mockTranslatorDefinition(array('fr')),
+ array('fr', 'nl')
+ )
+ );
+ $this->assertTrue(TRUE, 'the config consistency can process');
+ } catch (\Exception $ex) {
+ $this->assertTrue(FALSE,
+ 'the config consistency can process');
+ }
+ }
+
+ /**
+ * Test that everything is fine is configuration is correct
+ * if multiple fallback languages are present
+ *
+ */
+ public function testMultiplesLanguagesArePresent()
+ {
+ try {
+ $this ->configConsistencyCompilerPass
+ ->process(
+ $this->mockContainer(
+ $this->mockTranslatorDefinition(array('fr', 'nl')),
+ array('fr', 'nl', 'en')
+ )
+ );
+ $this->assertTrue(TRUE, 'the config consistency can process');
+ } catch (\Exception $ex) {
+ $this->assertTrue(FALSE,
+ 'the config consistency can process');
+ }
+ }
+
+
+
+ /**
+ * Test that a runtime exception is throw if the available language does
+ * not contains the fallback locale
+ *
+ * @expectedException \RuntimeException
+ * @expectedExceptionMessageRegExp /The chill_main.available_languages parameter does not contains fallback locales./
+ */
+ public function testLanguageNotPresent()
+ {
+ $container = $this->mockContainer(
+ $this->mockTranslatorDefinition(array('en')), array('fr')
+ );
+
+ $this->configConsistencyCompilerPass->process($container);
+ }
+
+ /**
+ * Test that a logic exception is thrown if the setFallbackLocale
+ * method is not defined in translator definition
+ *
+ * @expectedException \LogicException
+ */
+ public function testSetFallbackNotDefined()
+ {
+ $container = $this->mockContainer(
+ $this->mockTranslatorDefinition(NULL), array('fr')
+ );
+ $this->configConsistencyCompilerPass->process($container);
+ }
+
+ /**
+ * @return ContainerBuilder
+ */
+ private function mockContainer($definition, $availableLanguages)
+ {
+ $container = $this
+ ->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')
+ ->getMock();
+
+ $container->method('getParameter')
+ ->will($this->returnCallback(
+ function($parameter) use ($availableLanguages) {
+ if ($parameter === 'chill_main.available_languages') {
+ return $availableLanguages;
+ } else {
+ throw new \LogicException("the parameter '$parameter' "
+ . "is not defined in stub test");
+ }
+ }
+ ));
+
+ $container->method('findDefinition')
+ ->will($this->returnCallback(
+ function($id) use ($definition) {
+ if (in_array($id, array('translator', 'translator.default'))) {
+ return $definition;
+ } else {
+ throw new \LogicException("the id $id is not defined in test");
+ }
+ }));
+
+
+ return $container;
+ }
+
+ /**
+ *
+ * @param type $languages
+ * @return 'Symfony\Component\DependencyInjection\Definition'
+ */
+ private function mockTranslatorDefinition(array $languages = NULL)
+ {
+ $definition = $this
+ ->getMockBuilder('Symfony\Component\DependencyInjection\Definition')
+ ->getMock();
+
+ if (NULL !== $languages) {
+ $definition->method('getMethodCalls')
+ ->willReturn(array(
+ ['setFallbackLocales', array($languages)]
+ ));
+ } else {
+ $definition->method('getMethodCalls')
+ ->willReturn(array(['nothing', array()]));
+ }
+
+ return $definition;
+ }
+}