Skip to content
This repository has been archived by the owner on Jan 29, 2020. It is now read-only.

Commit

Permalink
Merge pull request zendframework/zendframework#4860 from sarge-ch/abs…
Browse files Browse the repository at this point in the history
…tract-config-factory

abstract factory for configs reading keys from merged config
  • Loading branch information
weierophinney committed Oct 22, 2013
177 parents 648b498 + 6da2074 + 26ea7ff + 44bad20 + 47ff527 + 33b5707 + 0f253b5 + 644d22a + f3cba00 + e470732 + ae8cd95 + a4f21b6 + f36ff90 + 5344247 + 5cdfa08 + 4925e55 + fb107e5 + 98634df + 8d23ab7 + 19e17a6 + 98ac67f + 0a2d51c + 86db540 + efbb513 + 24c143c + 307427e + 4c7a822 + 25d3bd7 + 40bfe7f + 70ca2ff + 76fd684 + 82cff31 + 186a39c + 39a35fe + b0c8193 + 1a7e426 + 09ea754 + 8317963 + 950705c + bd78289 + 25f3e05 + 1c0577b + 6bcfccb + 0b2a1a9 + 7974490 + f3ba45e + 4357e80 + 7d43d02 + 421a0f4 + e7aa329 + 6d05bfe + f27c5e2 + 6cb3b21 + 1ecb5ed + b66b0e2 + 0b91e40 + 6bda391 + b932fa5 + a431b75 + 9ce83ec + a35dff6 + 60e4965 + 0f071e9 + 3fe17b4 + 196ca18 + 17cbc64 + 8f4a51f + 88ec12d + 31ab35e + 59c83c4 + d50da4c + 01af50b + 6a46af5 + 4308adc + 1c3d629 + 18a268d + 1987408 + abc72db + 175f7ab + 8a85704 + 7706019 + cc5d38c + fbaa5aa + 0555415 + 20ae04b + 0680687 + e65301c + 424e30a + d36a7f1 + 64bb794 + c74649b + b14bb6b + 4e73e4e + 0ee93d0 + e887bfd + f66ad20 + 66c5ff2 + f5b2841 + 717175b + 52c5e49 + 8f39d69 + 2003fce + 1ccb3fd + 315a9ac + 2b82c0f + 1565409 + fd7399e + cb27129 + 62ca6c9 + 7b73995 + 18f93e0 + 72fe59b + 9f5b116 + 28a04a3 + b56ee4d + 9287e61 + 1a420ec + 6a43cc1 + ad11b96 + cf95523 + 25ef603 + 894f762 + c00c005 + 69fb7fc + 57cb4a0 + e25b09c + 17a7c5c + c526cd4 + 518ca6f + 57fa76c + 853c28f + 520cebc + dc5f609 + ccf1c7e + 251b79e + 78fbb55 + fcc04e7 + 9bf2948 + 9561532 + b614ad3 + 954a3b1 + dacc257 + 07a262d + 59c02c3 + 7064caa + 6f75739 + 747b7ed + eb24d30 + 8ff8298 + 97c61d8 + da4af46 + 11c9caf + cc11df8 + cd54577 + 298afbb + 24c5cf6 + fa546ac + 5e4d7a6 + cddbfdf + 7e73be1 + ecda841 + dc32703 + 9bb6302 + fee2498 + f827502 + 4b8d9e1 + eff3fbb + 240c93a + 3778e71 + c7f821e + c2f7d37 + 4abae37 + fa5d8fc + dd30c3d + 14d7077 + f84ebc9 + 7846df7 commit 24da9af
Show file tree
Hide file tree
Showing 2 changed files with 302 additions and 0 deletions.
172 changes: 172 additions & 0 deletions src/AbstractConfigFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace Zend\Config;

use Traversable;
use Zend\ServiceManager;

