Skip to content

Commit ab66de0

Browse files
authored
Merge pull request #261 from gsteel/filter-chain-and-build-vs-get
Fix filters registered under `services` cannot be found (no factory)
2 parents 6f52a22 + f04c2a9 commit ab66de0

File tree

6 files changed

+119
-39
lines changed

6 files changed

+119
-39
lines changed

composer.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,13 @@
4646
"ext-bz2": "*",
4747
"ext-zlib": "*",
4848
"ext-zip": "*",
49-
"laminas/laminas-coding-standard": "^3.0.1",
49+
"laminas/laminas-coding-standard": "^3.1.0",
5050
"laminas/laminas-diactoros": "^3.6",
51-
"pear/archive_tar": "^1.5.0",
51+
"pear/archive_tar": "^1.6.0",
5252
"pear/pear": "^1.10.16",
53-
"phpunit/phpunit": "^10.5.46",
53+
"phpunit/phpunit": "^10.5.51",
5454
"psalm/plugin-phpunit": "^0.19.5",
55-
"vimeo/psalm": "^6.10.3"
55+
"vimeo/psalm": "^6.13.1"
5656
},
5757
"suggest": {
5858
"laminas/laminas-i18n": "Laminas\\I18n component for filters depending on i18n functionality",

composer.lock

Lines changed: 41 additions & 28 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/FilterChain.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,13 @@ public function attach(FilterInterface|callable $callback, int $priority = self:
8484

8585
public function attachByName(string $name, array $options = [], int $priority = self::DEFAULT_PRIORITY): self
8686
{
87-
/** @psalm-var FilterInterface $filter */
88-
$filter = $this->plugins->build($name, $options);
87+
if ($options === []) {
88+
/** @psalm-var FilterInterface $filter */
89+
$filter = $this->plugins->get($name);
90+
} else {
91+
/** @psalm-var FilterInterface $filter */
92+
$filter = $this->plugins->build($name, $options);
93+
}
8994

9095
return $this->attach($filter, $priority);
9196
}

src/ImmutableFilterChain.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,14 @@ public function attach(FilterInterface|callable $callback, int $priority = self:
9696

9797
public function attachByName(string $name, array $options = [], int $priority = self::DEFAULT_PRIORITY): self
9898
{
99-
/** @psalm-var FilterInterface $filter */
100-
$filter = $this->pluginManager->build($name, $options);
99+
if ($options === []) {
100+
/** @psalm-var FilterInterface $filter */
101+
$filter = $this->pluginManager->get($name);
102+
} else {
103+
/** @psalm-var FilterInterface $filter */
104+
$filter = $this->pluginManager->build($name, $options);
105+
}
106+
101107
$filters = clone $this->filters;
102108
$filters->insert($filter, $priority);
103109

test/FilterChainTest.php

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,21 @@
2323

2424
/**
2525
* @psalm-import-type FilterChainConfiguration from FilterChain
26+
* @psalm-import-type ServiceManagerConfiguration from ServiceManager
2627
*/
2728
final class FilterChainTest extends TestCase
2829
{
2930
private FilterPluginManager $plugins;
3031

3132
protected function setUp(): void
3233
{
33-
$this->plugins = new FilterPluginManager(new ServiceManager());
34+
$this->plugins = self::pluginManagerWithConfig();
35+
}
36+
37+
/** @param ServiceManagerConfiguration $config */
38+
private static function pluginManagerWithConfig(array $config = []): FilterPluginManager
39+
{
40+
return new FilterPluginManager(new ServiceManager(), $config);
3441
}
3542

3643
public function testEmptyFilterChainReturnsOriginalValue(): void
@@ -238,4 +245,24 @@ public function testFilterChainSpecAcceptsFilterInstances(): void
238245
$filters = iterator_to_array($chain);
239246
self::assertSame([0 => $filter], $filters);
240247
}
248+
249+
public function testServiceManagerServicesCanBeUsedInChains(): void
250+
{
251+
$closure = static fn (mixed $value): mixed => $value;
252+
$plugins = self::pluginManagerWithConfig([
253+
'services' => [
254+
'custom' => $closure,
255+
],
256+
]);
257+
258+
$chain = iterator_to_array(new FilterChain($plugins, [
259+
'filters' => [
260+
['name' => StringTrim::class],
261+
['name' => 'custom'],
262+
],
263+
]), false);
264+
265+
self::assertCount(2, $chain);
266+
self::assertSame($closure, $chain[1]);
267+
}
241268
}

test/ImmutableFilterChainTest.php

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,32 @@
88
use Laminas\Filter\ImmutableFilterChain;
99
use Laminas\Filter\StringPrefix;
1010
use Laminas\Filter\StringToLower;
11+
use Laminas\Filter\StringTrim;
1112
use Laminas\ServiceManager\ServiceManager;
1213
use PHPUnit\Framework\TestCase;
1314

1415
use function implode;
1516
use function str_replace;
1617
use function str_split;
18+
use function strrev;
1719

18-
/** @psalm-import-type InstanceType from ImmutableFilterChain */
20+
/**
21+
* @psalm-import-type InstanceType from ImmutableFilterChain
22+
* @psalm-import-type ServiceManagerConfiguration from ServiceManager
23+
*/
1924
final class ImmutableFilterChainTest extends TestCase
2025
{
2126
private FilterPluginManager $plugins;
2227

2328
protected function setUp(): void
2429
{
25-
$this->plugins = new FilterPluginManager(new ServiceManager());
30+
$this->plugins = self::pluginManagerWithConfig();
31+
}
32+
33+
/** @param ServiceManagerConfiguration $config */
34+
private static function pluginManagerWithConfig(array $config = []): FilterPluginManager
35+
{
36+
return new FilterPluginManager(new ServiceManager(), $config);
2637
}
2738

2839
public function testThatFiltersWillBeRetrievedFromThePluginManager(): void
@@ -145,4 +156,22 @@ public function testSpecificationWithFilterInstancesInCallbacks(): void
145156

146157
self::assertSame('Foofoo', $chain->filter('Foo'));
147158
}
159+
160+
public function testServiceManagerServicesCanBeUsedInChains(): void
161+
{
162+
$plugins = self::pluginManagerWithConfig([
163+
'services' => [
164+
'custom' => static fn (string $value): string => strrev($value),
165+
],
166+
]);
167+
168+
$chain = ImmutableFilterChain::fromArray([
169+
'filters' => [
170+
['name' => StringTrim::class],
171+
['name' => 'custom'],
172+
],
173+
], $plugins);
174+
175+
self::assertSame('oof', $chain->filter(' foo '));
176+
}
148177
}

0 commit comments

Comments
 (0)