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

Allow passing objects to the url helper #4178

Merged
merged 4 commits into from
Apr 12, 2013
Merged
Show file tree
Hide file tree
Changes from 3 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 library/Zend/Mvc/Controller/Plugin/Redirect.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class Redirect extends AbstractPlugin
* @throws Exception\DomainException if composed controller does not implement InjectApplicationEventInterface, or
* router cannot be found in controller event
*/
public function toRoute($route = null, array $params = array(), $options = array(), $reuseMatchedParams = false)
public function toRoute($route = null, $params = array(), $options = array(), $reuseMatchedParams = false)
{
$controller = $this->getController();
if (!$controller || !method_exists($controller, 'plugin')) {
Expand Down
32 changes: 24 additions & 8 deletions library/Zend/Mvc/Controller/Plugin/Url.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,38 @@ class Url extends AbstractPlugin
/**
* Generates a URL based on a route
*
* @param string $route RouteInterface name
* @param array $params Parameters 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 bool $reuseMatchedParams Whether to reuse matched parameters
* @param string $route RouteInterface name
* @param array|\Traversable $params Parameters 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 bool $reuseMatchedParams Whether to reuse matched parameters
*
* @throws \Zend\Mvc\Exception\RuntimeException
* @throws \Zend\Mvc\Exception\InvalidArgumentException
* @throws \Zend\Mvc\Exception\DomainException
* @return string
* @throws Exception\DomainException if composed controller does not implement InjectApplicationEventInterface, or
* router cannot be found in controller event
* @throws Exception\RuntimeException if no RouteMatch instance or no matched route name present
*/
public function fromRoute($route = null, array $params = array(), $options = array(), $reuseMatchedParams = false)
public function fromRoute($route = null, $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');
}

if (! is_array($params)) {

if (! $params instanceof \Traversable) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No space after !

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use Traversable; in header.


throw new Exception\InvalidArgumentException(
'Params is expected to be an array of a Traversable object'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/of/or/

);

} else {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why all the empty lines here at the beginning of each block?

$params = iterator_to_array($params);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't need to be done inside an else block -- the if block will throw an exception. :)

}

$event = $controller->getEvent();
$router = null;
$matches = null;
Expand Down
35 changes: 26 additions & 9 deletions library/Zend/View/Helper/Url.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\Router\RouteMatch;
use Zend\Mvc\Router\RouteStackInterface;
use Zend\Stdlib\ArrayUtils;
use Zend\View\Exception;
use Zend\Stdlib\Exception as StdlibException;

/**
* Helper for making easy links and getting urls that depend on the routes and router.
Expand Down Expand Up @@ -61,16 +63,17 @@ public function setRouteMatch(RouteMatch $routeMatch)
* Generates an url given the name of a route.
*
* @see Zend\Mvc\Router\RouteInterface::assemble()
* @param string $name Name of the route
* @param array $params Parameters for the link
* @param array $options Options for the route
* @param bool $reuseMatchedParams Whether to reuse matched parameters
* @return string Url For the link href attribute
* @throws Exception\RuntimeException If no RouteStackInterface was provided
* @throws Exception\RuntimeException If no RouteMatch was provided
* @throws Exception\RuntimeException If RouteMatch didn't contain a matched route name
* @param string $name Name of the route
* @param array $params Parameters for the link
* @param array|\Traversable $options Options for the route
* @param bool $reuseMatchedParams Whether to reuse matched parameters
* @return string Url For the link href attribute
* @throws Exception\RuntimeException If no RouteStackInterface was provided
* @throws Exception\RuntimeException If no RouteMatch was provided
* @throws Exception\RuntimeException If RouteMatch didn't contain a matched route name
* @throws Exception\InvalidArgumentException If the params object was not an array or \Traversable object
*/
public function __invoke($name = null, array $params = array(), $options = array(), $reuseMatchedParams = false)
public function __invoke($name = null, $params = array(), $options = array(), $reuseMatchedParams = false)
{
if (null === $this->router) {
throw new Exception\RuntimeException('No RouteStackInterface instance provided');
Expand All @@ -93,6 +96,20 @@ public function __invoke($name = null, array $params = array(), $options = array
}
}

if (! is_array($params)) {

if (! $params instanceof \Traversable) {

throw new Exception\InvalidArgumentException(
'Params is expected to be an array of a Traversable object'
);

} else {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comments as above.

$params = iterator_to_array($params);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comments as noted for the controller plugin -- s/of/or/ and promote else block.

}

if ($reuseMatchedParams && $this->routeMatch !== null) {
$routeMatchParams = $this->routeMatch->getParams();

Expand Down
14 changes: 14 additions & 0 deletions tests/ZendTest/Mvc/Controller/Plugin/UrlTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ public function setUp()
'controller' => 'ZendTest\Mvc\Controller\TestAsset\SampleController',
),
)));
$router->addRoute('default', array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/:controller[/:action]',
)
));
$this->router = $router;

$event = new MvcEvent();
Expand All @@ -48,6 +54,14 @@ public function testPluginCanGenerateUrlWhenProperlyConfigured()
$this->assertEquals('/', $url);
}

public function testModel()
{
$it = new \ArrayIterator(array('controller' => 'ctrl', 'action' => 'act'));

$url = $this->plugin->fromRoute('default', $it);
$this->assertEquals('/ctrl/act', $url);
}

public function testPluginWithoutControllerRaisesDomainException()
{
$plugin = new UrlPlugin();
Expand Down
16 changes: 16 additions & 0 deletions tests/ZendTest/View/Helper/UrlTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,22 @@ public function testModuleRoute()
$this->assertEquals('/ctrl/act', $url);
}

public function testModel()
{
$it = new \ArrayIterator(array('controller' => 'ctrl', 'action' => 'act'));

$url = $this->url->__invoke('default', $it);
$this->assertEquals('/ctrl/act', $url);
}

/**
* @expectedException \Zend\View\Exception\InvalidArgumentException
*/
public function testThrowsExceptionOnInvalidParams()
{
$this->url->__invoke('default', 'invalid params');
}

public function testPluginWithoutRouteMatchesInEventRaisesExceptionWhenNoRouteProvided()
{
$this->setExpectedException('Zend\View\Exception\RuntimeException', 'RouteMatch');
Expand Down