diff --git a/composer.lock b/composer.lock index 40057d2645f99ceaeb8e5b76a8a9219b55dd2308..d4024367adcc7d51ebebe9d89963fbae4c017acc 100644 --- a/composer.lock +++ b/composer.lock @@ -269,12 +269,12 @@ "source": { "type": "git", "url": "https://github.com/mnapoli/PHP-DI.git", - "reference": "dad96f16334492ff387a4f8bc48c5f9f0e01e4a7" + "reference": "27341c05b930e3768f19f4c4b20eec14ce84bd06" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mnapoli/PHP-DI/zipball/dad96f16334492ff387a4f8bc48c5f9f0e01e4a7", - "reference": "dad96f16334492ff387a4f8bc48c5f9f0e01e4a7", + "url": "https://api.github.com/repos/mnapoli/PHP-DI/zipball/27341c05b930e3768f19f4c4b20eec14ce84bd06", + "reference": "27341c05b930e3768f19f4c4b20eec14ce84bd06", "shasum": "" }, "require": { @@ -319,7 +319,7 @@ "dependency injection", "di" ], - "time": "2014-11-10 01:38:05" + "time": "2014-11-12 03:18:24" }, { "name": "mnapoli/phpdocreader", diff --git a/core/Container/IniConfigDefinitionSource.php b/core/Container/IniConfigDefinitionSource.php new file mode 100644 index 0000000000000000000000000000000000000000..b84d33d94f6e3e0226d837229843b83d7c1b184a --- /dev/null +++ b/core/Container/IniConfigDefinitionSource.php @@ -0,0 +1,114 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +namespace Piwik\Container; + +use DI\Definition\Exception\DefinitionException; +use DI\Definition\MergeableDefinition; +use DI\Definition\Source\ChainableDefinitionSource; +use DI\Definition\Source\DefinitionSource; +use DI\Definition\ValueDefinition; +use Piwik\Config; + +/** + * Import the old INI config into PHP-DI. + */ +class IniConfigDefinitionSource implements DefinitionSource, ChainableDefinitionSource +{ + /** + * @var Config + */ + private $config; + + /** + * @var string + */ + private $prefix; + + /** + * @var DefinitionSource + */ + private $chainedSource; + + /** + * @param Config $config + * @param string $prefix Prefix for the container entries. + */ + public function __construct(Config $config, $prefix = 'old_config.') + { + $this->config = $config; + $this->prefix = $prefix; + } + + public function getDefinition($name, MergeableDefinition $parentDefinition = null) + { + // INI only contains values, so no definition merging here + if ($parentDefinition) { + return $this->notFound($name, $parentDefinition); + } + + if (strpos($name, $this->prefix) !== 0) { + return $this->notFound($name, $parentDefinition); + } + + list($sectionName, $configKey) = $this->parseEntryName($name); + + $section = $this->getSection($sectionName); + + if ($configKey === null) { + return new ValueDefinition($name, $section); + } + + if (! array_key_exists($configKey, $section)) { + return $this->notFound($name, $parentDefinition); + } + + return new ValueDefinition($name, $section[$configKey]); + } + + public function chain(DefinitionSource $source) + { + $this->chainedSource = $source; + } + + private function parseEntryName($name) + { + $parts = explode('.', $name, 3); + + array_shift($parts); + + if (! isset($parts[1])) { + $parts[1] = null; + } + + return $parts; + } + + private function getSection($sectionName) + { + $section = $this->config->$sectionName; + + if (!is_array($section)) { + throw new DefinitionException(sprintf( + 'Piwik\Config did not return an array for the config section %s', + $section + )); + } + + return $section; + } + + private function notFound($name, $parentDefinition) + { + if ($this->chainedSource) { + return $this->chainedSource->getDefinition($name, $parentDefinition); + } + + return null; + } +} diff --git a/core/Container/StaticContainer.php b/core/Container/StaticContainer.php index 2f950198ec980f35f2e9568ecece21577f22e493..5948ec1c78040931a967ba979d2c6c573f40f7e5 100644 --- a/core/Container/StaticContainer.php +++ b/core/Container/StaticContainer.php @@ -11,6 +11,7 @@ namespace Piwik\Container; use DI\Container; use DI\ContainerBuilder; use Doctrine\Common\Cache\ArrayCache; +use Piwik\Config; /** * This class provides a static access to the container. @@ -48,9 +49,11 @@ class StaticContainer } $builder = new ContainerBuilder(); - // TODO add cache + // TODO set a better cache $builder->setDefinitionCache(new ArrayCache()); - // $builder->writeProxiesToFile(true, PIWIK_USER_PATH . '/tmp/proxies'); + + // Old global INI config + $builder->addDefinitions(new IniConfigDefinitionSource(Config::getInstance())); // Global config $builder->addDefinitions(PIWIK_USER_PATH . '/config/global.php'); diff --git a/tests/PHPUnit/Unit/Container/IniConfigDefinitionSourceTest.php b/tests/PHPUnit/Unit/Container/IniConfigDefinitionSourceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..a418b9e705bd5aac8eceec2e1bcc9632a61c303c --- /dev/null +++ b/tests/PHPUnit/Unit/Container/IniConfigDefinitionSourceTest.php @@ -0,0 +1,124 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +namespace Piwik\Tests\Unit\Container; + +use DI\Definition\ValueDefinition; +use Piwik\Config; +use Piwik\Container\IniConfigDefinitionSource; + +class IniConfigDefinitionSourceTest extends \PHPUnit_Framework_TestCase +{ + /** + * @test + */ + public function getDefinition_withMergeableDefinition_shouldReturnNull() + { + $definition = $this->getMockForAbstractClass('DI\Definition\MergeableDefinition'); + + $definitionSource = new IniConfigDefinitionSource($this->createConfig()); + + $this->assertNull($definitionSource->getDefinition('foo', $definition)); + } + + /** + * @test + */ + public function getDefinition_whenNotMatchingPrefix_shouldReturnNull() + { + $definitionSource = new IniConfigDefinitionSource($this->createConfig(), 'prefix.'); + + $this->assertNull($definitionSource->getDefinition('foo')); + } + + /** + * @test + */ + public function getDefinition_withUnknownConfigSection_shouldReturnEmptyArray() + { + $definitionSource = new IniConfigDefinitionSource(Config::getInstance()); + + /** @var ValueDefinition $definition */ + $definition = $definitionSource->getDefinition('old_config.foo'); + + $this->assertTrue($definition instanceof ValueDefinition); + $this->assertEquals('old_config.foo', $definition->getName()); + $this->assertSame(array(), $definition->getValue()); + } + + /** + * @test + */ + public function getDefinition_withUnknownConfigSectionAndKey_shouldReturnNull() + { + $definitionSource = new IniConfigDefinitionSource(Config::getInstance()); + + $this->assertNull($definitionSource->getDefinition('old_config.foo.bar')); + } + + /** + * @test + */ + public function getDefinition_withUnknownConfigKey_shouldReturnNull() + { + $definitionSource = new IniConfigDefinitionSource(Config::getInstance()); + + $this->assertNull($definitionSource->getDefinition('old_config.General.foo')); + } + + /** + * @test + */ + public function getDefinition_withExistingConfigSection_shouldReturnValueDefinition() + { + $config = $this->createConfig(); + $config->expects($this->once()) + ->method('__get') + ->with('General') + ->willReturn(array('foo' => 'bar')); + + $definitionSource = new IniConfigDefinitionSource($config); + + /** @var ValueDefinition $definition */ + $definition = $definitionSource->getDefinition('old_config.General'); + + $this->assertTrue($definition instanceof ValueDefinition); + $this->assertEquals('old_config.General', $definition->getName()); + $this->assertInternalType('array', $definition->getValue()); + $this->assertEquals(array('foo' => 'bar'), $definition->getValue()); + } + + /** + * @test + */ + public function getDefinition_withExistingConfigKey_shouldReturnValueDefinition() + { + $config = $this->createConfig(); + $config->expects($this->once()) + ->method('__get') + ->with('General') + ->willReturn(array('foo' => 'bar')); + + $definitionSource = new IniConfigDefinitionSource($config); + + /** @var ValueDefinition $definition */ + $definition = $definitionSource->getDefinition('old_config.General.foo'); + + $this->assertTrue($definition instanceof ValueDefinition); + $this->assertEquals('old_config.General.foo', $definition->getName()); + $this->assertEquals('bar', $definition->getValue()); + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject|Config + */ + private function createConfig() + { + return $this->getMock('Piwik\Config', array(), array(), '', false); + } +}