Is it possible to pass parameters via redirect? I tried a lot of options, but nothing seems to work. My latest approach is:
return $this->redirect(array('Users::helloworld', 'args' => array('id' => 'myId')));
then I created a route:
Router::connect('/Users/helloworld?id={:id}', array('controller' => 'Users', 'action' => 'helloworld'));
but all I get is users/helloworld/myId
args is part of the routes and will be converted into an URL using the very generic route (not the one you created and don't require)
To get a query string, simply use the ? key:
return $this->redirect(array(
'Users::helloworld',
'?' => array('id' => $myId)
));
// will use the route:
// /{:controller}/{:action}/{:args}
// and generate
// /users/helloworld?id=$myId
The test for that: https://github.com/UnionOfRAD/lithium/blob/master/tests/cases/net/http/RouteTest.php#L374-405
Instead of defining a separate route to pass arguments, you could just do the following.
Lets say you want to pass 2 arguments: $arg1 & $arg2 to the helloworld action of your Users controller:
return $this->redirect(array(
'Users::helloworld',
'args' => array(
$arg1,
$arg2
)
));
Related
Is it possible to pass multiple parameters to an action in the controller by using the method postLink of the FormHelper?
I didn't manage to do it by using the options array. It is not very well specified in the docs what values this array admits.
This is what I tryed:
$this->Form->postLink($staffUser['User']['_name'], array(
'action' => 'subscribe',
array('ticketId' => $ticket['Ticket']['id'], 'userId' => $staffUser['User']['id'])
));
My subscribe action looks like this:
public function subscribe($ticketId, $userId = null){
if ($this->request->is('post')) {
//...
}
}
Update
I've just noticed the provided solution creates another problem to me. Now the class stop getting added ulike before when I was using only one parameter:
$this->Form->postLink($staffUser['User']['_name'], array(
'action' => 'subscribe',
$ticket['Ticket']['id'],
$staffUser['User']['id'],
array('class' => 'demo') //not beind added
));
postLink takes its URL entry in the same form as the create method. Parameters don't need a key, put them in order after the action key/value.
Other options need to go in the third argument - you have the options array as an additional entry to the url array.
$this->Form->postLink($staffUser['User']['_name'], array(
'action' => 'subscribe',
$ticket['Ticket']['id'],
$staffUser['User']['id']
),
array(
'class' => 'demo'
)
);
See options for FormHelper::create here:
http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html
I have some simple pagination set up in my controller like so:
public function index() {
$this->set('items', $this->paginate());
}
In my view I'm using the Paginator helper to output numbered links:
echo $this->Paginator->numbers(array(
'separator' => '',
'tag' => 'li',
'currentTag' => 'a',
'currentClass' => 'active'
));
This all works fine, however I want to use a custom URL for the paginated links. I added this to my routes.php file:
Router::connect('/things/:page', array('controller' => 'things', 'action' => 'index'), array('page' => '[0-9]+'));
Now the links outputted by the Paginator helper are the way I want. They look like http://mysite.com/things/2, http://mysite.com/things/3 etc.
But when I click the links the Paginator in my controller doesn't seem to recognize it's on a certain page, as I just get the first page's results shown. I'm guessing I need to somehow pass the page number to $this->paginate(), but I don't know what the best method is. Is there a way for Cake to get the page number automatically if I modify my route?
Thanks!
Since the Pagination component by default expect named parameter 'page:1' you need somehow to pass same variable in index.
if you make print of $this->request->params in your controller, you will see that it's missing.
See that example how you can pass named parameters in the Router:
Router::connect(
'/:controller/:action/*',
array(),
array(
'named' => array(
'wibble',
'fish' => array('action' => 'index'),
'fizz' => array('controller' => array('comments', 'other')),
'buzz' => 'val-[\d]+'
)
)
);
For more info see this section in Cakephp book
I have an Action method in Foo Controller which requires parameters:
public function fooAction($one, $two) {
$a = one;
$b = $two;
}
And I need to forward to that method from the other method of some Boo Controller. And one of those parameters has to be by reference parameter. The only example that the manual has is this:
$result = $this->forward()->dispatch('Boo\Controller\Boo', array('action' => 'boo'));
No any additional parameters. But they write:
$params is an optional array of parameters with which to see a
RouteMatch object for purposes of this specific request.
So, I tried:
$result = $this->forward()->dispatch('Boo\Controller\Boo', array(
'action' => 'boo',
'one' => &$one,
'two' => $two,
));
But it doesn't work.
Is there any way to pass additional parameters to forward controller?
UPD:
These do not work too:
$result = $this->forward()->dispatch('Boo\Controller\Boo', array(
'action' => 'boo',
'params' => array(
'one' => &$one,
'two' => $two,
)));
$result = $this->forward()->dispatch('Boo\Controller\Boo', array(
'action' => 'boo',
'options' => array(
'one' => &$one,
'two' => $two,
)));
UPD 2:
I still can't get the functionality I want (to pass parameters with the forward plugin) but I found other solutions. Before calling the forward plugin I set the variables to the Request object and after the forward I get them from the Request in my boo Action of my Boo\Controller\BooController:
// in Foo::fooAction
$this->getRequest()->one = &$one;
$this->getRequest()->two = $two;
$result = $this->forward()->dispatch('Boo\Controller\Boo', array('action' => 'boo'));
// in Boo::booAction
$a = $this->getRequest()->one;
$b = $this->getRequest()->two;
Stupid solution, it will not work with Ajax requests. Still interested how to pass parameters with the forward plugin. OR MAYBE how to get them in the booAction. Because there in no anything in the Request if I pass them with the forward.
UPD 3 and Final:
I finally found where they've decided to hide parameters I pass with the forward plugin. They put them in the RouteMatch object.
- Tryyyy to guess where we've hidden your params... Oh yeeah, they are in the RouteMatch, of course they are there, didn't you think smth else?
And NO ANY info in the forward plugin section of the manual!
To get params, I have to do this in my BooController::booAction:
$param = $this->getEvent()->getRouteMatch()->getParam('nameOfParam');
Why not to use the params plugin?
This works for me:
public function indexAction() {
$object = new SomeObject();
return $this->forward()->dispatch('Application\Controller\Index', [
'action' => 'show',
'myObject' => $object,
]);
}
public function showAction() {
$object = $this->params('myObject');
var_dump($object);
return [];
}
You can create a container class and use it in both controllers
in module.conf
public function getServiceConfig()
{
return array(
'invokables' => array(
'my_handy_container' => 'path\container_class_name',
)
);
}
Create a getter in both controllers:
public function getMyHandyContainer()
{
if (!$this->myHandyContainer) {
$this->myHandyContainer = $this->getServiceLocator()->get('my_handy_container');
}
return $this->myHandyContainer;
}
And call it using:
$myContainer = $this->getMyHandyContainer()->myHandyContainer;
$myContainer->foo = 5; // set something
ZF2 way to pass vars using forward
In the passing method do:
return $this->forward()->dispatch('controller_name', [
'action' => 'whatever',
'varname' => $value,
'varname2' => $value2
]);
In the invoked controller method, do:
$param2 = $this->params()->fromRoute('varname2',false);
Thought I would add another option that works for me.
You can simply pass the params straight through the forward function and use the routeMatch function to access them at the other end.
return $this->forward()
->dispatch('Module\Controller\Foo', array(
'action' => 'bas',
'id' => 6)
);
Passes to Foo Controller, basAction in this method you can then use the following code to access the id param
$myParam = (int) $this->getEvent()->getRouteMatch()->getParam('id');
Not sure if this meets your requirements - but works for me.
Thanks for the question, helped me a lot. Found an easy way for getting all params passed to forward()->dispatch(...). In the controller's action method:
$params = $this->params()->fromRoute();
returns array $data as passed as $data into forward()->dispatch($controllerName, $data).
Here in the official ZF2 documentation is written exactly how it works:
$params is an optional array of parameters with which to seed a RouteMatch object for purposes of this specific request. Meaning the parameters will be matched by their key to the routing identifiers in the config (otherwise non-matching keys are ignored).
So pass like this:
$params = array(
'foo' => 'foo',
'bar' => 'bar'
);
$this->forward()->dispatch('My\Controller', $params)
And then you can get your route match params in your My\Controller like normally:
$foo = $this->params()->fromRoute('foo');
$bar = $this->params()->fromRoute('bar');
For people struggling with accessing parameters within their controller here a nice overview from this CheatSheet.
$this->params()->fromPost('foo'); //POST
$this->params()->fromQuery('foo'); //GET
$this->params()->fromRoute('foo'); //RouteMatch
$this->params()->fromHeader('foo');//Header
$this->params()->fromFiles('foo'); //Uploaded file
I have one route that looks like this:
Router::connect('/Album/:slug/:id',array('controller' => 'albums', 'action' => 'photo'),array('pass' => array('slug','id'),'id' => '[0-9]+'));
and another like this:
Router::connect('/Album/:slug/*',array('controller' => 'albums','action' => 'contents'),array('pass' => array('slug')));
for what doesn't match the first. In the 'contents' action of the 'albums' controller, I take care of pagination myself - meaning I retrieve the named parameter 'page'.
A URL for the second route would look like this:
http://somesite.com/Album/foo-bar/page:2
The Above URL indeed works, but when I try to use the HTML Helper (url,link) to output a url like this, it appends the controller and action to the beginning, like this:
http://somesite.com/albums/contents/Album/foo-bar/page:2
Which i don't like.
The code that uses the HtmlHelper is as such:
$html->url(array('/Album/' . $album['Album']['slug'] . '/page:' . $next))
See below url it is very help full to you
http://book.cakephp.org/2.0/en/development/routing.html
Or read it
Passing parameters to action
When connecting routes using Route elements you may want to have routed elements be passed arguments instead. By using the 3rd argument of Router::connect() you can define which route elements should also be made available as passed arguments:
<?php
// SomeController.php
public function view($articleId = null, $slug = null) {
// some code here...
}
// routes.php
Router::connect(
'/blog/:id-:slug', // E.g. /blog/3-CakePHP_Rocks
array('controller' => 'blog', 'action' => 'view'),
array(
// order matters since this will simply map ":id" to $articleId in your action
'pass' => array('id', 'slug'),
'id' => '[0-9]+'
)
);
And now, thanks to the reverse routing capabilities, you can pass in the url array like below and Cake will know how to form the URL as defined in the routes:
// view.ctp
// this will return a link to /blog/3-CakePHP_Rocks
<?php
echo $this->Html->link('CakePHP Rocks', array(
'controller' => 'blog',
'action' => 'view',
'id' => 3,
'slug' => 'CakePHP_Rocks'
));
I have the following route:
Router::connect('/admin/login/:to',
array('admin'=>true,'controller'=>'users','action'=>'login'),
array(
'to' => '[A-Za-z0-9\._-]+',
'pass' => array('to')
));
Which basically passes a string/int with the login url. But it no longer uses the named parameter of to. So for example instead of getting: /admin/login/to:1AB I get /admin/login/1AB
How do I keep the named parameter but still alter the routing to remove the users bit from the url? I've tried: '/admin/login/to::to' but that seems rather sloppy...
you could find passed parameter's name in "$this->data" in your controller.
in your example: $this->data->to has the same value you put in your url.
Remove that route. Why do you have that route when you want the named parameter?
Edit: if so:
Router::connect(
'/admin/login/*',
array(
'admin' => true,
'controller' => 'users',
'action' => 'login'
)
);