rewriting old-school query strings to modern cakephp URLs - url

A plea for your indulgence. I have searched for answers and tried many things, so I now humbly turn here for help. It should be simple: I'm moving to CakePhp and I want to redirect my old query strings (action=show&id=2) to groovy cake URLs (/Feature/view/2).
I've tried this in the .htaccess file in the webroot:
RewriteCond %{QUERY_STRING} ^action=show&id=([0-9]+)$
RewriteRule /Features/view/%1? [R,L]
No love. I also tried:
RewriteRule action=show&id=([0-9]+) /Features/view/$1 [L]
No love.
I tried Cakephp's routes.php with:
Router::connect('index.php?action=show&id=([0-9]+)',array('controller' => 'features', 'action' => 'view', 'id' => $1));
But I've seen no evidence that regex can be used that way in routes.php so that was really just throwing up a prayer.
It's possible to do this. Right? Thanks for any advice!

I think you can do it within router.php!
Maybe, you can get away with:
Router::connect('?action=:action&id=:id',
array(
'controller' => 'myController',
'action' => 'myAction',
),
array(
'action' => '[a-zA-Z]+',
'id' => '[0-9]+',
)
);
Or (probably better) a series of more specific forms like:
Router::connect('?action=show&id=:id',
array(
'controller' => 'features',
'action' => 'view',
),
array(
'id' => '[0-9]+',
)
);
In this case, action and id would be available in $this->request->params in myController (and in the case of a standard like id, there might even be automagic to help!)
Though I'm not sure that the routing elements (:foo) will pick up GET params like that..
Alternatively, you could send everything to one controller anyway, and you should find the GET parameters are listed in $this->request->params['url'], so you can route everything in the controller (to other controllers, I guess).
Doesn't sound pretty either way, but I understand you want to keep some legacy urls running!

Related

ZF2 - Formatting Routes

