Kohana routing. ID that can contain letters but must end with digit - php

I want this routes to work
forum/forum-name.9 -> controller = forum, action = index, id = forum-name.9
forum/forum-name.9/edit -> controller = forum, action = edit, id = forum-name.9
forum/rules -> controller = forum, action = rules, id = null
I tried
Route::set('default', '(/<controller>)((/<id>)(/<action>)))',
array(
'controller' => '[a-zA-Z_-]+',
'action' => '[a-zA-Z_-]+',
'id' => '[a-zA-Zа-я0-9.-]+',
))
->defaults(array(
'controller' => 'forum',
'action' => 'index',
'id'=>null
));
But its wrong, because id now can contain only letter

Routes should be specific. Do NOT try to sole everything using one route. These will do what you want.
Route::set('forum/rules', 'forum/rules')
->defaults(array(
'controller' => 'forum',
'action' => 'rules',
));
Route::set('forum', 'forum/(<name>.)<id>(/<action>)',
array(
'action' => 'edit', // the action must not be present (and default to 'index') or be 'edit'
'name' => '\w+',
'id' => '\d+',
))
->defaults(array(
'controller' => 'forum',
));
Also, only add - to the regex for actions and controllers if you overload something and have it replaced. PHP class and function/method names are not allowed to contain a dash.

This solved my problem
'id' => '(\w+.)?\d+'

Related

Kohana more than one dynamic routing for specific urls

