I have following configuration in module.config.php
'router'=>array(
'routes'=>array(
'test'=>array(
'type'=>'Zend\Mvc\Router\Http\Literal',
'options'=>array(
'route'=>'/test',
'defaults'=>array(
'controller'=>'Test\Controller\Index',
'action'=>'index'
)
),
'may_terminate' => true,
'child_routes' => array(
'edit' => array(
'type' => 'segment',
'options' => array(
'route' =>'/edit[/:id]',
'constraints' =>array('id' => '[\d\w\-_]*'),
'defaults' => array(
'controller' =>'Test\Controller\Index',
'action' => 'edit',
),
),
),
'add' => array(
'type' => 'segment',
'options' => array(
'route' =>'/add',
'defaults' => array(
'controller' =>'Test\Controller\Index',
'action' => 'add',
),
),
),
),
)
)
)
now I am using following redirect
return $this->redirect()->toRoute('test');
and it is not working. I am not getting what is wrong with this
Your Config file is not much helpful here, you should have posted your controller's code, nevertheless ,
instead of return $this->redirect()->toRoute('test');,
use the following format
return $this->redirect()->toRoute('ModuleName',
array('controller'=>controllerName,
'action' => actionName,
'params' =>params));
Where ModuleName is the name of your module,
Where ControllerName is the name of your controller,
Where Action Name is the name of your action,
Note:- params are optional.
If you module name is test, then you try with:
return $this->redirect()->toUrl('/test');
Related
I have configured a route in my module.config.php to handle two parameters ,
here is the content of the file module.config.php , i put just the definition of the routes ( same routes ) :
updated :
'router' => array(
'routes' => array(
'Products' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/application/admin/products[/:id]',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Admin',
'action' => 'index',
),
),
),
'productsList' => array(
'type' => 'segment',
'options' => array(
'route' => '/application/products/productsList[/:type][/:id]',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Products',
'action' => 'productsList'
),
),
),
'Emplacement' => array(
'type' => 'segment',
'options' => array(
'route' => '/application/support/listeEmplacementsSupport[/:pkSupport]',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Support',
'action' => 'listeEmplacementsSupport',
),
),
),
'application' => array(
'type' => 'Literal',
'options' => array(
'route' => '/application',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:controller[/:action[/:id][/:dr]]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
),
),
),
),
),
),
),
And I build a link in the view using the following
<a href="/application/products/productsList/mandan/<?php echo $coreg['idProduct']; ?>" >
<img height='20' src="/img/mail-recevoir-32.png" alt='products' />
</a>
To get one parameter I use
$param = $this->params('id');
Routes are matched in the 'Last in first out' LIFO order.
The relevant section of the documentation states:
Typically, routes should be queried in a LIFO order, and hence the reason behind the name RouteStack. [...] you will need to ensure that routes that potentially overlap are registered such that the most specific match will match first (i.e., register later)
Therefore based on you current configuration, as all the routes are register at the top level, the last route (application/default) is being checked and then subsequently matched first, before the productList is given a chance.
Also because application/default defines an optional id parameter as the first argument this is the reason that you get the value of the type param when using $this->params('id').
Soultion
The easiest solution is just to reorder the routes; moving the application route right to the top of the definition should work.
The order should be the following
'router' => array(
'routes' => array(
'application' => array(
// .. same
'child_routes' => array(
'default' => array(
// .. Same
),
),
),
'Products' => array(
// ..same
),
'productsList' => array(
// ..same
),
'Emplacement' => array(
// ..config
),
),
),
You could alternatively give each route a priority, regardless of the order, however I think It would make more sense to keep them in a natural order to save confusion in the future.
While I'm here
I mentioned in my comment you incorrectly used a Literal route rather than a Segment. You have this same issue with the the Products route definition. If a route is literal it will only match on the exact value (so you would need /[:id] in the URL).
/application/admin/products[/:id]
Therefore you will also need to update this route to a segment in order for the product id to be regarded as a parameter.
Lastly, there is a easier way of constructing URL's in the view, using the URL view helper. Your view script code would be changed to
<?php
$type = 'mandan';
$id = $coreg['idProduct'];
?>
<a href="<?php echo $this->url('productsList', compact('type', 'id')); ?>">
<img height='20' src="/img/mail-recevoir-32.png" alt='products' />
</a>
I have a /files controller that will have two actions: upload and download
it's defined as follows:
'files' => array(
'type' => 'Segment',
'options' => array(
'route' => '/files[/:action]',
'defaults' => array(
'controller' => 'Application\Controller\Files',
'action' => 'index',
),
),
),
I want the download action to be accessed like /files/download/1?authString=asdf. 1 in this case is a fileId.
I understand I can just change the route to /files[/action[/:fileId]] to set up the route, correct me if I'm wrong, but then how do I access the fileId inside the downloadAction? And is there anything else I need to change about the route definition to make it work??
I can just change the route to /files[/action[/:fileId]] to set up the route, correct me if I'm wrong
You're not wrong, that would be a valid route.
is there anything else I need to change about the route definition?
If you add the fileId as a optional route param then you will need to do some manual checking within the downloadAction() to ensure it is set.
Another solution would be to separate the routes into children, this ensures that unless you have the correct parameters on each route, it would not be matched.
'files' => array(
'type' => 'Segment',
'options' => array(
'route' => '/files',
'defaults' => array(
'controller' => 'Application\Controller\Files',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'download' => array(
'type' => 'Segment',
'options' => array(
'route' => '/download/:fileId',
'defaults' => array(
'action' => 'download',
),
'constraints' => array(
'fileId' => '[a-zA-Z0-9]+',
),
),
),
'upload' => array(
'type' => 'Literal',
'options' => array(
'route' => '/upload',
'defaults' => array(
'action' => 'upload',
),
),
),
),
),
how do I access the fileId inside the downloadAction
The easiest way would be to use the Zend\Mvc\Controller\Plugin\Params controller plugin to fetch the parameter from the route).
// FilesController::downloadAction()
$fileId = $this->params('fileId');
Or specifically from the route
// FilesController::downloadAction()
$fileId = $this->params()->fromRoute('fileId');
I follow this tutorial: http://ivangospodinow.com/zend-framework-2-acl-setup-in-5-minutes-tutorial/
But, I want to grant permission by custom URLs, so I had some changes in my code.
In module.acl.roles.php
return array(
'guest'=> array(
'/home.html',
'/login.html',
'/register.html'
),
'admin'=> array(
'/user/add.html',
'/user/edit.html',
'/user/list.html',
),
);
In module.config.php
return array(
'router' => array(
'routes' => array(
'/home.html' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/',
'defaults' => array(
'controller' => 'Application\Controller\Index',
'action' => 'index',
),
),
),
'/user/add.html' => array(
'type' => 'Zend\Mvc\Router\Http\Regex',
'options' => array(
'regex' => '/user/add.html',
'defaults' => array(
'controller' => 'Application\Controller\User',
'action' => 'add',
'format' => 'html',
),
'spec' => '/user/add.%format%',
),
),
...
),
),
);
But I received this error: Route with name "" not found. Please give me some advices and solutions to grant permission by URLs
Thank you!
I really really recommend the BjyAuthorize module (https://packagist.org/packages/bjyoungblood/bjy-authorize).
But if you really want to do this by yourselft you need to add a listener to the \Zend\Mvc\MvcEvent::EVENT_ROUTE.
You can attach your listener with
$events->attach(MvcEvent::EVENT_ROUTE, array($this, 'myOnRoute'), -1000);
and in your myOnRoute method you can handle the route
public function myOnRoute(MvcEvent $event) {
$match = $event->getRouteMatch();
$routeName = $match->getMatchedRouteName();
// do stuff here (compare to config or whatever)
}
I've have an problem to redirect on child routes in zend framework 2. I can access the controller and action but while redirecting it throws me an error missing parameter "id".
'admin' => array(
'type' => 'segment',
'options' => array(
'route' => '/admin[/][:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Admin\Controller\Admin',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'settings' => array(
'type' => 'Segment',
'may_terminate' => true,
'options' => array(
'route' => '/general[/][:action][/][:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Admin\Controller\Settings\General',
'action' => 'index',
),
),
),
),
),
I have given redirect to route like below,
return $this->redirect()->toRoute('admin/settings');
But it throws an error,
Missing parameter "id"
as the error message implies you need to add the "id" parameter. You can redirect with a parameter like so.
return $this->redirect()->toRoute('admin', array('action'=>'settings', 'id' => $id));
You did not show us your Controller action's but I assume 'settings' is a action within your admin module.
At this point I cannot really see what kind of id the admin/settings function need's might aswell just try to add a 0 or 1 to try the route at first for testing purposes.
The route matching method doesn't seem to 'consume' the parent node of the route.
Changing the child route to include the /admin part of the grammar to
/admin/settings/general[/][:action][/][:id]
or
/admin/settings[/][:action][/][:id]
should allow $this->redirect()->toRoute('admin/settings'); to work.
Build navigation from config:
'navigation' => array(
'default' => array(
'admin' => array(
'label' => 'Administration',
'controller' => 'index',
'action' => 'index',
'route' => 'admin/default',
),
'album' => array(
'label' => 'Album',
'controller' => 'index',
'action' => 'index',
'route' => 'album/default',
),
/* ... */
Routing is configured like it is true. Navigation in the menu works. Links menu lead to the desired controller/action of the desired module. But while introducing menu and a transition to one or another menuitem, active marked both points simultaneously and 'Administration' and 'Album'. As I understand it, for the reason that match the names of controllers and actions with them, but there's still the 'route' and it's different... not for nothing that the generated different url for each item... but somehow, despite this, they both are marked as active.
Routing config:
'router' => array(
'routes' => array(
'admin' => array(
'type' => 'Literal',
'options' => array(
'route' => '/admin',
'defaults' => array(
'__NAMESPACE__' => 'Admin\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:controller][/:action[/id:id]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
),
),
),
Album routing config similar...
Why this is happening? Thanks.
Looks like it's how ZF2 works (read isActive() function in Zend\Navigation\Page\Mvc.php). Initially it checks matching of route/controller/action, but if it fails, ZF2 again check for just controller/action pair. So there are three possible ways:
Open a ticket at https://github.com/zendframework/zf2/issues and wait for response.
Override \Zend\Navigation\Page\Mvc.
Choose different names for controllers (and don't use index name because it's default name for controller in Mvc.php).
If you make your controller names include the the namespace then they will be unique and won't clash:
Admin\Controller\IndexController
Album\Controller\IndexController
Rather than
Index
Index