I typically format my routes in ZF2 like so: /name/to/route
Now I have been doing the same thing with my api routes however I am finding that I am struggling to include data such as encoded urls or arrays.
Here is an example of such a route:
http://example.com/api/register/access/code/c102dea422fa4bb6958d77a29d9873d2/http%3A%2F%2Frouter-local.example.com%2Fapi%2Fdirectory
The following represents forward slashes and thus causes the route not to work: %3A%2F%2
I am thinking I should encode my route as such:
http://example.com/api/register/access/code/?access_code=c102dea422fa4bb6958d77a29d9873d2&route=http%3A%2F%example.com%2Fapi%2Fdirectory
How do you configure the module.config file to deal with this?
Currently it is set as such in apigility:
'api.rpc.register-access-code' => array(
'type' => 'Segment',
'options' => array(
'route' => '/api/register/access/code/:access_code/:route',
'defaults' => array(
'controller' => 'Api\\V1\\Rpc\\RegisterAccessCode\\Controller',
'action' => 'registerAccessCode',
),
),
),
EDIT
I have encoded my routes to include GET parameters by doing the following:
$url = "http://example.com/api/register/access/code/";
$params = [
'access_code' => 'c102dea422fa4bb6958d77a29d9873d2',
'route' => 'http://example.com/api/directory'
];
$final = $url . "?" . http_build_query($params);
Which gives this:
http://example.com/api/register/access/code/?access_code=c102dea422fa4bb6958d77a29d9873d2&route=http%3A%2F%2Fexample.com%2Fapi%2Fdirectory
However this breaks due to a "The requested URL could not be matched by routing." error.
The route is unidentified due to the interpretation of the slashes in the included URL.
Perhaps the issue is to do with how the URL is formatted and included as a parameter?
You don't define query variables in the segment route option; only the path.
You may append ?query=vars to any url, regardless of route configuration. ZF2's url helpers should encode the query vars for you, you just have to create an array of query vars and give it to the helper function when creating a url.
<?php echo $this->url('api.rpc.register-access-code', array(), array('query' => array(
'access_code' => 'c102dea422fa4bb6958d77a29d9873d2',
'route' => 'http://router-local.example.com/api/directory',
))); ?>`
In this case, it would seem the problem is to do with htaccess or apache. The simplest solution has been to encode the url using: base64_encode($url) which can be de-coded at the other end.

zf2 website with a single entry-point, no routes/paths in URL

Is it be possible to make a website that doesn't reveal any relative URL's at all?
Say for example, I have a domain name "somedomain.xyz" and I want to route everything through the default route, and I want not to reveal any paths or route structures to the end user.
The end user shall only see the domain name in the browser's address bar, like:
http://somedomain.xyz
or
https://somedomain.xyz.
Any path like
http://somedomain.xyz/index.php
or
http://somedomain.xyz/index or
http://somedomain.xyz/index/index
shall show a 404.
And I don't care about SEO stuff and static pages.
Is that possible with ZF2, and if yes, then how?
similar question: hide module and action name from zf2 routing
Just create a hostname route for subdomain.xyz like so:
'my-route' => array(
'type' => 'Hostname',
'options' => array(
'route' => 'subdomain.xyz',
'defaults' => array(
'controller' => 'MyApp\Controller\TheController',
'action' => 'whatever-action',
),
),
),
see here for a complete solution, with using HTTP POST vars for the routing:
ZF2 routing via post vars

ZF2 Route with Colon Separator

I am working with ZF2 and trying to setup Route configuration that uses a colon separator.
For example, the web address could be www.example.com/namespace:subject and I want to send it to a specific controller, action with the two variables. I am trying to use a Regex since the colon ":" is a special character for segments. Is there a nice way to do this? Here is my route configuration:
'dataReqs' => array(
'type' => 'regex',
'options' => array(
'regex' => '/(?<namespace>[^:]+).(?<subject>[a-zA-Z0-9_-]+)',
'defaults' => array(
'controller' => 'Application\Controller\Data',
'action' => 'get',
),
'spec' => '/%namespace%:%subject%',
),
),
EDIT: I want to use the colon as the prefix:resource format is commonly used in RDF syntax (http://www.w3.org/TR/2007/PR-rdf-sparql-query-20071112/#QSynIRI). For instance, a long uri like http://dbpedia.org/data/Semantic_Web with a #prefix dbp: http://dbpedia.org/resource/ may be referred in a document with dbp:Semantic_Web. So for my Linked Data server I could direct requests and include the prefix (namespace) and the resource name; eg http://myserver.com/dbp:Semantic_Web. While I am using the segment combinations /namespace/resource for now, it would be nice to handle a route with prefix:resource syntax.
Do not use colon in your route. It isn't good practice, because colon is reserved character(see https://www.rfc-editor.org/rfc/rfc3986#section-2.2)
I'm inclined to agree with kormik. Why do you want to specify URL's in that way? What is wrong with the default behavior?
www.example.com/namespace/subject
eg:
www.example.com/somenamespace/10
or even:
www.exmple.com/namespace/namespace/subject/subject
eg
www.example.com/namespace/somenamespace/subject/10
you can easily grab these parameters in the controller like so:
$ns = $this->params()->fromRoute('namespace',0);
$subject = (int) $this->params->fromRoute('subject',0);
You would need to modify the route config also.

Change default controller path in lithium

I'm writing a new version of an API and would like to support legacy versions by having distinct sets of controllers for each version. Within the default "app\controllers" path in Lithium, I would like to have for example "v1" and "v2" paths.
I have tried accomplishing this within the route itself by doing something like:
Router::connect('/{:version}/{:controller}/{:action}{:args}', array(
'controller'=> '\app\controllers\{:version}\{:controller}Controller',
), array());
Then I tried overriding the path in the libraries bootstrap module by doing something like:
if( preg_match('/^\/(v[0-9\.]+)/', $_SERVER['REQUEST_URI'], $match) ) {
Libraries::paths(array(
'controllers' => "controllers\\".$match[1].'\\{:name}Controller',
'models' => "models\\".$match[1]."\\{:name}",
));
}
I spent about a half a day at work searching google and the very sparse lithium docs. I am not sure what release of Lithium we are using as I have stepped into this pre-existing code base.
Thanks for any tips you may have!
In your routes.php file, you should re-configure the Dispatcher default rules with
Dispatcher::config(array('rules' => array(
'v1' => array('controller' => 'app\controllers\v1\{:controller}Controller')
)));
and a continuation route to match /v1/... requests
Router::connect('/v1/{:args}', array('v1' => true), array(
'continue' => true, 'persist' => array('controller', 'v1')
));
You can easily use :version instead of a predefined version number if you need so.

how to route always to www.mydomain.com/ cakephp

I want to clear everything from my url and just leave www.mydomain.com/... no profiles no controller no action no ids no vars in the url...
is that posible?
Router::connect('/', array('controller' => 'something', 'action' => 'here', 123, 'some' => 'named_params'));
nothing wrong with doing that. its not a hack, and its 100% reliable. and no, you dont need to do it with htaccess

Resources