Skip to content

Commit

Permalink
Merge pull request zendframework#2221 from weierophinney/hotfix/url-p…
Browse files Browse the repository at this point in the history
…lugin-sync

Synced url plugin and helper usage
  • Loading branch information
EvanDotPro committed Aug 22, 2012
2 parents 44734c2 + 4a1d95b commit f5edeb0
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 7 deletions.
44 changes: 38 additions & 6 deletions library/Zend/Mvc/Controller/Plugin/Url.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Zend\EventManager\EventInterface;
use Zend\Mvc\Exception;
use Zend\Mvc\InjectApplicationEventInterface;
use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
use Zend\Mvc\Router\RouteStackInterface;

Expand All @@ -28,29 +29,60 @@ class Url extends AbstractPlugin
*
* @param string $route RouteInterface name
* @param array $params Parameters to use in url generation, if any
* @param array $options RouteInterface-specific options to use in url generation, if any
* @param array|bool $options RouteInterface-specific options to use in url generation, if any. If boolean, and no fourth argument, used as $reuseMatchedParams
* @param boolean $reuseMatchedParams Whether to reuse matched parameters
* @return string
* @throws Exception\DomainException if composed controller does not implement InjectApplicationEventInterface, or
* router cannot be found in controller event
*/
public function fromRoute($route, array $params = array(), array $options = array())
public function fromRoute($route = null, array $params = array(), $options = array(), $reuseMatchedParams = false)
{
$controller = $this->getController();
if (!$controller instanceof InjectApplicationEventInterface) {
throw new Exception\DomainException('Url plugin requires a controller that implements InjectApplicationEventInterface');
}

$event = $controller->getEvent();
$router = null;
$event = $controller->getEvent();
$router = null;
$matches =null;
if ($event instanceof MvcEvent) {
$router = $event->getRouter();
$router = $event->getRouter();
$matches = $event->getRouteMatch();
} elseif ($event instanceof EventInterface) {
$router = $event->getParam('router', false);
$router = $event->getParam('router', false);
$matches = $event->getParam('route-match', false);
}
if (!$router instanceof RouteStackInterface) {
throw new Exception\DomainException('Url plugin requires that controller event compose a router; none found');
}

if (3 == func_num_args() && is_bool($options)) {
$reuseMatchedParams = $options;
$options = array();
}

if ($route === null) {
if (!$matches) {
throw new Exception\RuntimeException('No RouteMatch instance present');
}

$route = $matches->getMatchedRouteName();

if ($route === null) {
throw new Exception\RuntimeException('RouteMatch does not contain a matched route name');
}
}

if ($reuseMatchedParams && $matches) {
$routeMatchParams = $matches->getParams();

if (isset($routeMatchParams[ModuleRouteListener::ORIGINAL_CONTROLLER])) {
$routeMatchParams['controller'] = $routeMatchParams[ModuleRouteListener::ORIGINAL_CONTROLLER];
}

$params = array_merge($routeMatchParams, $params);
}

$options['name'] = $route;
return $router->assemble($params, $options);
}
Expand Down
7 changes: 6 additions & 1 deletion library/Zend/View/Helper/Url.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,17 @@ public function setRouteMatch(RouteMatch $routeMatch)
* @throws Exception\RuntimeException If no RouteMatch was provided
* @throws Exception\RuntimeException If RouteMatch didn't contain a matched route name
*/
public function __invoke($name = null, array $params = array(), array $options = array(), $reuseMatchedParams = false)
public function __invoke($name = null, array $params = array(), $options = array(), $reuseMatchedParams = false)
{
if (null === $this->router) {
throw new Exception\RuntimeException('No RouteStackInterface instance provided');
}

if (3 == func_num_args() && is_bool($options)) {
$reuseMatchedParams = $options;
$options = array();
}

if ($name === null) {
if ($this->routeMatch === null) {
throw new Exception\RuntimeException('No RouteMatch instance provided');
Expand Down
60 changes: 60 additions & 0 deletions tests/ZendTest/Mvc/Controller/Plugin/UrlTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
use Zend\Mvc\Controller\Plugin\Url as UrlPlugin;
use Zend\Mvc\MvcEvent;
use Zend\Mvc\Router\Http\Literal as LiteralRoute;
use Zend\Mvc\Router\Http\Segment as SegmentRoute;
use Zend\Mvc\Router\RouteMatch;
use Zend\Mvc\Router\SimpleRouteStack;
use ZendTest\Mvc\Controller\TestAsset\SampleController;

Expand All @@ -28,6 +30,7 @@ public function setUp()
'controller' => 'ZendTest\Mvc\Controller\TestAsset\SampleController',
),
)));
$this->router = $router;

$event = new MvcEvent();
$event->setRouter($router);
Expand Down Expand Up @@ -68,4 +71,61 @@ public function testPluginWithoutRouterInEventRaisesDomainException()
$this->setExpectedException('Zend\Mvc\Exception\DomainException', 'event compose a router');
$plugin->fromRoute('home');
}