I don't know if someone else is using kohana (koseven with new name) framework for develepment. I need help about routing. I am migrating an asp site to php with using koseven ( kohana) framework and I must keep all the url routing on current site. Because of this I must use more than one routing on my project.
Url structer must be like this:
domain.com/contenttype/contentid -> contenttype is dynamic and gets data over Content Controller
domain.com/profile/username ->profile is the controller and index is the action. I must get the user name from id parameter.
domain.com/categories/categorname (Works fine-> categories is the controller, index is the action and categorname is the id parameter.
There is an admin page on my site and using a directory route on it.
Here is my route on bootstrap.php file:
Route::set('panel', '<directory>(/<controller>(/<action>(/<id>)))', array('directory' => 'panel'))
->defaults(array(
'controller' => 'panel',
'action' => 'index',
));
Route::set('kategori','<kategori>(/<id>)', array('id'=>'.*'))
->defaults([
'controller'=>'kategori',
'action'=>'index',
]);
Route::set('default', '(<controller>(/<action>(/<id>)))', array('id'=>'.*'))
->defaults([
'controller' => 'anasayfa',
'action' => 'index',
]);
First Problem: If I copy kategori route for profile it uses kategori route instead of profile.
Second Problem: How can I get dynamic routing for the contenttype. Content controller is the default controller and it will list the contents under the dynamic contenttype if there isn't given any content title on the id parameter. If the id parameter is identified at this time it will Show the detail of content.
Thanks.
Route::set('panel', 'panel(/<controller>(/<action>(/<id>)))', ['controller' => '\w+', 'action' => '\w+', 'id' => '[-\w]+'])
->defaults(array(
'directory' => 'panel',
'controller' => 'dashboard',
'action' => 'index',
'id' => null,
));
Route::set('kategori','<kategori>(/<id>)', ['kategori' => '[-\w]+', 'id' => '[-\w]+'])
->defaults([
'controller' => 'kategori',
'action' => 'index',
'id' => null,
])
->filter(function ($route, $params, $request) {
$model = ORM::factory('Kategori', ['kategori' => $params['kategori'], 'id' => $params['id']]);
if ($model->loaded()) {
$params['model'] = $model;
return $params;
}
return false;
});
Route::set('default', '(<controller>(/<action>(/<id>)))', ['controller' => '\w+', 'action' => '\w+', 'id' => '[-\w]+'])
->defaults([
'controller' => 'anasayfa',
'action' => 'index',
'id' => null,
]);

Router cakephp pointing to same action

I am facing some problems in routing under cakephp
there are two actions in my controller
they are as below:
example.com/posts/show/show-by-day
example.com/posts/view/slug-post
I want them as:
example.com/article/show-by-day.html
example.com/article/slug-post.html
So i routes file under config file I wrote as:
Router::connect('/article/:show_by_day', array('controller' => 'posts', 'action' => 'show'), array('pass' => array('show_by_day')));
Router::connect('/article/:slug', array('controller' => 'posts', 'action' => 'view'), array('pass' => array('slug')));
its working fine when I hit the url example.com/article/show-by-day.html
but when I hit url example.com/article/slug-post.html , its again point to action show.
So how can I solve it?
Many thanks!
try this
Router::connect( '/article/show-by-day.html',
array(
'controller' => 'posts',
'action' => 'show'
),
array(
'pass' => array('show_by_day')
)
);
Router::connect( '/article/slug-post.html',
array(
'controller' => 'posts',
'action' => 'view'
),
array(
'pass' => array('slug')
)
);
Explanation:
The first parameter of the Router::connect is the exact URL you want to match - in the original code, a : was included - which parameterized the URL instead of using exact match. The second and third paramters in Router::connect are the actual controller / action that need to be invoked along with required parameters.

CakePHP Routes - Generate appropiate links for /:controller/:id/ with html helper

I have this route set up, and manually entering the url works:
Router::connect('/:controller/:id/*',
array('action' => 'view'),
array('pass'=>array('id'), 'id' => '[0-9]+'));
However, with html->link, I can't generate a link without the action.
$this->Html->link('linkName', array(
'controller' => 'controllerName',
'action' => 'view',
$id, $slug));
generates controllerName/view/id
$this->Html->link('linkName', array(
'controller' => 'controllerName',
$id, $slug));
generates controllerName/index/id
How can I generate the url controller/id with html helper?
Thanks!
CakePHP needs specificity. Here, I had to specify the action and the id, then cake matched these attributes to the correct route and generated the correct url:
$this->Html->link('linkName', array(
'controller' => 'controllerName',
'action' => 'view',
'id' => $id,
$slug
));

CakePHP route with regex

I have a controller setup to accept two vars: /clients/view/var1/var2
And I want to show it as /var1/var2
SO i tried
Router::connect('/*', array('admin'=>false, 'controller' => 'clients', 'action' => 'view'));
But this stops all other controllers working as /* routes everything
All other pages that are on the site are within the admin prefix so basically i need a route that is ignored if the current prefix is admin! I tried this (regex is from Regular expression to match a line that doesn't contain a word?):
Router::connect('/:one', array('admin'=>false, 'controller' => 'clients', 'action' => 'view'), array(
'one' => '^((?!admin).*)$'
));
But I think the regex is incorrect because if i naviate to /test it asks for the tests controller, not clients
My only other routes are:
Router::connect('/admin', array('admin'=>true, 'controller' => 'clients', 'action' => 'index'));
Router::connect('/', array('admin'=>false, 'controller' => 'users', 'action' => 'login'));
What am I doing wrong? Thanks.
I misunderstood your question the first time. I tested your code and didn't get the expected result either. The reason might be that the regex parser doesn't support negative lookahead assertion. But I still think you can solve this with reordering the routes:
The CakeBook describes which routes are automatically generated if you use prefix routing. In your case these routes have to be assigned manually before the '/*'-route to catch all admin actions. Here is the code that worked for me:
// the previously defined routes
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
Router::connect('/admin', array('controller' => 'clients', 'action' => 'index', 'admin' => true));
// prefix routing default routes with admin prefix
Router::connect("/admin/:controller", array('action' => 'index', 'prefix' => 'admin', 'admin' => true));
Router::connect("/admin/:controller/:action/*", array('prefix' => 'admin', 'admin' => true));
// the 'handle all the rest' route, without regex
Router::connect(
'/*',
array('admin'=>false, 'controller' => 'clients', 'action' => 'view'),
array()
);
Now I get all my admin controller actions with the admin prefix and /test1/test2 gets redirected to the client controller.
I think the solution is described in the bakery article on routing - "Passing parameters to the action" (code not tested):
Router::connect(
'/clients/view/:var1/:var2/*',
array(
'controller' => 'clients',
'action' => 'view'
),
array(
'pass' => array(
'var1',
'var2'
)
)
);
The controller action would look like:
public function view($var1 = null, $var2 = null) {
// do controller stuff
}
Also you have too look at the order of your routes (read section "The order of the routes matters"). In your example the '/*' stops all other routes if it comes first, if you assign the rule after the others it handles only requests which didn't match any other route.

Zend_Controller_Router_Route

I'm trying to make a Router that can respond to this structure:
module/controller/action/id and module/controller/action/page
The only difference is is 'id' or 'page'. I'm using this code:
$routeAdmin = new Zend_Controller_Router_Route(
'administrador/:controller/:action/:id/:pg',
array(
'module' => 'administrador',
'controller' => 'index',
'action' => 'index',
'id' => 0,
'pg' => 1
),
array(
'id' => '\d+',
'pg' => '\d+'
)
);
$router->addRoute('administrador', $routeAdmin);
The problem is that in some situations i want:
'http://www.domain.cl/administrador/productos/2' => (module=>administrador, controller=>productos,page=>2) but with the router 'administrador' result in 'http://www.domain.cl/administrador/productos/index/0/2' (module=>administrador, controller=>productos,action=>index,id=>0,page=>2)
I'm very confused about how it works for cases like this. I tried to make two router where the first only have 'id' param and the other 'page' param. And from url helper use it like:
$this->url(array('module' => 'administrador', 'controller' => 'productos', 'action' => 'index', 'id' => 0), 'administradorId');
$this->url(array('module' => 'administrador', 'controller' => 'productos', 'action' => 'index', 'page' => 1), 'administradorPg');
But when I used the routers always select the last one added to the router ($router->addRoute('routerIdentifier', $route);)
Thanks
I have had a similar issue and I got around this by defining just one route like this
$routeAdmin = new Zend_Controller_Router_Route(
'administrador/:controller/:action/:id/:pg',
array(
'module' => 'administrador',
'controller' => 'index',
'action' => 'index',
'id' => 0
),
array(
'id' => '\d+'
)
);
$router->addRoute('administrador', $routeAdmin);
In your actions you'd then need to get the id and check for it somewhere where that id might be, for example if you were in /administrador/events/view/1 then you might look in the events table or if you were in /administrador/pages/view/1 then you would look for a page.
But the problems really start when the id could be either an event or a page in a given controller and action. The only real way around this is explicitly set the type of id your using for example
/administrador/events/view/index/id/1
or
/administrador/pages/view/index/page/1
If you want to remove the index part then set up routes like
$routeAdmin = new Zend_Controller_Router_Route(
// Remove the action from here and explicitly set the controller
'administrador/pages/:pg',
array(
'module' => 'administrador',
'controller' => 'pages',
// Then set the default action here
'action' => 'index',
'pg' => 0
),
array(
'pg' => '\d+'
)
);
$router->addRoute('administradorpages', $routeAdmin);
What your asking for basically results in a lot of guess work and therefore risk of producing unexpected results.
Have a look at dynamic segments in routes. It is not exactly what you want, but it might be helpful in your case.

Categories