How to build a Url with multiple query (?) params with CakePHP 3 - cakephp

I'm working in a redirection for autocomplete some fields, and I'm doing this with simple javascript.
I wanted to print a URL without A tag, then I used Url builder. I've seen documentation and reviewed source code for this method in Router class but I see something that I can't understand.
All works right when I use Url builder with this code:
<?= $this->Url->build(['controller' => 'places', 'action' => 'add', '?' => ['event_id' => $event->id]]) ?>
Url genetared is:
/places/add?event_id=1
But, when I add more params in ? query, I get a & in url, but I didn't find in docs something for elimitate special chars filter.
<?= $this->Url->build(['controller' => 'places', 'action' => 'add', '?' => ['from' => 'events','id' => $event->id]])
// Generates: /places/add?from=events&id=1
// I want: /places/add?from=events&id=1
?>
Is there an option to get & without &? If I put all in one string, I get UTF codes %5D and those. I'm using url in a javascript window.open, then I'm not printing in html body.
I see line 597 in http://api.cakephp.org/3.0/source-class-Cake.Routing.Router.html#509-646, but I don't understand if $url = static::_applyUrlFilters($url); code is changing something.
Thank you!

The URL helper is ment to be used for generating URLs for use in markup contexts, therefore they are being entity encoded using the h() function.
In case you need the plain URLs, don't use the URL helper, but the Router::url() method instead.
use Cake\Routing\Router;
Router::url([
'controller' => 'places',
'action' => 'add',
'?' => [
'from' => 'events',
'id' => $event->id
]
]);

Related

How to redefine the URLs generation without changes at the HtmlHelper#link(...) calls in CakePHP?

