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

Commit

Permalink
Merge pull request #6963 from Ocramius/feature/#6441-prefix-path-reso…
Browse files Browse the repository at this point in the history
…lver

Feature/#6441 prefix path resolver
  • Loading branch information
Ocramius committed Dec 16, 2014
2 parents 224d3ec + d25bc94 commit 45151ee
Show file tree
Hide file tree
Showing 11 changed files with 297 additions and 44 deletions.
1 change: 1 addition & 0 deletions library/Zend/Mvc/Service/ServiceListenerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class ServiceListenerFactory implements FactoryInterface
'ViewResolver' => 'Zend\Mvc\Service\ViewResolverFactory',
'ViewTemplateMapResolver' => 'Zend\Mvc\Service\ViewTemplateMapResolverFactory',
'ViewTemplatePathStack' => 'Zend\Mvc\Service\ViewTemplatePathStackFactory',
'ViewPrefixPathStackResolver' => 'Zend\Mvc\Service\ViewPrefixPathStackResolverFactory',
),
'aliases' => array(
'Configuration' => 'Config',
Expand Down
38 changes: 38 additions & 0 deletions library/Zend/Mvc/Service/ViewPrefixPathStackResolverFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace Zend\Mvc\Service;

use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\View\Resolver\PrefixPathStackResolver;

class ViewPrefixPathStackResolverFactory implements FactoryInterface
{
/**
* Create the template prefix view resolver
*
* Creates a Zend\View\Resolver\PrefixPathStackResolver and populates it with the
* ['view_manager']['prefix_template_path_stack']
*
* @param ServiceLocatorInterface $serviceLocator
* @return PrefixPathStackResolver
*/
public function createService(ServiceLocatorInterface $serviceLocator)
{
$config = $serviceLocator->get('Config');
$prefixes = array();

if (isset($config['view_manager']['prefix_template_path_stack'])) {
$prefixes = $config['view_manager']['prefix_template_path_stack'];
}

return new PrefixPathStackResolver($prefixes);
}
}
25 changes: 17 additions & 8 deletions library/Zend/Mvc/Service/ViewResolverFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,28 @@ class ViewResolverFactory implements FactoryInterface
* Creates a Zend\View\Resolver\AggregateResolver and attaches the template
* map resolver and path stack resolver
*
* @param ServiceLocatorInterface $serviceLocator
* @param ServiceLocatorInterface $serviceLocator
* @return ViewResolver\AggregateResolver
*/
public function createService(ServiceLocatorInterface $serviceLocator)
{
$resolver = new ViewResolver\AggregateResolver();
$mapResolver = $serviceLocator->get('ViewTemplateMapResolver');
$pathResolver = $serviceLocator->get('ViewTemplatePathStack');
$resolver->attach($mapResolver)
->attach($pathResolver)
->attach(new ViewResolver\RelativeFallbackResolver($mapResolver))
->attach(new ViewResolver\RelativeFallbackResolver($pathResolver))
;

/* @var $mapResolver \Zend\View\Resolver\ResolverInterface */
$mapResolver = $serviceLocator->get('ViewTemplateMapResolver');
/* @var $pathResolver \Zend\View\Resolver\ResolverInterface */
$pathResolver = $serviceLocator->get('ViewTemplatePathStack');
/* @var $prefixPathStackResolver \Zend\View\Resolver\ResolverInterface */
$prefixPathStackResolver = $serviceLocator->get('ViewPrefixPathStackResolver');

$resolver
->attach($mapResolver)
->attach($pathResolver)
->attach($prefixPathStackResolver)
->attach(new ViewResolver\RelativeFallbackResolver($mapResolver))
->attach(new ViewResolver\RelativeFallbackResolver($pathResolver))
->attach(new ViewResolver\RelativeFallbackResolver($prefixPathStackResolver));

return $resolver;
}
}
59 changes: 59 additions & 0 deletions library/Zend/View/Resolver/PrefixPathStackResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace Zend\View\Resolver;

use Zend\View\Exception;
use Zend\View\Renderer\RendererInterface as Renderer;

