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

abstract factory for configs reading keys from merged config #4860

Merged
merged 13 commits into from Oct 22, 2013
Merged

abstract factory for configs reading keys from merged config #4860

merged 13 commits into from Oct 22, 2013

Conversation

ghost
Copy link

@ghost ghost commented Jul 20, 2013

this abstract factory can be activated in your service manager config like this:

'service_manager' => array(
    'abstract_factories' => array(
        'Zend\Config\AbstractConfigFactory'
    )
);

it will factor a \Zend\Config\Config object for requested names like

$serviceLocator->get('MyModule\Sub\Config');

where in this case the key MyModule\Sub has to exist in the merged Config.

@ghost
Copy link
Author

ghost commented Jul 20, 2013

travis failed on php 5.3.3 build only, all others are good. i cant find the issue here :-(

/**
* @var string
*/
protected $pattern = '#^(.*)\\\\Config$#i';
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could be done more performant using strrpos

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm honestly not sure about the regex.

I've seen a lot of modules not use their namespace for the module-specific config key, but instead a normalized version. As an example, ZfcUser uses the key "zfc-user"; I use "phly-blog", "phly-simple-page", etc. As such, using a namespace separator and class-like naming feels off.

It might make sense to have several regexes to check against, and allow injecting additional ones (developers could attach the abstract factory by instantiating it, injecting it, and then adding it to the ServiceManager). If so, I'd include the following:

  • #config[._-](.*)$#i
  • #^(.*)[\\\\._-]config$#i

That would likely capture the bulk of existing modules, allowing them to adopt the convention by either suffixing or prepending some verbiage ("config.", "config-", "config_", "-config", ".config", "_config", "\Config") to their existing keys based on the style they've already adopted.

Then, either add a setter or a constructor with an optional dependency that allows providing additional regex to use; these should be preferred over the defaults, so treat them like a stack when matching.

It will mean a little more work matching, but be a bit more flexible and allow for different naming styles.

@weierophinney
Copy link
Member

Please add unit tests, @sarge-ch

@ghost
Copy link
Author

ghost commented Aug 20, 2013

Thanks, added a TestCase, 3 Tests with 4 Assertionms. This ran though on travis:

[concat] ZendTest/Config
[concat]
[concat] PHPUnit 3.7.24 by Sebastian Bergmann.
[concat]
[concat] Configuration read from /home/travis/build/zendframework/zf2/tests/phpunit.xml.dist
[concat]
[concat] ............................................................... 63 / 140 ( 45%)
[concat] ..........................................SSSSSS............... 126 / 140 ( 90%)
[concat] ........SSSSSS
[concat]
[concat] Time: 2.16 seconds, Memory: 12.25Mb

Allthough it seems this branch has 2 failing Tests in ZendTest/View.

@weierophinney
Copy link
Member

@sarge-ch I've fixed the failing tests on develop earlier today, which means I can review this without issue.

return false;
}

$config = $serviceLocator->get('Config');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd do a check with has('Config') prior to this, and return false if that service is not available:

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

That way no exception is thrown if the config service is unavailable, but the method will still correctly report it cannot create the service.

@ghost
Copy link
Author

ghost commented Aug 21, 2013

@weierophinney Many thanks for your feedback and thoughts. I've implemented your suggestions and wrote some tests accordingly.

public function setPatterns($patterns)
{
if ($patterns instanceof \Traversable) {
$patterns = ArrayUtils::iteratorToArray($patterns);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since patterns are not a nested structure, you can just use iterator_to_array() here; I'll make that change on merge.

@weierophinney
Copy link
Member

@sarge-ch Looking good -- a bit more feedback to incorporate, and I think we may have a winner!

@ghost
Copy link
Author

ghost commented Aug 21, 2013

@weierophinney Thanks Matthew, added things :)

I could not really understand what you've meant with s/$this/self there ... however I'd be happy to change this as well as per your request. PHPStorm seems to only like $this a the @return - so I did not change it.

@weierophinney
Copy link
Member

I could not really understand what you've meant with s/$this/self there

@return self is the accepted standard, and works across IDEs and with phpDocumentor; @return $this is a synonym that is less supported. If PHPStorm is not accepting it, we should raise a ticket with them.

}

$config = $serviceLocator->get('Config');
$config = new Config($config[$key]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As noted in a previous comment -- don't cast this to a Config object; otherwise, there may be issues with existing code that works with configuration and expects an array (the current Config service is actually an array, not a Config instance!).

@ghost
Copy link
Author

ghost commented Aug 21, 2013

Rgr, will correct with the next commit.

Btw:
The fact that the Config service actually is an array is the issue why I originally came up with this. This service (allthough the default sm behaviour is shared) is imo not a shared service because retrieving the Config service from the sm returns me just another copy of the default config array rather than a reference to it (or does sm check if the service is an array and return a reference - I might check on this ...). So I was using such an abstract factory to at least dont copy my own array configs around a million times and rather work with the beauty named Zend\Config\Config :)

But I might miss the bigger picture here. If you still see a useful benefit in having this returning arrays I am happy with it.

@ghost
Copy link
Author

ghost commented Aug 21, 2013

@return self is the accepted standard, and works across IDEs and with phpDocumentor; @return $this is a synonym that is less supported. If PHPStorm is not accepting it, we should raise a ticket with them.

Thanks for the clarification. PHPStorm in fact supports @return self - my mistake.

@ghost ghost assigned weierophinney Oct 22, 2013
weierophinney added a commit that referenced this pull request Oct 22, 2013
abstract factory for configs reading keys from merged config
weierophinney added a commit that referenced this pull request Oct 22, 2013
@weierophinney weierophinney merged commit 3bdfebf into zendframework:develop Oct 22, 2013
@ghost ghost deleted the abstract-config-factory branch October 22, 2013 21:11
weierophinney added a commit to zendframework/zend-config that referenced this pull request May 15, 2015
…tract-config-factory

abstract factory for configs reading keys from merged config
weierophinney added a commit to zendframework/zend-config that referenced this pull request May 15, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants