How do I access a routed parameter from inside a controller? - php

This is the route...
'panel-list' => array (
'type' => 'Segment',
'options' => array (
'route' => '/panel-list/:pageId[/:action]',
'constraints' => array (
'pageId' => '[a-z0-9_-]+'
),
'defaults' => array (
'action' => 'index',
'controller' => 'PanelList',
'site' => null
),
),
),
What do I need to put in here....
public function indexAction()
{
echo ???????
}
to echo the pageId?

In beta5 of zf2 it changed to easier usage so you don't need to remember different syntax for every different type. I cite:
New "Params" controller plugin. Allows retrieving query, post,
cookie, header, and route parameters. Usage is
$this->params()->fromQuery($name, $default).
So to get a parameter from the route, all you need to do is.
$param = $this->params()->fromRoute('pageId');
This can also be done with query ($_GET) and post ($_POST) etc. as the citation says.
$param = $this->params()->fromQuery('pageId');
// will match someurl?pageId=33
$param = $this->params()->fromPost('pageId');
// will match something with the name pageId from a form.
// You can also set a default value, if it's empty.
$param = $this->params()->fromRoute('key', 'defaultvalue');
Example:
$param = $this->params()->fromQuery('pageId', 55);
if the url is someurl?pageId=33 $param will hold the value 33.
if the url doesn't have ?pageId $param will hold the value 55

Have you tried
$this->getRequest()->getParam('pageId')

$this->getEvent()->getRouteMatch()->getParam('pageId');

Related

Zend framework 2 routing required query parameters not working

I'm working on zf2 to make one of my routes only accessible when a query string parameter is passed. Otherwise, it will not. I've added a filter on the route section but when accessing the page without the query parameter, it is still going thru.
'router' => array(
'routes' => array(
'show_post' => array(
'type' => 'segment',
'options' => array(
'route' => '[/]show/post/:filter',
'constraints' => array(
'filter' => '[a-zA-Z0-9-.]*',
),
'defaults' => array(
'controller' => 'blog_controller',
'action' => 'show'
)
),
),
),
),
http://example.com/show/post/?postId=1235 = This should work
http://example.com/show/post?postId=1235 = This should work
http://example.com/show/post/ = This should not work
http://example.com/show/post = This should not work
The way you currently have this setup you would have to structure your url like this
http://example.com/show/post/anything?postId=1235
I think what you are wanting is to structure your route like this
'route' => '[/]show/post',
Not sure what you are trying to accomplish with [/] before show though, you are making that dash optional there?
I would write it like this
'route' => '/show/post[/:filter]',
This way you can structure your urls like this
http://example.com/show/post/anything?postId=1235
or
http://example.com/show/post?postId=1235
Then in your action you can access those parameters like this
$filter = $this->params('filter');
$post_id = $this->params()->fromQuery('post_id');
or just
$post_id = $this->params()->fromQuery('post_id');
***************UPDATE***************
It looks like zf2 used to include what you are trying to do and removed it because of security reasons.
http://framework.zend.com/security/advisory/ZF2013-01
Don't try to bend ZF2 standard classes to your way. Instead write your own route class, a decorator to the segment route, which will do exactly as you please:
<?php
namespace YourApp\Mvc\Router\Http;
use Zend\Mvc\Router\Http\Segment;
use use Zend\Mvc\Router\Exception;
use Zend\Stdlib\RequestInterface as Request;
class QueryStringRequired extends Segment
{
public static function factory($options = [])
{
if (!empty($options['string'])) {
throw new Exception\InvalidArgumentException('string parameter missing');
}
$object = parent::factory($options);
$this->options['string'] = $options['string'];
return $object;
}
public function match(Request $request, $pathOffset = null, array $options = [])
{
$match = parent::match($request, $pathOffset, $options);
if (null === $match) {
// no match, bail early
return null;
}
$uri = $request->getUri();
$path = $uri->getPath();
if (strpos($path, $this->options['string']) === null) {
// query string parametr not found in the url
// no match
return null;
}
// no query strings parameters found
// return the match
return $match;
}
}
This solution is very easy to unit test as well, it does not validate any OOP principles and is reusable.
Your new route definition would look like this now:
// route definition
'router' => array(
'routes' => array(
'show_post' => array(
'type' => YourApp\Mvc\Router\Http\QueryStringRequired::class,
'options' => array(
'string' => '?postId=',
'route' => '[/]show/post/:filter',
'constraints' => array(
'filter' => '[a-zA-Z0-9-.]*',
),
'defaults' => array(
'controller' => 'blog_controller',
'action' => 'show'
)
),
),
),
),

Multiple parameters in Form->postLink at CakePHP 2.3.0

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

How to prevent controller and action from coming up in URL in cakephp?

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'
));

Storing a multidimensional array as an object variable, adding additional keys to the array

