Zend Router chaining problem with subdomain - zend-framework

I have a $siteRoute for subdomains:
$siteRoute = new Zend_Controller_Router_Route_Hostname(
':siteSlug.test.com',
array(
'module' => 'site',
),
array('siteSlug' => '^(programming|photography|gaming)$')
);
$router->addRoute('site', $siteRoute);
and i have $questionRoute for questions' fancy
$questionRoute = new Zend_Controller_Router_Route(
'questions/:questionId/:questionSlug',
array(
'controller' => 'question',
'action' => 'view',
'questionSlug' => ''
)
);
$router->addRoute('question', $siteRoute->chain($questionRoute));
all these two routes are matching without any problems. for example:
programming.test.com matches and dispatches for site route and programming.test.com/questions/132/test-headline matches for question route.
But when i assemble a new url with Zend_View's url helper or Zend_Router's assemble function for question route, it returns just the path, not domain like:
echo $questionRoute->assemble(array('questionId' => 1, 'questionSlug' => 'testing-testing', 'siteSlug' => 'programming'));
echoes questions/1/testing-testing not programming.test.com/questions/1/testing-testing.
How can i do this?

Try this piece of code, works fine for me (if u need more example tell me)
$router = Zend_Controller_Front::getInstance()->getRouter();
echo $router->assemble(array('questionId' => 1, 'questionSlug' => 'testing-testing', 'siteSlug' => 'programming'), 'question');

The router is only concerned about routing the path, i.e. take the path and match it to your modules, controllers and actions. It has basically no awareness of the domain. Assemble only creates the route (path) based on your arguments.
echo $_SERVER['HTTP_HOST'] . '/' . $questionRoute->assemble(...);

Related

Route sudmains controller with Zend

I have the following structure on my app:
Modules =>
default => site.com
blog => blog.site.com
admin => admin.site.com
I used this code on my bootstrap to allow subdomains and redirect to the follow module:
$pathRoute = new Zend_Controller_Router_Route(':controller/:action/*', array('controller' => 'index', 'action' => 'index'));
$frontController = Zend_Controller_Front::getInstance();
$router = $frontController->getRouter();
$blogDomainRoute = new Zend_Controller_Router_Route_Hostname(
'blog.site.com', array(
'module' => 'blog',
'controller' => 'index',
'action' => 'index'
));
$router->addRoute('blogdomain', $blogDomainRoute->chain($pathRoute));
And the same code to adminDomainRoute.
It works fine! But now i notice that my pagination route don't work, i have the follow route to manage pages in admin module:
routes.usuarios.route = /usuarios/pagina/:pagina
routes.usuarios.defaults.module = admin
routes.usuarios.defaults.controller = usuarios
routes.usuarios.defaults.action = index
routes.usuarios.defaults.pagina = 1
I tried to change the route to
routes.usuarios.route = admin.site.com/usuarios/pagina/:pagina
But i still got action no found:
array (
'controller' => 'usuarios',
'action' => 'pagina',
'module' => 'admin',
)
How can i route admin.site.com/usuarios/pagina/1 admin.site.com/usuarios/pagina/3 ?
The thing that jumps at me from your setup is, that in the ini format (your current admin route), you are using the default router. Well this router knows nothing about the hostname you are on, so it is looking for an url like this one:
site.com/admin.site.com/usuarios/pagina/1 admin.site.com/usuarios/pagina/3
What you want is something like this:
//Create a hostname route. This route is only concerned with the subdomain part of the uri
$hostnameRoute = new Zend_Controller_Router_Route_Hostname(
'admin.:host.:domain');
//Create a default router that would take care of the rest of the routing.
$defaultRoute = new Zend_Controller_Router_Route(
'/usuarios/pagina/:pagina',
array(
'module'=>'admin',
'controller'=>'usuarios',
'action'=>'index'
)
);
//Chain those two routes together to make them go one after the other.
$defaultRoute=$hostnameRoute->chain($defaultRoute);
This code may need a bit of tweaking, but I think this should do what you need.

Zend routes two routes need same count of params