I have a CakePHP website with many internal links, that are build with the HtmlHelper:
/app/View/MyController/myaction.ctp
<?php
echo $this->Html->link(
$item['Search']['name'],
array(
'controller' => 'targetcontroller',
'action' => 'targetaction',
$profileId,
$languageId
)
);
?>
It works fine with the default route:
/app/Config/routes.php
Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
The generated links look like that: /mycontroller/myaction/$profileId/$languageId.
Now I want to use search engine friendly URLs (with profile names and ISO-639-1 language codes instead of IDs) for a part of the website and added a new Route:
/app/Config/routes.php
Router::connect(
'/:iso6391/:name.html',
array('controller' => 'mycontroller', 'action' => 'myaction'),
array(
'iso6391' => '[a-zA-Z]+',
'name' => '[0-9a-zA-ZäöüßÄÖÜ\-]+',
)
);
And it also works fine and the incomming URIs like /producer/en/TestName.html are interpreted correctly.
But the HtmlHelper is still generating the old URIs like /mycontroller/myaction/1/1.
The docu says:
Reverse routing is a feature in CakePHP that is used to allow you to easily change your URL structure without having to modify all your code. By using routing arrays to define your URLs, you can later configure routes and the generated URLs will automatically update.
Well, the HtmlHelper gets a routing array as input, that means: I'm using the reverse routing.
Why does it not work? How to make the HtmlHelper generate the new URLs (without changing the HtmlHelper#link(...) calls)?
Bit of explanation first
You are technically not using reverse routing. You see, the output link, /mycontroller/myaction/1/1 definitively doesn't match /iso/name.html. Like, in no way. So, the routing skips that rule because it doesn't apply.
Code
Try this
echo $this->Html->link(
$item['Search']['name'],
array(
'controller' => 'targetcontroller',
'action' => 'targetaction',
'iso6391' => $someStringWithIso,
'name' => $someName
)
);
But for that, you have to change your routing a bit, because you are not passing the parameters (check the docs for examples)
Router::connect(
'/:iso6391/:name.html',
array('controller' => 'mycontroller', 'action' => 'myaction'),
array(
'pass' => array('iso6391', 'name'),
'iso6391' => '[a-zA-Z]+',
'name' => '[0-9a-zA-ZäöüßÄÖÜ\-]+',
)
);
And you have to mind the first string match /:iso6391/:name.html. Do you want to match this route to every controller and action in your project, or just the one controller and the one view. If it is for all projects, just for precaution, use this
/:controller/:action/:iso6391/:name.html
if is just for, say, Controller1 and action "view", use
/controller1/view/:iso6391/:name.html
The detail you need to consider is the extension you use .html, is that really necessary in the url? If it is, add it as a parameter in the Html#link
echo $this->Html->link(
$item['Search']['name'],
array(
'controller' => 'targetcontroller',
'action' => 'targetaction',
'iso6391' => $someStringWithIso,
'name' => $someName
'ext' => 'html'
)
);
and also add parseExtensions to the routing file. Read this. Would be easier if you don't add the extension, but that's up to you.
In the end, you still have to change your calls to Html->link...

How I can make and use custom url in cakephp

I am using cakephp 2.4.1, I want make following url for my project. how is it possible?
http://example.com/privew/Homepage?=true
or
http://example.com/privew?=true . I tried it like this
Router::connect('/privew/*',array('controller'=>'Admin','action'=>'privew'));
But it is not helping. Anybody knows how to do it
Try to remove the extra slash before * like:
Router::connect('/privew*',array('controller'=>'Admin','action'=>'privew'));
Also I don't know if you have controller Admin, it should be 'admins' though and it should be lowercase.
Router::url(array(
'controller' => 'posts',
'action' => 'index',
'?' => array('page' => 1),
'#' => 'top'
));
// will generate a URL like.
/posts/index?page=1#top
So you can try like this
Refer this for more info
http://book.cakephp.org/2.0/en/development/routing.html#Router::connectNamed

how to set cakephp paginator url for custom route

I am making blog and url route is like this-
Router::connect('/blog/c/:catid/*',
array('controller' => 'blogarticles', 'action' => 'index'));
it works well with url as- /blog/c/3/other-articles
but when i use paginator in view as
echo $this->Paginator->numbers();
it generates url as- /blogarticles/index/other-articles/page:2
What changes should in make in paginator to generate proper url.
Please suggest possible solution , Thanks in advance
This should solve your problem:
$this->Paginator->options(
array(
'controller' => 'blog',
'action' => 'c',
$catid,
$title
)
);
The trick is to pass blog as the controller and c as the action, and all other variables (NOT LIMITED TO $catid and $title) as additional parameters, sequentially!
NOTE: I assumed here that you have "set" $catid and $title from your Controller, to the current "category id" and "title" respecting. I also assumed that your URLs are always in the format: /blog/c/:catid/:title
You may also want to view my answer to a similar question: https://stackoverflow.com/a/25097693/2862423
What you want is to set the options for the PaginatorHelper for that view:
<?php $this->Paginator->options(array('url' => '/blog/c/3/other-articles')); ?>
CakePHP Book Section on the PaginatorHelper Options Function: http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#modifying-the-options-paginatorhelper-uses

how to change part of url from cakephp's paginator options?

have custom pagination in my cakephp view. before that i made some custom routing changes.
problem is that links leads to pages like
http://localhost/myapp/foos/view/news/page:2
instead of
http://localhost/myapp/news/page:2
so, part with foos/view/ not have to be part of the link.
tried to change url with several custom options, like
$this->Paginator->options(array('url' => $this->passedArgs));
but no luck, because i always have foos/view/ in url.
can you help me how can i get rid of that foos/view?
thank you very much in advance!
UPDATE: i manage to do "something", but not enough, by adding following lines:
$options = array('url'=> array('controller' => 'news' ) );
$paginator->options($options);
now, my link looks like:
http://localhost/myapp/news/index/page:2
how can i get rid of that "index" in url?
The following line is more about passing various pieces of URL information to the view:
$this->Paginator->options(array('url' => $this->passedArgs));
I think what you want to look into is the helper declaration in your Controller:
var $helpers = (
'SomeHelper',
'AnotherHelper',
'Paginator' => array(
'url' => array('controller'=>'news')
)
);
If you want finer control of a custom route like the one you have then try
'url' => '/news'
I haven't used PaginatorHelper in a while - so I could be egregiously on the wrong track - but I believe that's a good start.
Also, take a look at the Paginator Helper page for where it mentions $options and then take a look at Router::url() as the former page recommends.
I had a case where I am working on a project using CakePHP 2.1 (This thread is tagged as 1.3) with a dynamic admin route to display pages like this:
Router::connect('/admin/main/*', array('controller' => 'adminPages', 'action' => 'display'));
With a query string parameter, that produces a dynamic url like this: http://mydomain.com/adminPages/main/...?page=1
The link route, was incorrect for our needs and found I could alter the url directly by using this:
$this->Paginator->options(array(
'url' => array(
'controller' => 'admin/main/my-display',
)
));
For me it made a link: http://mydomain.com/admin/main/my-display?page=1 - which was the correct url we were looking for. If I used a string, as described above, it appends itself to the url, like: http://mydomain.com/adminPages/main/.../admin/main/my-display?page=1
In view :
<?php
$this->Paginator->options(array('url' => array('controller' => '','action' =>'your-custom-url')));
?>
In routes.php :
<?php
Router::connect('/your-custom-url/*', array('controller' => 'Controller', 'action' => 'function'));
?>

Creating meaningful add URLs in Cakephp

For my site I have a number of Orders each of which contains a number of Quotes. A quote is always tied to an individual order, so in the quotes controller I add a quote with reference to it's order:
function add($orderId) {
// function here
}
And the calling URL looks a bit like
http://www.example.com/quotes/add/1
It occurred to me the URLs would make more sense if they looked a bit more like
http://www.example.com/orders/1/quotes/add
As the quote is being added to order 1.
Is this something it's possible to achieve in CakePHP?
Have a look at the documentation for defining routes.
Something like this should do the trick:
Router::connect(
'/orders/:id/quotes/add',
array('controller' => 'quotes', 'action' => 'add'),
array('id' => '[0-9]+')
);
You will be able to access the ID with $this->params['id'] in QuotesController::add().
Edit:
Also, have a look at the documentation for passing parameters to action.
It is possible to pass the ID in as a parameter of the controller action like so:
Router::connect(
'/orders/:id/quotes/add',
array('controller' => 'quotes', 'action' => 'add'),
array('pass' => array('id'), 'id' => '[0-9]+')
);
You can then access the ID with $id in QuotesController::add($id).

Resources