/**
* Class AbstractConfigFactory
*/
class AbstractConfigFactory implements ServiceManager\AbstractFactoryInterface
{
/**
* @var array
*/
protected $configs = array();

/**
* @var string[]
*/
protected $defaultPatterns = array(
'#config[\._-](.*)$#i',
'#^(.*)[\\\\\._-]config$#i'
);

/**
* @var string[]
*/
protected $patterns;

/**
* Determine if we can create a service with name
*
* @param ServiceManager\ServiceLocatorInterface $serviceLocator
* @param string $name
* @param string $requestedName
* @return bool
*/
public function canCreateServiceWithName(ServiceManager\ServiceLocatorInterface $serviceLocator, $name, $requestedName)
{
if (isset($this->configs[$requestedName])) {
return true;
}

if (!$serviceLocator->has('Config')) {
return false;
}

$key = $this->match($requestedName);
if (null === $key) {
return false;
}

$config = $serviceLocator->get('Config');
return isset($config[$key]);
}

/**
* Create service with name
*
* @param ServiceManager\ServiceLocatorInterface $serviceLocator
* @param string $name
* @param string $requestedName
* @return string|mixed|array
*/
public function createServiceWithName(ServiceManager\ServiceLocatorInterface $serviceLocator, $name, $requestedName)
{
if (isset($this->configs[$requestedName])) {
return $this->configs[$requestedName];
}

$key = $this->match($requestedName);
if (isset($this->configs[$key])) {
$this->configs[$requestedName] = $this->configs[$key];
return $this->configs[$key];
}

$config = $serviceLocator->get('Config');
$this->configs[$requestedName] = $this->configs[$key] = $config[$key];
return $config;
}

/**
* @param string $pattern
* @return self
* @throws Exception\InvalidArgumentException
*/
public function addPattern($pattern)
{
if (!is_string($pattern)) {
throw new Exception\InvalidArgumentException('pattern must be string');
}

$patterns = $this->getPatterns();
array_unshift($patterns, $pattern);
$this->setPatterns($patterns);
return $this;
}

/**
* @param array|Traversable $patterns
* @return self
* @throws Exception\InvalidArgumentException
*/
public function addPatterns($patterns)
{
if ($patterns instanceof Traversable) {
$patterns = iterator_to_array($patterns);
}

if (!is_array($patterns)) {
throw new Exception\InvalidArgumentException("patterns must be array or Traversable");
}

foreach ($patterns as $pattern) {
$this->addPattern($pattern);
}

return $this;
}

/**
* @param array|Traversable $patterns
* @return self
* @throws \InvalidArgumentException
*/
public function setPatterns($patterns)
{
if ($patterns instanceof Traversable) {
$patterns = iterator_to_array($patterns);
}

if (!is_array($patterns)) {
throw new \InvalidArgumentException("patterns must be array or Traversable");
}

$this->patterns = $patterns;
return $this;
}

/**
* @return array
*/
public function getPatterns()
{
if (null === $this->patterns) {
$this->setPatterns($this->defaultPatterns);
}
return $this->patterns;
}

/**
* @param string $requestedName
* @return null|string
*/
protected function match($requestedName)
{
foreach ($this->getPatterns() as $pattern) {
if (preg_match($pattern, $requestedName, $matches)) {
return $matches[1];
}
}
return null;
}
}
130 changes: 130 additions & 0 deletions test/AbstractFactoryTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<?php
/**
* AbstractFactoryTest.php
*
* @author Chris Raidler <[email protected]>
* @copyright Copyright 2012 - 2013, raidler dot com
*/
namespace ZendTest\Config;

use Zend\Config\AbstractConfigFactory;
use Zend\Mvc\Service\ServiceManagerConfig;
use Zend\ServiceManager;

/**
* Class AbstractFactoryTest
*/
class AbstractFactoryTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \Zend\Mvc\Application
*/
protected $application;

/**
* @var \Zend\ServiceManager\ServiceManager
*/
protected $serviceManager;

/**
* @return void
*/
public function setUp()
{
$config = array(
'MyModule' => array(
'foo' => array(
'bar'
)
),
'phly-blog' => array(
'foo' => array(
'bar'
)
)
);

$sm = $this->serviceManager = new ServiceManager\ServiceManager(
new ServiceManagerConfig(array(
'abstract_factories' => array(
'Zend\Config\AbstractConfigFactory',
)
))
);

$sm->setService('Config', $config);
}

/**
* @expectedException InvalidArgumentException
* @return void
*/
public function testInvalidPattern()
{
$factory = new AbstractConfigFactory();
$factory->addPattern(new \stdClass());
}

/**
* @expectedException InvalidArgumentException
* @return void
*/
public function testInvalidPatternIterator()
{
$factory = new AbstractConfigFactory();
$factory->addPatterns('invalid');
}

/**
* @return void
*/
public function testPatterns()
{
$factory = new AbstractConfigFactory();
$defaults = $factory->getPatterns();

// Tests that the accessor returns an array
$this->assertInternalType('array', $defaults);
$this->assertGreaterThan(0, count($defaults));

// Tests adding a single pattern
$this->assertSame($factory, $factory->addPattern('#foobarone#i'));
$this->assertCount(count($defaults) + 1, $factory->getPatterns());

// Tests adding multiple patterns at once
$patterns = $factory->getPatterns();
$this->assertSame($factory, $factory->addPatterns(array('#foobartwo#i', '#foobarthree#i')));
$this->assertCount(count($patterns) + 2, $factory->getPatterns());

// Tests whether the latest added pattern is the first in stack
$patterns = $factory->getPatterns();
$this->assertSame('#foobarthree#i', $patterns[0]);
}

/**
* @return void
*/
public function testCanCreateService()
{
$factory = new AbstractConfigFactory();
$serviceLocator = $this->serviceManager;

$this->assertFalse($factory->canCreateServiceWithName($serviceLocator, 'mymodulefail', 'MyModule\Fail'));
$this->assertTrue($factory->canCreateServiceWithName($serviceLocator, 'mymoduleconfig', 'MyModule\Config'));
}

/**
* @depends testCanCreateService
* @return void
*/
public function testCreateService()
{
$serviceLocator = $this->serviceManager;
$this->assertInternalType('array', $serviceLocator->get('MyModule\Config'));
$this->assertInternalType('array', $serviceLocator->get('MyModule_Config'));
$this->assertInternalType('array', $serviceLocator->get('Config.MyModule'));
$this->assertInternalType('array', $serviceLocator->get('phly-blog.config'));
$this->assertInternalType('array', $serviceLocator->get('phly-blog-config'));
$this->assertInternalType('array', $serviceLocator->get('config-phly-blog'));
}
}

0 comments on commit 24da9af

Please sign in to comment.