8000 [Cache] Fix accepting named closures as early-expiration callbacks · symfony/symfony@a2b6fed · GitHub
[go: up one dir, main page]

Skip to content

Commit a2b6fed

Browse files
[Cache] Fix accepting named closures as early-expiration callbacks
1 parent 711c969 commit a2b6fed

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

src/Symfony/Component/Cache/Messenger/EarlyExpirationMessage.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ public static function create(ReverseContainer $reverseContainer, callable $call
3535

3636
$pool = $reverseContainer->getId($pool);
3737

38+
if ($callback instanceof \Closure && !str_contains(($r = new \ReflectionFunction($callback))->name, '{closure')) {
39+
$callback = [$r->getClosureThis() ?? $r->getClosureCalledClass()?->name, $r->name];
40+
$callback[0] ?: $callback = $r->name;
41+
}
42+
3843
if (\is_object($callback)) {
3944
if (null === $id = $reverseContainer->getId($callback)) {
4045
return null;

src/Symfony/Component/Cache/Tests/Messenger/EarlyExpirationMessageTest.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,58 @@ public function __invoke(CacheItem $item)
5757
$this->assertSame('@computation_service', $msg->getCallback());
5858
$this->assertSame($computationService, $msg->findCallback($reverseContainer));
5959
}
60+
61+
public function testCreateWithNonAnonymousClosureBoundToInstance()
62+
{
63+
$pool = new ArrayAdapter();
64+
$item = $pool->getItem('foo');
65+
$item->set(234);
66+
67+
$computationService = new class {
68+
public function compute(CacheItem $item)
69+
{
70+
return 123;
71+
}
72+
73+
public static function staticCompute(CacheItem $item)
74+
{
75+
return 123;
76+
}
77+
};
78+
79+
$container = new Container();
80+
$container->set('computation_service', $computationService);
81+
$container->set('cache_pool', $pool);
82+
83+
$reverseContainer = new ReverseContainer($container, new ServiceLocator([]));
84+
85+
$closure = $computationService->compute(...);
86+
$msg = EarlyExpirationMessage::create($reverseContainer, $closure, $item, $pool);
87+
$this->assertSame(['@computation_service', 'compute'], $msg->getCallback());
88+
89+
$closure = $computationService::staticCompute(...);
90+
$msg = EarlyExpirationMessage::create($reverseContainer, $closure, $item, $pool);
91+
$this->assertSame([$computationService::class, 'staticCompute'], $msg->getCallback());
92+
93+
$msg = EarlyExpirationMessage::create($reverseContainer, var_dump(...), $item, $pool);
94+
$this->assertSame('var_dump', $msg->getCallback());
95+
96+
$this->assertSame('cache_pool', $msg->getPool());
97+
}
98+
99+
public function testCreateWithAnonymousClosure()
100+
{
101+
$pool = new ArrayAdapter();
102+
$item = $pool->getItem('foo');
103+
$item->set(234);
104+
105+
$container = new Container();
106+
$container->set('cache_pool', $pool);
107+
108+
$reverseContainer = new ReverseContainer($container, new ServiceLocator([]));
109+
110+
$msg = EarlyExpirationMessage::create($reverseContainer, static fn () => 123, $item, $pool);
111+
112+
$this->assertNull($msg);
113+
}
60114
}

0 commit comments

Comments
 (0)
0