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

Url factory does not work starting in 2.6 #71

Merged
merged 3 commits into from
Feb 22, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Service/AbstractPluginManagerFactory.php
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@ public function createService(ServiceLocatorInterface $serviceLocator)
/* @var $plugins AbstractPluginManager */
$plugins = new $pluginManagerClass;
$plugins->setServiceLocator($serviceLocator);
$configuration = $serviceLocator->get('Config');
$configuration = $serviceLocator->get('config');

if (isset($configuration['di']) && $serviceLocator->has('Di')) {
$plugins->addAbstractFactory($serviceLocator->get('DiAbstractServiceFactory'));
148 changes: 114 additions & 34 deletions src/Service/ViewHelperManagerFactory.php
Original file line number Diff line number Diff line change
@@ -9,17 +9,19 @@

namespace Zend\Mvc\Service;

use Interop\Container\ContainerInterface;
use Zend\Console\Console;
use Zend\Mvc\Exception;
use Zend\Mvc\Router\RouteMatch;
use Zend\ServiceManager\ConfigInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\View\Helper as ViewHelper;
use Zend\View\HelperPluginManager;
use Zend\View\Helper\HelperInterface as ViewHelperInterface;

class ViewHelperManagerFactory extends AbstractPluginManagerFactory
{
const PLUGIN_MANAGER_CLASS = 'Zend\View\HelperPluginManager';
const PLUGIN_MANAGER_CLASS = HelperPluginManager::class;

/**
* An array of helper configuration classes to ensure are on the helper_map stack.
@@ -43,29 +45,92 @@ public function createService(ServiceLocatorInterface $serviceLocator)
{
$plugins = parent::createService($serviceLocator);

// Configure default helpers from other components
$plugins = $this->configureHelpers($plugins);

// Override plugin factories
$plugins = $this->injectOverrideFactories($plugins, $serviceLocator);

return $plugins;
}

/**
* Configure helpers from other components.
*
* Loops through the list of default helper configuration classes, and uses
* each to configure the helper plugin manager.
*
* @param HelperPluginManager $plugins
* @return HelperPluginManager
*/
private function configureHelpers(HelperPluginManager $plugins)
{
foreach ($this->defaultHelperMapClasses as $configClass) {
if (is_string($configClass) && class_exists($configClass)) {
$config = new $configClass;

if (!$config instanceof ConfigInterface) {
throw new Exception\RuntimeException(sprintf(
'Invalid service manager configuration class provided; received "%s", expected class implementing %s',
$configClass,
'Zend\ServiceManager\ConfigInterface'
));
}

$config->configureServiceManager($plugins);
if (! is_string($configClass) || ! class_exists($configClass)) {
continue;
}

$config = new $configClass;

if (! $config instanceof ConfigInterface) {
throw new Exception\RuntimeException(sprintf(
'Invalid service manager configuration class provided; received "%s", expected class implementing %s',
$configClass,
'Zend\ServiceManager\ConfigInterface'
));
}

$config->configureServiceManager($plugins);
}

// Configure URL view helper with router
$plugins->setFactory('url', function () use ($serviceLocator) {
return $plugins;
}

/**
* Inject override factories into the plugin manager.
*
* @param HelperPluginManager $plugins
* @param ContainerInterface $services
* @return HelperPluginManager
*/
private function injectOverrideFactories(HelperPluginManager $plugins, ContainerInterface $services)
{
// Configure URL view helper
$urlFactory = $this->createUrlHelperFactory($services);
$plugins->setFactory(ViewHelper\Url::class, $urlFactory);
$plugins->setFactory('zendviewhelperurl', $urlFactory);

// Configure base path helper
$basePathFactory = $this->createBasePathHelperFactory($services);
$plugins->setFactory(ViewHelper\BasePath::class, $basePathFactory);
$plugins->setFactory('zendviewhelperbasepath', $basePathFactory);

// Configure doctype view helper
$doctypeFactory = $this->createDoctypeHelperFactory($services);
$plugins->setFactory(ViewHelper\doctype::class, $doctypeFactory);
$plugins->setFactory('zendviewhelperdoctype', $doctypeFactory);

return $plugins;
}

/**
* Create and return a factory for creating a URL helper.
*
* Retrieves the application and router from the servicemanager,
* and the route match from the MvcEvent composed by the application,
* using them to configure the helper.
*
* @param ContainerInterface $services
* @return callable
*/
private function createUrlHelperFactory(ContainerInterface $services)
{
return function () use ($services) {
$helper = new ViewHelper\Url;
$router = Console::isConsole() ? 'HttpRouter' : 'Router';
$helper->setRouter($serviceLocator->get($router));
$helper->setRouter($services->get($router));

$match = $serviceLocator->get('application')
$match = $services->get('application')
->getMvcEvent()
->getRouteMatch()
;
@@ -75,10 +140,21 @@ public function createService(ServiceLocatorInterface $serviceLocator)
}

return $helper;
});
};
}

$plugins->setFactory('basepath', function () use ($serviceLocator) {
$config = $serviceLocator->has('Config') ? $serviceLocator->get('Config') : [];
/**
* Create and return a factory for creating a BasePath helper.
*
* Uses configuration and request services to configure the helper.
*
* @param ContainerInterface $services
* @return callable
*/
private function createBasePathHelperFactory(ContainerInterface $services)
{
return function () use ($services) {
$config = $services->has('config') ? $services->get('config') : [];
$basePathHelper = new ViewHelper\BasePath;

if (Console::isConsole()
@@ -96,31 +172,35 @@ public function createService(ServiceLocatorInterface $serviceLocator)
return $basePathHelper;
}

$request = $serviceLocator->get('Request');
$request = $services->get('Request');

if (is_callable([$request, 'getBasePath'])) {
$basePathHelper->setBasePath($request->getBasePath());
}

return $basePathHelper;
});

/**
* Configure doctype view helper with doctype from configuration, if available.
*
* Other view helpers depend on this to decide which spec to generate their tags
* based on. This is why it must be set early instead of later in the layout phtml.
*/
$plugins->setFactory('doctype', function () use ($serviceLocator) {
$config = $serviceLocator->has('Config') ? $serviceLocator->get('Config') : [];
};
}

/**
* Create and return a Doctype helper factory.
*
* Other view helpers depend on this to decide which spec to generate their tags
* based on. This is why it must be set early instead of later in the layout phtml.
*
* @param ContainerInterface $services
* @return callable
*/
private function createDoctypeHelperFactory(ContainerInterface $services)
{
return function () use ($services) {
$config = $services->has('config') ? $services->get('config') : [];
$config = isset($config['view_manager']) ? $config['view_manager'] : [];
$doctypeHelper = new ViewHelper\Doctype;
if (isset($config['doctype']) && $config['doctype']) {
$doctypeHelper->setDoctype($config['doctype']);
}
return $doctypeHelper;
});

return $plugins;
};
}
}
2 changes: 1 addition & 1 deletion test/Service/HydratorManagerFactoryTest.php
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ public function setUp()
{
$this->factory = new HydratorManagerFactory();
$this->services = $this->prophesize(ServiceLocatorInterface::class);
$this->services->get('Config')->willReturn([]);
$this->services->get('config')->willReturn([]);
}

public function testFactoryReturnsZendHydratorManagerInstance()
146 changes: 138 additions & 8 deletions test/Service/ViewHelperManagerFactoryTest.php
Original file line number Diff line number Diff line change
@@ -11,8 +11,14 @@

use PHPUnit_Framework_TestCase as TestCase;
use Zend\Console\Request as ConsoleRequest;
use Zend\Http\PhpEnvironment\Request;
use Zend\Mvc\Application;
use Zend\Mvc\MvcEvent;
use Zend\Mvc\Router\RouteMatch;
use Zend\Mvc\Router\RouteStackInterface;
use Zend\Mvc\Service\ViewHelperManagerFactory;
use Zend\ServiceManager\ServiceManager;
use Zend\View\Helper;

class ViewHelperManagerFactoryTest extends TestCase
{
@@ -41,7 +47,7 @@ public function emptyConfiguration()
*/
public function testDoctypeFactoryDoesNotRaiseErrorOnMissingConfiguration($config)
{
$this->services->setService('Config', $config);
$this->services->setService('config', $config);
$manager = $this->factory->createService($this->services);
$this->assertInstanceof('Zend\View\HelperPluginManager', $manager);
$doctype = $manager->get('doctype');
@@ -50,7 +56,7 @@ public function testDoctypeFactoryDoesNotRaiseErrorOnMissingConfiguration($confi

public function testConsoleRequestsResultInSilentFailure()
{
$this->services->setService('Config', []);
$this->services->setService('config', []);
$this->services->setService('Request', new ConsoleRequest());

$manager = $this->factory->createService($this->services);
@@ -67,18 +73,142 @@ public function testConsoleRequestsResultInSilentFailure()
*/
public function testConsoleRequestWithBasePathConsole()
{
$this->services->setService('Config',
[
'view_manager' => [
'base_path_console' => 'http://test.com'
]
$this->services->setService('config', [
'view_manager' => [
'base_path_console' => 'http://test.com'
]
);
]);
$this->services->setService('Request', new ConsoleRequest());

$manager = $this->factory->createService($this->services);

$basePath = $manager->get('basepath');
$this->assertEquals('http://test.com', $basePath());
}

public function urlHelperNames()
{
return [
['url'],
['Url'],
[Helper\Url::class],
['zendviewhelperurl'],
];
}

/**
* @group 71
* @dataProvider urlHelperNames
*/
public function testUrlHelperFactoryCanBeInvokedViaShortNameOrFullClassName($name)
{
$routeMatch = $this->prophesize(RouteMatch::class)->reveal();
$mvcEvent = $this->prophesize(MvcEvent::class);
$mvcEvent->getRouteMatch()->willReturn($routeMatch);

$application = $this->prophesize(Application::class);
$application->getMvcEvent()->willReturn($mvcEvent->reveal());

$router = $this->prophesize(RouteStackInterface::class)->reveal();

$this->services->setService('HttpRouter', $router);
$this->services->setService('Router', $router);
$this->services->setService('application', $application->reveal());
$this->services->setService('config', []);

$manager = $this->factory->createService($this->services);
$helper = $manager->get($name);

$this->assertAttributeSame($routeMatch, 'routeMatch', $helper, 'Route match was not injected');
$this->assertAttributeSame($router, 'router', $helper, 'Router was not injected');
}

public function basePathConfiguration()
{
$names = ['basepath', 'basePath', 'BasePath', Helper\BasePath::class, 'zendviewhelperbasepath'];

$configurations = [
'console' => [[
'config' => [
'view_manager' => [
'base_path_console' => '/foo/bar',
],
],
], '/foo/bar'],

'hard-coded' => [[
'config' => [
'view_manager' => [
'base_path' => '/foo/baz',
],
],
], '/foo/baz'],

'request-base' => [[
'config' => [], // fails creating plugin manager without this
'request' => function () {
$request = $this->prophesize(Request::class);
$request->getBasePath()->willReturn('/foo/bat');
return $request->reveal();
},
], '/foo/bat'],
];

foreach ($names as $name) {
foreach ($configurations as $testcase => $arguments) {
array_unshift($arguments, $name);
$testcase .= '-' . $name;
yield $testcase => $arguments;
}
}
}

/**
* @group 71
* @dataProvider basePathConfiguration
*/
public function testBasePathHelperFactoryCanBeInvokedViaShortNameOrFullClassName($name, array $services, $expected)
{
foreach ($services as $key => $value) {
if (is_callable($value)) {
$this->services->setFactory($key, $value);
continue;
}

$this->services->setService($key, $value);
}

$plugins = $this->factory->createService($this->services);
$helper = $plugins->get($name);
$this->assertInstanceof(Helper\BasePath::class, $helper);
$this->assertEquals($expected, $helper());
}

public function doctypeHelperNames()
{
return [
['doctype'],
['Doctype'],
[Helper\Doctype::class],
['zendviewhelperdoctype'],
];
}

/**
* @group 71
* @dataProvider doctypeHelperNames
*/
public function testDoctypeHelperFactoryCanBeInvokedViaShortNameOrFullClassName($name)
{
$this->services->setService('config', [
'view_manager' => [
'doctype' => Helper\Doctype::HTML5,
],
]);

$plugins = $this->factory->createService($this->services);
$helper = $plugins->get($name);
$this->assertInstanceof(Helper\Doctype::class, $helper);
$this->assertEquals('<!DOCTYPE html>', (string) $helper);
}
}