Skip to content
This repository was archived by the owner on Feb 6, 2020. It is now read-only.

Commit ba7069c

Browse files
committed
Merge branch 'hotfix/159-creation-options-must-be-null' into release-2.7
Close #159
2 parents 249d9d5 + f217651 commit ba7069c

File tree

4 files changed

+51
-10
lines changed

4 files changed

+51
-10
lines changed

CHANGELOG.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
All notable changes to this project will be documented in this file, in reverse chronological order by release.
44

5-
## 2.7.10 - TBD
5+
## 2.7.10 - 2017-12-05
66

77
### Added
88

@@ -22,7 +22,10 @@ All notable changes to this project will be documented in this file, in reverse
2222

2323
### Fixed
2424

25-
- Nothing.
25+
- [#210](https://github.com/zendframework/zend-servicemanager/pull/210) fixes a
26+
regression whereby factories accepting creation options were receiving an
27+
empty array versus a `null` value when no options were present for a
28+
particular invocation; they now correctly receive a `null` value.
2629

2730
## 2.7.9 - 2017-11-27
2831

src/AbstractPluginManager.php

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
use Interop\Container\ContainerInterface;
1313
use Exception as BaseException;
14+
use ReflectionMethod;
1415

1516
/**
1617
* ServiceManager implementation for managing plugins
@@ -356,13 +357,38 @@ protected function createServiceViaCallback($callable, $cName, $rName)
356357
$factory = reset($callable);
357358
}
358359

359-
// duck-type MutableCreationOptionsInterface for forward compatibility
360-
if (isset($factory)
360+
if ($factory instanceof Factory\InvokableFactory) {
361+
// InvokableFactory::setCreationOptions has a different signature than
362+
// MutableCreationOptionsInterface; allows null value.
363+
$options = is_array($this->creationOptions) && ! empty($this->creationOptions)
364+
? $this->creationOptions
365+
: null;
366+
$factory->setCreationOptions($options);
367+
} elseif ($factory instanceof MutableCreationOptionsInterface) {
368+
// MutableCreationOptionsInterface expects an array, always; pass an
369+
// empty array for lack of creation options.
370+
$options = is_array($this->creationOptions) && ! empty($this->creationOptions)
371+
? $this->creationOptions
372+
: [];
373+
$factory->setCreationOptions($options);
374+
} elseif (isset($factory)
361375
&& method_exists($factory, 'setCreationOptions')
362376
) {
363-
$factory->setCreationOptions(is_array($this->creationOptions) ? $this->creationOptions : []);
364-
} elseif ($factory instanceof Factory\InvokableFactory) {
365-
$factory->setCreationOptions(null);
377+
// duck-type MutableCreationOptionsInterface for forward compatibility
378+
379+
$options = $this->creationOptions;
380+
381+
// If we have empty creation options, we have to find out if a default
382+
// value is present and use that; otherwise, we should use an empty
383+
// array, as that's the standard type-hint.
384+
if (! is_array($options) || empty($options)) {
385+
$r = new ReflectionMethod($factory, 'setCreationOptions');
386+
$params = $r->getParameters();
387+
$optionsParam = array_shift($params);
388+
$options = $optionsParam->isDefaultValueAvailable() ? $optionsParam->getDefaultValue() : [];
389+
}
390+
391+
$factory->setCreationOptions($options);
366392
}
367393

368394
return parent::createServiceViaCallback($callable, $cName, $rName);

test/AbstractPluginManagerTest.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,8 @@ public function testRetrievingServicesViaFactoryThatUsesCreationOptionsShouldRet
209209

210210
/**
211211
* @group 205
212+
* @codingStandardsIgnoreStart
212213
*/
213-
// @codingStandardsIgnoreStart
214214
public function testRetrievingServicesViaFactoryThatUsesCreationOptionsShouldReturnNewInstanceEveryTimeOptionsAreProvided()
215215
{
216216
// @codingStandardsIgnoreEnd
@@ -451,4 +451,16 @@ public function testInvokableFactoryHasMutableOptions()
451451
$object = $pluginManager->get('foo', $options);
452452
$this->assertEquals($options, $object->getOptions());
453453
}
454+
455+
public function testIfCreationOptionsAreEmptySetThemThemToNullWhenCreatingAService()
456+
{
457+
// @codingStandardsIgnoreEnd
458+
/** @var $pluginManager AbstractPluginManager */
459+
$pluginManager = $this->getMockForAbstractClass('Zend\ServiceManager\AbstractPluginManager');
460+
$pluginManager->setFactory(Baz::class, FactoryUsingCreationOptions::class);
461+
$pluginManager->setShared(Baz::class, false);
462+
$plugin = $pluginManager->get(Baz::class);
463+
464+
$this->assertNull($plugin->options);
465+
}
454466
}

test/TestAsset/FactoryUsingCreationOptions.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ public function createService(ServiceLocatorInterface $serviceLocator)
2323
}
2424

2525
/**
26-
* @param array $creationOptions
26+
* @param array|null $creationOptions
2727
*
2828
* @return void
2929
*/
30-
public function setCreationOptions(array $creationOptions)
30+
public function setCreationOptions(array $creationOptions = null)
3131
{
3232
$this->creationOptions = $creationOptions;
3333
}

0 commit comments

Comments
 (0)