So I have a multidimensional array which is stored in an object. I want to add additional keys to this array.
Here's what I have:
$object->pathsArray = array(
"key1" => array('path' => '/some/path/to/some/file.php', 'action' => 'index'),
"key2" => array('path' => '/some/path/to/some/class.php', 'action' => 'method2')
);
And here's what I assumed would work but did not:
$object->pathsArray['key3'] = array('path' => '/some/path/to/some/method/or/script.php', 'action' => 'method3');
My first workaround:
$newPathsArray = array("key3" => array('path' => '/some/path/to/some/method/or/script.php', 'action' => 'method3'));
$object->pathsArray = array_merge($object->pathsArray, $newPathsArray);
Another workaround that SHOULD work:
$tempPathsArray = $object->pathsArray;
$tempPathsArray['key3'] = array('path' => '/some/path/to/some/method/or/script.php', 'action' => 'method3');
$object->pathsArray = $tempPathsArray;
So my question: Is there a simpler syntax (ie: one line solution) or am I forced to bring in a temp. variable, append to that then merge/re-assign the value to the object?
Sorry to write an answer, but I'm not able to comment.
I think that it's not correct to make an attribute public just to use it by that way. The correct thing should be make a setter to fill it, not modifying the class design just for that.

Routing configuration and controller action parameters for simple URL redirector

I am trying to make a simple redirector controller in CakePHP. I'd like the URL to be of the form:
http://example.com/redirector/<numeric id>/<url to redirect to>
For example,
http://example.com/redirector/1/http://www.google.com
The URL that I need to redirect could be more complex, of course, including slashes, parameters and anchors.
I can't seem to be able to figure out how to write the route configuration so that my action would look something like:
class RedirectsController extends AppController {
function myredirectaction($id, $url) {
$this->autoRender = false;
$this->redirect($url);
}
It seems like whatever I try, the "/"'s in the url-to-redirect-to confuses my route attempt and splits the URL into pieces, and this no longer matches my action definition. What should I do?
I am new to PHP and CakePHP, so any advice you can give is appreciated.
Update:
So instead of the example URL above, it has been URL-escaped to look like this:
http://example.com/redirector/1/http%3A%2F%2Fwww.google.com
However, my routing is still not working. Here's what I have in routes.php:
Router::connect(
'/redirector/:id/:url',
array('controller' => 'redirects', 'action' => 'myredirectaction'),
array(
'id' => '[0-9]+',
'url' => 'http.*'
)
);
This is what I get when I try that URL:
Warning (2): array_merge() [function.array-merge]: Argument #1 is not an array [CORE/cake/dispatcher.php, line 301]
Code | Context
$fromUrl = "redirector/1/http://www.google.com"
$params = array(
"pass" => array(),
"named" => array(),
"id" => "1",
"url" => "http://www.google.com",
"plugin" => null,
"controller" => "redirects",
"action" => "myredirectaction",
"form" => array()
)
$namedExpressions = array(
"Action" => "index|show|add|create|edit|update|remove|del|delete|view|item",
"Year" => "[12][0-9]{3}",
"Month" => "0[1-9]|1[012]",
"Day" => "0[1-9]|[12][0-9]|3[01]",
"ID" => "[0-9]+",
"UUID" => "[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}"
)
$Action = "index|show|add|create|edit|update|remove|del|delete|view|item"
$Year = "[12][0-9]{3}"
$Month = "0[1-9]|1[012]"
$Day = "0[1-9]|[12][0-9]|3[01]"
$ID = "[0-9]+"
$UUID = "[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}"
$url = array(
"url" => "/redirector/1/http://www.google.com"
)
array_merge - [internal], line ??
Dispatcher::parseParams() - CORE/cake/dispatcher.php, line 301
Dispatcher::dispatch() - CORE/cake/dispatcher.php, line 118
[main] - APP/webroot/index.php, line 88
And more warnings from my action since it did not get the two expected arguments.
Of course, I've changed my action to urldecode($url) before using the $url.
To place slashes and other special characters, use their ACSII codes instead. For a list of the codes and their respective characters, refer to this documentation:
http://www.ascii.cl/htmlcodes.htm
You need to add a pass array to pass the variables to your action.
Router::connect(
'/redirector/:id/:url',
array('controller' => 'redirects', 'action' => 'myredirectaction'),
array(
'id' => '[0-9]+',
'url' => 'http.*',
'pass' => array('id', 'url')
)
);
You can find additional information about why here: http://book.cakephp.org/view/543/Passing-parameters-to-action
I can't seem to make this work with the URL like I was originally hoping for. The best I have been able to do is to supply the URL to redirect to in the parameters. So routing becomes simply:
Router::connect(
'/redirector',
array('controller' => 'redirects', 'action' => 'myredirectaction')
);
And the controller action becomes (error handling omitted):
function myredirectaction() {
$this->autoRender = false;
$redirect_url = $this->params['url']['theurl'];
$this->redirect($redirect_url);
}
And the URL is of the form:
http://example.com/redirector?theid=1&theurl=http://www.google.com

Categories