ZF2 Route with Colon Separator - zend-framework2

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.

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

How to handle GET params within urlManager's rule in Yii?

I pass a query string to SearchController::actionDefault in form of GET parameter q:
/search/?q=...
However I need to define a rule that would automatically initialize this parameter with some value or define another param.
If I'll request mysite.com/showall I need get the same content like in /search/?q=*
This is what I've tried:
'/showall' => '/search/default/index/?r=*',
I solved this!
there is possible to set defaultParams in urlManager, and finaly it looks like in application config file:
...
'components' => array(
...
'urlManager' => array(
...
'rules' => array(
....
'/show_all' => array( '/search/default/index', 'defaultParams' => array('show_all'=>'-') ),
....
),
...
),
...
),
The accepted answer also works when you are getting different requests and you need to map it to the same GET param.
For example I want all of these requests:
user/pics
user/photos
user/pictures
to actually generate: user/index?content=photos.
This might be one of a way to go:
'<controller:user>/(<content:photos>|pics|pictures)' => array('<controller>/index', 'defaultParams'=>array('content'=>'photos')),

How to hide everything(id) in the URL in the browser except the site name and controller name in yii?

How to hide/encrypt everything(id) in the URL in the browser except the site name and controller name?
I think UrlManager can do it, but I don't know how ? need url mapping similar in ROR
my url manager code
'urlManager'=>array(
//'urlFormat'=>'path',
'showScriptName'=> false,
'rules'=>array(
'<controller:\w+>/<id:\d+>'=>'<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
),
),
I like to add a random number between every action(for secure my urls)
ROR eg:
map.connect 'by/:develop_name',
:controller => 'developer',
:action => 'builder_projects'
Please explain step by step.
couple if links I found relate to this
LINK1
LINk2
You just need to specify your application routes appropriately. Before continuing, you should read the URL management chapter of the Yii guide.
What you want to do is use named parameters in your rules, which means that the rule definition would look like this:
'by/<id:\w+>' => 'developer/builder_projects'
This rule takes a URL of the form http://site.com/index.php/by/42 and routes it to the controller developer, action builder_projects with the parameter id equal to whatever 42 (this is what the regular expression \w+ matches).
Routes are specified in your application configuration file as parameters to the urlManager component:
'urlManager' => array(
'urlFormat' => 'path',
'rules' => array(
'by/<id:\w+>' => 'developer/builder_projects'
// more rules
),
),
What you could do is define a helper function which symmetrically encrypts/decrypts:
class Helper {
public static function myCrypt($data, $decrypt = false){
//Logic to encrypt/decrypt
return $result;
}
}
and then when you create urls you can do:
$this->createUrl("myRoute", array("secret_id" => Helper::myCrypt($secret_id)));
and then in the controller action this resolves to you can do this:
public function actionMyRoute($secret_id){
$secret_id = Helper::myCrypt($secret_id, true);
//Do what you need to do with the decrypted id
}
Just make sure your encryption method returns a url safe string.

rewriting old-school query strings to modern cakephp URLs

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!

Resources