public function testPluginWithoutRouteMatchesInEventRaisesExceptionWhenNoRouteProvided()
{
$this->setExpectedException('Zend\Mvc\Exception\RuntimeException', 'RouteMatch');
$url = $this->plugin->fromRoute();
}

public function testPluginWithRouteMatchesReturningNoMatchedRouteNameRaisesExceptionWhenNoRouteProvided()
{
$event = $this->controller->getEvent();
$event->setRouteMatch(new RouteMatch(array()));
$this->setExpectedException('Zend\Mvc\Exception\RuntimeException', 'matched');
$url = $this->plugin->fromRoute();
}

public function testPassingNoArgumentsWithValidRouteMatchGeneratesUrl()
{
$routeMatch = new RouteMatch(array());
$routeMatch->setMatchedRouteName('home');
$this->controller->getEvent()->setRouteMatch($routeMatch);
$url = $this->plugin->fromRoute();
$this->assertEquals('/', $url);
}

public function testCanReuseMatchedParameters()
{
$this->router->addRoute('replace', SegmentRoute::factory(array(
'route' => '/:controller/:action',
'defaults' => array(
'controller' => 'ZendTest\Mvc\Controller\TestAsset\SampleController',
),
)));
$routeMatch = new RouteMatch(array(
'controller' => 'foo',
));
$routeMatch->setMatchedRouteName('replace');
$this->controller->getEvent()->setRouteMatch($routeMatch);
$url = $this->plugin->fromRoute('replace', array('action' => 'bar'), array(), true);
$this->assertEquals('/foo/bar', $url);
}

public function testCanPassBooleanValueForThirdArgumentToAllowReusingRouteMatches()
{
$this->router->addRoute('replace', SegmentRoute::factory(array(
'route' => '/:controller/:action',
'defaults' => array(
'controller' => 'ZendTest\Mvc\Controller\TestAsset\SampleController',
),
)));
$routeMatch = new RouteMatch(array(
'controller' => 'foo',
));
$routeMatch->setMatchedRouteName('replace');
$this->controller->getEvent()->setRouteMatch($routeMatch);
$url = $this->plugin->fromRoute('replace', array('action' => 'bar'), true);
$this->assertEquals('/foo/bar', $url);
}
}
64 changes: 64 additions & 0 deletions tests/ZendTest/View/Helper/UrlTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
namespace ZendTest\View\Helper;

use Zend\View\Helper\Url as UrlHelper;
use Zend\Mvc\Router\RouteMatch;
use Zend\Mvc\Router\SimpleRouteStack as Router;

/**
Expand Down Expand Up @@ -45,6 +46,7 @@ protected function setUp()
'route' => '/:controller[/:action]',
)
));
$this->router = $router;

$this->url = new UrlHelper;
$this->url->setRouter($router);
Expand All @@ -68,4 +70,66 @@ public function testModuleRoute()
$url = $this->url->__invoke('default', array('controller' => 'ctrl', 'action' => 'act'));
$this->assertEquals('/ctrl/act', $url);
}

public function testPluginWithoutRouteMatchesInEventRaisesExceptionWhenNoRouteProvided()
{
$this->setExpectedException('Zend\View\Exception\RuntimeException', 'RouteMatch');
$url = $this->url->__invoke();
}

public function testPluginWithRouteMatchesReturningNoMatchedRouteNameRaisesExceptionWhenNoRouteProvided()
{
$this->url->setRouteMatch(new RouteMatch(array()));
$this->setExpectedException('Zend\View\Exception\RuntimeException', 'matched');
$url = $this->url->__invoke();
}

public function testPassingNoArgumentsWithValidRouteMatchGeneratesUrl()
{
$routeMatch = new RouteMatch(array());
$routeMatch->setMatchedRouteName('home');
$this->url->setRouteMatch($routeMatch);
$url = $this->url->__invoke();
$this->assertEquals('/', $url);
}

public function testCanReuseMatchedParameters()
{
$this->router->addRoute('replace', array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/:controller/:action',
'defaults' => array(
'controller' => 'ZendTest\Mvc\Controller\TestAsset\SampleController',
),
),
));
$routeMatch = new RouteMatch(array(
'controller' => 'foo',
));
$routeMatch->setMatchedRouteName('replace');
$this->url->setRouteMatch($routeMatch);
$url = $this->url->__invoke('replace', array('action' => 'bar'), array(), true);
$this->assertEquals('/foo/bar', $url);
}

public function testCanPassBooleanValueForThirdArgumentToAllowReusingRouteMatches()
{
$this->router->addRoute('replace', array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/:controller/:action',
'defaults' => array(
'controller' => 'ZendTest\Mvc\Controller\TestAsset\SampleController',
),
),
));
$routeMatch = new RouteMatch(array(
'controller' => 'foo',
));
$routeMatch->setMatchedRouteName('replace');
$this->url->setRouteMatch($routeMatch);
$url = $this->url->__invoke('replace', array('action' => 'bar'), true);
$this->assertEquals('/foo/bar', $url);
}
}

0 comments on commit f5edeb0

Please sign in to comment.