I don´t know what I do wrong. I got two named Zend route:
$route = new Zend_Controller_Router_Route(
'catalog/:categoryIdent/:productIdent/',
array(
'action' => 'viewproduct',
'controller' => 'catalog',
'module' => 'eshop',
'categoryIdent' => '',
'productIdent' => ''
),
array(
'categoryIdent' => '[a-zA-Z-_0-9]+',
'productIdent' => '[a-zA-Z-_0-9]+'
)
);
$router->addRoute('catalog_category_product', $route);
// catalog category route
$route = new Zend_Controller_Router_Route(
'catalog/:categoryIdent/:page/',
array(
'action' => 'viewcategory',
'controller' => 'category',
'module' => 'eshop',
'categoryIdent' => '',
'page' => ''
),
array(
'categoryIdent' => '[a-zA-Z-_0-9]+'
)
);
$router->addRoute('catalog_category', $route);
When I call catalog_category its all fine but when I try call to catalog_category_product is used viewcategory action from second route. It means its problem with :page variable in url, resp. same count of arguments in URL? I think that itsn´t nessesary I would like to get two different but similar routes - for example:
For category - catalog/category1/1
For product - catalog/category1/product1 (without number of page)
when I change form of route catalog_category_product to catalog/:categoryIdent/something/:productIdent/ so its working
here is route calls
$this->url(array('categoryIdent' => categoryIdent, 'productIdent' => productIdent), 'catalog_category_product', true);
$this->url(array('categoryIdent' => 'cerveny-cedr', 'page' => 'pageNumber'), 'catalog_category', true);
Thanks for any help
Keep in mind that routes are checked in reverse order, so the ZF router will check the catalog_category route before the catalog_category_product route when matching URLs. So, the number of arguments is not a problem, but since you've not put any sort of restriction on the 'page' parameter, all URLs that would normally match your catalog_category_product URL will be matched by catalog_category instead.
It sounds like 'page' should be numeric, so adding that restriction to your second route should fix the problem.

Zend Controller Router : Define variables to point to a different action in one controller

I'm just new with Zend and I have a little trouble with Zend Routers. I've searched about it, but nothing found...
I want to be able to define a router for each defined variable at uri level to point to a different action in one controller.
I'm working with lang and modules so I defined at bootstrap application the next initRoutes function:
protected function _initRoutes()
{
$front = Zend_Controller_Front::getInstance();
$router = $front->getRouter();
$defaultRoute = new Zend_Controller_Router_Route(
':lang/:module/:controller/:action',
array(
'lang' => 'es',
'module' => 'default',
'controller' => 'index',
'action' => 'index'
),
array(
'lang' => '^(en|es)$',
'module' => '^(default|admin)$'
)
);
$router->addRoute('defaultRoute', $defaultRoute);
return $router;
}
I want to be able to access forum sections and forum topics by their defined action.
Something like :
mydomain/forum -> forum/index
mydomain/forum/section -> forum/sectionAction
mydomain/forum/section/topic -> forum/topicAction
and also with the lang and module defined at uri level like :
mydomain/lang/module/forum
mydomain/lang/module/forum/section
mydomain/lang/module/forum/section/topic
So I have this :
class ForumController extends Zend_Controller_Action
{
public function indexAction()
{
}
public function sectionAction()
{
}
public function topicAction()
{
}
Then I created the next routes inside the Default_Bootstrap :
$forumRoutes = new Zend_Controller_Router_Route(
':lang/:module/forum',
array(
'lang' => 'es',
'module' => 'default',
'controller' => 'forum',
'action' => 'index'
)
);
$sectionRoutes = new Zend_Controller_Router_Route(
':lang/:module/forum/:section',
array(
'lang' => 'es',
'module' => 'default',
'controller' => 'forum',
'action' => 'section',
'section' => ''
)
);
$topic = new Zend_Controller_Router_Route(
':lang/:module/forum/:section/:topic',
array(
'lang' => 'es',
'module' => 'default',
'controller' => 'forum',
'action' => 'topic',
'section' => '',
'topic' => ''
)
);
$router->addRoute('forumTopics', $topic);
$router->addRoute('forumSections', $section);
$router->addRoute('forum', $forumRoutes);
Now, this only works if I define the lang and module at uri level, but doesn't work if I defined like => mydomain/forum/section | section/topic. This also brings me another problem with my navigation->menu. If I define "forum" as a static variable at router definition, when I hover over at any label defined at navigatoin.xml, the uri level have the same value for every one of them.
I've tried to make a chain like this:
$forumRoutes = new Zend_Controller_Router_Route(
':lang/:module/forum',
array(
'lang' => 'es',
'module' => 'default',
'controller' => 'forum',
'action' => 'index'
)
);
$section = new Zend_Controller_Router_Route(
':section',
array(
'action' => 'section',
'section' => ''
)
)
$topic = new Zend_Controller_Router_Route(
':topic',
array(
'action' => 'topic',
'topic' => ''
)
)
$chainedRoute = new Zend_Controller_Router_Route_Chain();
$chainedRoute->chain($topic)
->chain($section)
->chain($forumRoutes);
$router->addRoute($chainedRoute);
But this doesn't work as I expected.
Any help would be appreciated, thanks.
You are new to Zend. You said it. So here are some explanations:
Ideally the URL on Zend application is:
example.com/controller/action/param-name/:param-value
So in which case, if there is an action called Edit under UsersController, it will be:
example.com/users/edit
if action is add, it will be :
example.com/users/add
when you specify first parameter as a variable, it will collide with controller requests. Example: if you say controller is User but first parameter accepts a value and puts it in emplyees then a request as example.com/employees and example.com/user will both point towards employees controller even if the usercontroller exists! which again is a theory!
What you might want to do is, leave the routes to only accept dynamic values rather routing! You do not want users to route your application but, route user to different sections of the application.
About language then you need to use Zend_Locale which will check for HTML language that is
<html lang="nl"> or <html lang = "en">
Hope things are clear! :)
Here's a quick example which should help you work with routes like that in ZF.
If you are using a default project structure like the one you get when starting a new project using Zend Tool go into the Application folder.
In your Bootstrap.php set up something like this:
protected function _initRouteBind() {
// get the front controller and get the router
$front = Zend_Controller_Front::getInstance();
$router = $front->getRouter();
// add each custom route like this giving them a descriptive name
$router->addRoute(
'addTheDescriptiveRouteNameHere',
new Zend_Controller_Router_Route(
'/:controller/:id/:action/:somevar',
array(
'module' => 'default',
'controller' => ':controller',
'action' => ':action',
'id' => ':id',
'somevar' => ':somevar'
)
)
);
}
My example above is just to illustrate how you would use a route where the controller, the action and a couple of parameters are set in the url.
The controller and action should be resolved without any additional work however to get the 'id' or 'somevar' value you can do this in your controller:
public function yourAction()
{
// How you get the parameters to pass in to a function
$id = $this->getRequest()->getParam('id');
$somevar = $this->getRequest()->getParam('somevar');
// Using the parameters
$dataYouWant = $this->yourAmazingMethod($id);
$somethingElse = $this->yourOtherAmazingMethod($somevar);
// Assign results to the view
$this->view->data = $dataYouWant;
$this->view->something = $somethingElse;
}
So while you will want to make sure your methods handle the parameters being passed in with care (after all it is user supplied info) this is the principle behind making use of the route parameter binding. You can of course do things like '/site' as the route and have it direct to a CMS module or controller, then another for '/site/:id' where 'id' is a page identifier.
Also just to say a nice alternative to:
$id = $this->getRequest()->getParam('id');
$somevar = $this->getRequest()->getParam('somevar');
which wasn't that nice itself anyway since it was assuming a parameter was going to be passed, using shorthand conditional statement in conjunction with action helpers is:
$id = ($this->_hasParam('id')) ? $this->_getParam('id') : null;
$somevar = ($this->_hasParam('somevar')) ? $this->_getParam('somevar') : null;
If you are not familiar with this, the
($this->_hasParam('id'))
is the conditional test which if true assigns the value of whatever is on the left of the ':' and which if false assigns the value of whatever is on the right of the ':'.
So if true the value assigned would be
$this->_getParam('id')
and null if false.
Does that help? :-D