final class PrefixPathStackResolver implements ResolverInterface
{
/**
* Array containing prefix as key and "template path stack array" as value
*
* @var string[]|string[][]|ResolverInterface[]
*/
private $prefixes = array();

/**
* Constructor
*
* @param string[]|string[][]|ResolverInterface[] $prefixes Set of path prefixes to be matched (array keys), with
* either a path or an array of paths to use for matching
* as in the {@see \Zend\View\Resolver\TemplatePathStack},
* or a {@see \Zend\View\Resolver\ResolverInterface}
* to use for view path starting with that prefix
*/
public function __construct(array $prefixes = array())
{
$this->prefixes = $prefixes;
}

/**
* {@inheritDoc}
*/
public function resolve($name, Renderer $renderer = null)
{
foreach ($this->prefixes as $prefix => & $resolver) {
if (strpos($name, $prefix) !== 0) {
continue;
}

if (! $resolver instanceof ResolverInterface) {
$resolver = new TemplatePathStack(array('script_paths' => (array) $resolver));
}

if ($result = $resolver->resolve(substr($name, strlen($prefix)), $renderer)) {
return $result;
}
}

return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace ZendTest\Mvc\Service;

use Zend\Mvc\Service\ViewPrefixPathStackResolverFactory;

class ViewPrefixPathStackResolverFactoryTest extends \PHPUnit_Framework_TestCase
{
public function testCreateService()
{
/* @var $serviceLocator \Zend\ServiceManager\ServiceLocatorInterface|\PHPUnit_Framework_MockObject_MockObject */
$serviceLocator = $this->getMock('Zend\ServiceManager\ServiceLocatorInterface');

$serviceLocator->expects($this->once())
->method('get')
->with('Config')
->will($this->returnValue(array(
'view_manager' => array(
'prefix_template_path_stack' => array(
'album/' => array(),
),
),
)));

$factory = new ViewPrefixPathStackResolverFactory();
$resolver = $factory->createService($serviceLocator);

$this->assertInstanceOf('Zend\View\Resolver\PrefixPathStackResolver', $resolver);
}
}
84 changes: 84 additions & 0 deletions tests/ZendTest/View/Resolver/PrefixPathStackResolverTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace ZendTest\View\Resolver;

use Zend\View\Resolver\PrefixPathStackResolver;

/**
* Tests for {@see \Zend\View\Resolver\PrefixPathStackResolver}
*
* @covers \Zend\View\Resolver\PrefixPathStackResolver
*/
class PrefixPathStackResolverTest extends \PHPUnit_Framework_TestCase
{
/**
* @var string
*/
private $basePath;

/**
* {@inheritDoc}
*/
protected function setUp()
{
$this->basePath = realpath(__DIR__ . '/../_templates/prefix-path-stack-resolver');
}

public function testResolveWithoutPathPrefixes()
{
$resolver = new PrefixPathStackResolver();

$this->assertNull($resolver->resolve(__DIR__));
$this->assertNull($resolver->resolve(__FILE__));
$this->assertNull($resolver->resolve('path/to/foo'));
$this->assertNull($resolver->resolve('path/to/bar'));
}

public function testResolve()
{
$resolver = new PrefixPathStackResolver(array(
'base1' => $this->basePath,
'base2' => $this->basePath . '/baz'
));

$this->assertEmpty($resolver->resolve('base1/foo'));
$this->assertSame(realpath($this->basePath . '/bar.phtml'), $resolver->resolve('base1/bar'));
$this->assertEmpty($resolver->resolve('base2/tab'));
$this->assertSame(realpath($this->basePath . '/baz/taz.phtml'), $resolver->resolve('base2/taz'));
}

public function testResolveWithCongruentPrefix()
{
$resolver = new PrefixPathStackResolver(array(
'foo' => $this->basePath,
'foobar' => $this->basePath . '/baz'
));

$this->assertSame(realpath($this->basePath . '/bar.phtml'), $resolver->resolve('foo/bar'));
$this->assertSame(realpath($this->basePath . '/baz/taz.phtml'), $resolver->resolve('foobar/taz'));
}

public function testSetCustomPathStackResolver()
{
$mockResolver = $this->getMock('Zend\View\Resolver\ResolverInterface');

$resolver = new PrefixPathStackResolver(array(
'foo' => $mockResolver,
));

$mockResolver->expects($this->at(0))->method('resolve')->with('/bar')->will($this->returnValue('1111'));
$mockResolver->expects($this->at(1))->method('resolve')->with('/baz')->will($this->returnValue('2222'));
$mockResolver->expects($this->at(2))->method('resolve')->with('/tab')->will($this->returnValue(false));

$this->assertSame('1111', $resolver->resolve('foo/bar'));
$this->assertSame('2222', $resolver->resolve('foo/baz'));
$this->assertNull($resolver->resolve('foo/tab'));
}
}
Loading

0 comments on commit 45151ee

Please sign in to comment.