Phalcon URL assembly - how to supply parameters - php

I have the following Phalcon route:
$router->add('/:controller/:action/:params', [
'module' => 'secured',
'controller' => 1,
'action' => 2,
'params' => 3,
'namespace' => 'My\Namespace\Controllers'
])->setName('main');
I am trying to assemble URL for that route, which should look like this:
/user/register/admin/john
Where, "user" is controller name, "register" is action and there are two params: [0] = 'admin', [1] = 'john'.
I am assembling it as follows:
$url = $this->di['url']->get([
'for' => 'main',
'controller' => 'user',
'action' => 'regiser',
'params' => [
'admin',
'john'
]
]);
However, parameters are not in the $url:
/user/register
How can I make :params go into final URL?
Thanks!

I cannot check this right now, but does:
array(
'for' => 'main',
'controller' => 'user',
'action' => 'regiser',
'admin'
'john'
);
works as you wish?

I found the only way how to do this. Do it myself:
$this->url->get(array(
'for' => 'main',
'controller' => 'user',
'action' => 'register',
'params' => implode("/", array('admin', 'john'))
));

Related

Phalcon two single routes

I have a problem. I have two routes:
$router->add('/news/{alias:[a-z\-]+}(/?)', array(
'module' => 'frontend',
'controller' => 'news',
'action' => 'view',
'news_id' => 1,
'lang' => 'md',
))->setName('news_view_short_e'); //=> /news/282334-alias-news
AND route => /news/index/:
$router->add('/{lang:[' . $langsDefined . ']{2}+}/{controller:[a-z]{3,50}+}(/?)', array(
'module' => 'frontend',
'controller' => 2,
'action' => 'index',
'lang' => 1,
))->setName('default_module_lang');
When I use these routes. site.com/news/index not working. But if I remove route with alias. Route site.com/news/index working good. How I can resolve conflict?
Probably because it matches your "index" as alias parameter too, so first rule wins. There's no magic solution other than just fixing your regex or reordering your routes.
Reversing your routes order will bring a new problem though, reversely because it will also match the controller instead of your alias.
I prefer to stick with the default routing, and mount a router group here's my router right now:
//From my config
'router' => array(
'defaults' => array(
'namespace' => 'My\\Default\\Namespace\\Controllers',
'module' => 'frontend',
'controller' => 'index',
'action' => 'index'
),
'notFound' => array(
'controller' => 'errors',
'action' => 'notFound'
)
),
// From my service
$router = new Router();
$router->removeExtraSlashes(true);
$router->setDefaults($this->config->router->defaults->toArray()?: $this->defaults);
$router->notFound($this->config->router->notFound->toArray()?: $this->notFound);
$router->mount(new ModuleRoute($this->getDefaults(), true));
class ModuleRoute extends RouterGroup
{
public $default = false;
public function __construct($paths = null, $default = false)
{
$this->default = $default;
parent::__construct($paths);
}
public function initialize()
{
$path = $this->getPaths();
$routeKey = '/' . $path['module'];
$this->setPrefix('/{locale:([a-z]{2,3}([\_\-][[:alnum:]]{1,8})?)}' . ($this->default ? null : $routeKey));
$this->add( '/:params', array(
'namespace' => $path['namespace'],
'module' => $path['module'],
'controller' => $path['controller'],
'action' => $path['action'],
'params' => 3
))->setName($routeKey);
$this->add( '/:controller/:params', array(
'namespace' => $path['namespace'],
'module' => $path['module'],
'controller' => 3,
'action' => $path['action'],
'params' => 4
))->setName($routeKey);
$this->add( '/:controller/([a-zA-Z0-9\_\-]+)/:params', array(
'namespace' => $path['namespace'],
'module' => $path['module'],
'controller' => 3,
'action' => 4,
'params' => 5
))->setName($routeKey);
$this->add( '/:controller/:int', array(
'namespace' => $path['namespace'],
'module' => $path['module'],
'controller' => 3,
'id' => 4,
))->setName($routeKey);
}
}

Using Router Annotations with other routes in Phalcon