Zend Framework: Route assemble and GET parameters

In my Bootstrap I have
$route = new Zend_Controller_Router_Route(
':language/:country/:controller/:action/*',
array(
'language' => 'en',
'country' => 'us',
'controller' => 'bicycle',
'action' => 'index'
),
array(
'language' => '[a-z][a-z]',
'country' => '[a-z][a-z]'
)
);
Somewhere in my view I have
echo $this->url(array('page'=>2));
//actually this translated to $route->assemble(array('page' => 2), null, false);
The problem, is when I have some GET parameters: they won't be considered in the building of the link, and this is what I actually want.
Example:
I access the URL (in the browser)
http://localhost/myproject/en/us/controller/action/?get1=gval1&get2=gval2&get3=gval3
and the assembled URL is
http://localhost/myproject/en/us/controller/action/page/2
INSTEAD of
http://localhost/myproject/en/us/controller/action/page/2/get1/gval1/get2/gval2/get3/gval3/
or (I would prefer the next one)
http://localhost/myproject/en/us/controller/action/page/2/?get1=gval1&get2=gval2&get3=gval3
Any ideas?
Of course one solution (with Apache) would be to call this in my view:
$this->url(array(page=>2)) . ($_SERVER['QUERY_STRING']?$_SERVER['QUERY_STRING']:"")
but you cannot be sure this will always be included in the $_SERVER variable.

Zend Framework Router Getting /module/VALUE/controller/action

I've been googling around and I can't seem to find anything which explains the use of ZF router well. I've read the documentation on the site, which seems to only talk about re-routing.
I am trying to make the format:
/module/value/controller/action give /module/controller/action passing on value as a parameter
e.g.
/store/johnsmithbigsale/home/newstuff would route to /store/home/newstuff passing on johnsmithbigsale as the value to a parameter with a hidden namespace e.g. storeName.
Some help would be greatful!
You can use Zend_Controller_Router_Route to map your url parts to modules, controllers, actions, and parameters that can be used in the controller by $this->_getParam('varName'). You can define these routes in the application.ini file or in the application bootstrap.
// custom city route
$route = new Zend_Controller_Router_Route(
'cities/:city',
array(
'controller' => 'city',
'action' => 'view'
)
);
$this->addRoute('city', $route);
// custom buy widgets route
$route = new Zend_Controller_Router_Route_Regex(
'buy_(.+)_widgets/([0-9]+)(.*)',
array(
'controller' => 'widgets',
'action' => 'view'
),
array(
1 => 'nothing',
2 => 'widget_id',
3 => 'vars'
)
);
$this->addRoute('widgets', $route);
The regex route is kind of specific to my app, but you can see that each match can get mapped to a parameter.