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

Commit e31a31e

Browse files
committed
Use a factory to create the SendResponseListener
Reported in: - zendframework/zend-mvc-console#10 - zendframework/zend-mvc-console#11 - zendframework/zend-mvc-console#12 The `SendResponseListener` was lazy-instantiating an event manager on first request to `getEventManager()`. However, because initializers run after delegators, this meant that the EM instance composed did not have a shared EM instance, which triggered the initializer to re-inject, losing any listeners injected by delegators. This patch introduces a factory for the `SendResponseListener`. The factory creates the instance, and then injects it with an EM instance pulled from the container; since these are guaranteed to have a shared EM instance, the initializer will skip injection, keeping any listeners injected by delegators.
1 parent 75d3672 commit e31a31e

File tree

3 files changed

+81
-1
lines changed

3 files changed

+81
-1
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
/**
3+
* @link http://github.com/zendframework/zend-mvc for the canonical source repository
4+
* @copyright Copyright (c) 2016 Zend Technologies USA Inc. (http://www.zend.com)
5+
* @license http://framework.zend.com/license/new-bsd New BSD License
6+
*/
7+
8+
namespace Zend\Mvc\Service;
9+
10+
use Interop\Container\ContainerInterface;
11+
use Zend\Mvc\SendResponseListener;
12+
13+
class SendResponseListenerFactory
14+
{
15+
/**
16+
* @param ContainerInterface $container
17+
* @return SendResponseListener
18+
*/
19+
public function __invoke(ContainerInterface $container)
20+
{
21+
$listener = new SendResponseListener();
22+
$listener->setEventManager($container->get('EventManager'));
23+
return $listener;
24+
}
25+
}

src/Service/ServiceListenerFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ class ServiceListenerFactory implements FactoryInterface
8686
'ViewPrefixPathStackResolver' => 'Zend\Mvc\Service\ViewPrefixPathStackResolverFactory',
8787
'Zend\Mvc\MiddlewareListener' => InvokableFactory::class,
8888
'Zend\Mvc\RouteListener' => InvokableFactory::class,
89-
'Zend\Mvc\SendResponseListener' => InvokableFactory::class,
89+
'Zend\Mvc\SendResponseListener' => SendResponseListenerFactory::class,
9090
'Zend\View\Renderer\FeedRenderer' => InvokableFactory::class,
9191
'Zend\View\Renderer\JsonRenderer' => InvokableFactory::class,
9292
'Zend\View\Renderer\PhpRenderer' => ViewPhpRendererFactory::class,
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
/**
3+
* @link http://github.com/zendframework/zend-mvc for the canonical source repository
4+
* @copyright Copyright (c) 2016 Zend Technologies USA Inc. (http://www.zend.com)
5+
* @license http://framework.zend.com/license/new-bsd New BSD License
6+
*/
7+
8+
namespace ZendTest\Mvc\Service;
9+
10+
use Interop\Container\ContainerInterface;
11+
use PHPUnit_Framework_TestCase as TestCase;
12+
use Prophecy\Argument;
13+
use Zend\EventManager\EventManagerInterface;
14+
use Zend\EventManager\SharedEventManagerInterface;
15+
use Zend\Mvc\ResponseSender\HttpResponseSender;
16+
use Zend\Mvc\ResponseSender\PhpEnvironmentResponseSender;
17+
use Zend\Mvc\ResponseSender\SendResponseEvent;
18+
use Zend\Mvc\ResponseSender\SimpleStreamResponseSender;
19+
use Zend\Mvc\SendResponseListener;
20+
use Zend\Mvc\Service\SendResponseListenerFactory;
21+
22+
class SendResponseFactoryTest extends TestCase
23+
{
24+
public function testFactoryReturnsListenerWithEventManagerFromContainer()
25+
{
26+
$sharedEvents = $this->prophesize(SharedEventManagerInterface::class);
27+
$events = $this->prophesize(EventManagerInterface::class);
28+
$events->getSharedManager()->will([$sharedEvents, 'reveal']);
29+
30+
$events->setIdentifiers([SendResponseListener::class, SendResponseListener::class])->shouldBeCalled();
31+
$events->attach(
32+
SendResponseEvent::EVENT_SEND_RESPONSE,
33+
Argument::type(PhpEnvironmentResponseSender::class),
34+
-1000
35+
)->shouldBeCalled();
36+
$events->attach(
37+
SendResponseEvent::EVENT_SEND_RESPONSE,
38+
Argument::type(SimpleStreamResponseSender::class),
39+
-3000
40+
)->shouldBeCalled();
41+
$events->attach(
42+
SendResponseEvent::EVENT_SEND_RESPONSE,
43+
Argument::type(HttpResponseSender::class),
44+
-4000
45+
)->shouldBeCalled();
46+
47+
$container = $this->prophesize(ContainerInterface::class);
48+
$container->get('EventManager')->will([$events, 'reveal']);
49+
50+
$factory = new SendResponseListenerFactory();
51+
$listener = $factory($container->reveal());
52+
$this->assertInstanceOf(SendResponseListener::class, $listener);
53+
$this->assertSame($events->reveal(), $listener->getEventManager());
54+
}
55+
}

0 commit comments

Comments
 (0)