Is it possible to use annotations on top of regular routes in Phalcon. For example, I have this:
$router->add('/', [
'module' => 'home',
'controller' => 'index',
'action' => 'index'
])->setName('home');
$router->notFound([
'module' => 'home',
'namespace' => 'Home\Controller',
'controller' => 'error',
'action' => 'show404'
]);
foreach ($app->getModules() as $key => $module) {
$router->add('/'.$key.'/:params', [
'module' => $key,
'controller' => 'index',
'action' => 'index',
'params' => 1
])->setName($key);
$router->add('/'.$key.'/:controller/:params', [
'module' => $key,
'controller' => 1,
'action' => 'index',
'params' => 2
]);
$router->add('/'.$key.'/:controller/:action/:params', [
'module' => $key,
'controller' => 1,
'action' => 2,
'params' => 3
]);
}
$router->addModuleResource('api', 'Api\\Controller\\Index', '/api/index');
$router->addModuleResource('api', 'Api\\Controller\\Client', '/api/client');
The problem is that the router annotations that I define near the bottom don't seem to work, probably because the routes to /api/index and /api/client have already been defined above.
Also, at the same time, is there a way to define a notFound for a module? Basically, if I'm at some URL that starts with /api/, I would like it to go to an error page in my api module. Otherwise, it should go to error page in the regular module.

Using route in Zend Framework 2

i need to route urls like in zf1.
in particular i need that these urls will be automatically redirect to appropriate actions without specify a new route every time.
/site/getData
/site/getData?param=5&par2=test
/site/getOther
...
So a segment route doesn't work, i've tried a Literal route but i can't reach a working solutions.
Anyone can help me?
Thanks a lot
This should be solved by a pretty default segment route like the one provided in the documentation.
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/:controller[/:action]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]+',
'action' => '[a-zA-Z][a-zA-Z0-9_-]+',
),
'defaults' => array(
'controller' => 'default-controller-alias',
'action' => 'index',
),
)
Now if you set up your controller names like the following:
'controllers' => array(
'invokables' => array(
'sites' => 'Namespace\Controller\SitesController',
'other' => 'Namespace\Controller\OtherController'
Then you should be able to achieve exactly what you want. And to create params to your route, you simply use the ViewHelper correctly ;)
$this->url('routename',
array(
'controller' => 'site',
'action' => 'getData'
),
array (
'query' => array(
'param1' => 'foo',
'param2' => 'bar',
'paramN' => 'baz',
)
)
)

ZF: routing. How to make correct route?

I have several templates:
/admin/
/somecode1/somecode2/
/staticpage.htm
Trying to enter on /admin/. Doing follow:
$router->addRoutes(array(
'adminsys' => new Zend_Controller_Router_Route('/:module/:controller/:action/*', array('module' => 'admin', 'controller' => 'index', 'action' => 'index')),
'page_catalog' => new Zend_Controller_Router_Route('/:code/:page', array('module' => 'default', 'controller' => 'Staticcatalog', 'action' => 'index', 'code' => '', 'page' => '')),
'static' => new Zend_Controller_Router_Route_Regex('([\wА-Яа-я\-\_]+)\.(htm|html)', array('module' => 'default', 'controller' => 'static', 'action' => 'index')
));
also I tried to change 'adminsys' on :
'adminsys' => new Zend_Controller_Router_Route('/admin/:controller/:action/*', array('module' => 'admin', 'controller' => 'index', 'action' => 'index')),
or
'adminsys' => new Zend_Controller_Router_Route('/admin/*', array('module' => 'admin', 'controller' => 'index', 'action' => 'index')),
But all time it routes on 'page_catalog'.
If I comment it, I can enter /admin/. But not with 'page_catalog'.
What I'm doing wrong here?
When you define routes, you define the general one first, and then you go more and more specific after. The router takes your routes 'last one first' and stops on the first that matches.
This means that if '/admin' could also work for the 'page_catalog' route, it would use this one, before even trying to match 'adminsys' route. And that's the thing, '/admin' could be a 'page_catalog' url where :code param would be 'admin'.
The second variant of the adminsys route is a good one, you just have to make it the last one of your routes in order to avoid any more general route to match first :
$router->addRoutes(array(
'page_catalog' => new Zend_Controller_Router_Route('/:code/:page', array('module' => 'default', 'controller' => 'Staticcatalog', 'action' => 'index', 'code' => '', 'page' => '')),
'static' => new Zend_Controller_Router_Route_Regex('([\wА-Яа-я\-\_]+)\.(htm|html)', array('module' => 'default', 'controller' => 'static', 'action' => 'index')),
'adminsys' => new Zend_Controller_Router_Route('/admin/:controller/:action/*', array('module' => 'admin', 'controller' => 'index', 'action' => 'index'))
));

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