How to route multi subdomain with zend router hostname - zend-framework

I need to create routing in Zend to simply copy the current live site url structure which is sadly inconsistent
What i want to do is to route subdomain as follow:
www.site.com -> static router
a.site.com & b.site.com -> category controller
c.site.com & d.site.com -> location controller
the rest sub domain -> user controller
could anyone guide me how to solve this, thanks.
UPDATE:
First thanks Fge, vote your answer, it works but i need some more advice:
Since i have many subdomains for each rules is there a better way than add the rules in looping
foreach($subdomains as $a){
$tr = new Zend_Controller_Router_Route_Hostname(
"$a.site.com",
array(
'module' => 'mod',
'controller' => 'ctrl',
'param_1' => $a
));
$router->addRoute($a,$tr);
}
How to combine it with other routing type to parse the parameters (chained?), something like http://a.site.com/:b/:c, i want t parse it to param_1 (a), param_2 (b), param_2 (c)

Note: Reverse Matching
Routes are
matched in reverse order so make sure
your most generic routes are defined
first.
(Zend_Controller_Router)
Thus you have to define the route for all other subdomains first, then the specific ones:
$user = new Zend_Controller_Router_Route_Hostname(
':subdomain.site.com',
array(
'controller' => 'user'
)
);
$location1 = new Zend_Controller_Router_Route_Hostname(
'c.site.com',
array(
'controller' => 'location'
)
);
$location1 = new Zend_Controller_Router_Route_Hostname(
'd.site.com',
array(
'controller' => 'location'
)
);
// other definitions with known subdomain
$router->addRoute($user); // most general one added first
$router->addRoute($location1);
$router->addRoute($location2);
// add all other subdomains
Update for the updated question:
1) This really depends on how different the parameters are you want to route a subdomain to. In your example you routed them all to the same model and controller and added the actual subdomain as a parameter. This can be done easily with the user-route i posted above. There the subdomain is set as parameter subdomain ($request->getParam("subdomain")). If you want the subdomains to be the action of a known controller/model you could replace :subdomain with :action. But as soon as you have other controllers/models for each subdomain, I'm affraid you have to loop over them (or use a config file). For the example you provided in the question, the route simply could look like this:
$user = new Zend_Controller_Router_Route_Hostname(
':param1.site.com',
array(
'controller' => 'user'
)
);
// routes "subdomain".site.com to defaultModul/userController/indexAction with additional parameter param1 => subdomain.
As long as you don't have any schema in your subdomains it's very difficult to route them in a general way.
2) That's an example where router chains come into play. The outer route would be the hostname route which handles the subdomain and the inner route would handle the :a/:b part. This could look like this for example:
$user->chain(new Zend_Controller_Router_Route(':a/:b'));

Related

How to get the variables in routing in zend framework 1.12

I am new to routing in zf. I don't understand some terms in route
$route = new Zend_Controller_Router_Route(
'author/:username',
array(
'controller' => 'profile',
'action' => 'userinfo'
)
);
$router->addRoute('user', $route);
How do we get :username here? from where do we get this?
Username here is parameter pass by the user. So correct link using this route will be http://somepage.com/author/John. In your controller you can get this variable just like POST and GET variables - $this->getParam('author');
If you want to allow user use link without parameter (default parameter) you can add to array - 'author' => null (i usually use this in pagination)

how to make optional parametres in zendframework URL

I am new to Zend, but very very keen to learn. This is really just a quick question on routing in Zend Framework.
I understand the basic of it but I am still confused about how I can create some optional parameters at the end of my URL. For example, I have the following default page URL:
examplesite.com/accounts/enquiry
I now want to add two additional parameters to it i.e:
userid= 6
location= 12
So, the eventual URL should look like:
examplesite.com/accounts/enquiry/6/12
but
examplesite.com/accounts/enquiry
Will get you to the same page.
I am not clear. How do it do this? I mean, this is not a bespoke URL. so, I don't need to create a custom route. It basically just the last two parameters that need to be added to the page.
How do I do this?
First 2 parameters are controller and action name, the named params.
Here you are:
examplesite.com/accounts/enquiry/userid/6/location/12
or you can define your own route like this:
$route = new Zend_Controller_Router_Route('accounts/enquiry/:userid/:location);
and then add it to router:
$router->addRoute('accounts', $route);
You could add a custom route inside your Bootstrap.php, e.g. (untested):
protected function _initRoutes()
{
[...]
$frontController = Zend_Controller_Front::getInstance();
$router = $frontController->getRouter();
$accounts = new Zend_Controller_Router_Route(
'accounts/enquiry/:userid/:location',
array(
'userid' => '[0-9]{2}',
'location' => '[0-9]{2}',
'controller' => 'accounts',
'action' => 'enquiry',
)
);
$router->addRoute('accounts', $accounts);
[...]
}
http://framework.zend.com/manual/1.12/en/zend.controller.router.html

Zend Custom Route if no match found

I have a ZF app with several modules as this: ( as usual )
root\
\application\
\default
\items
\me
\controllers
\views
The application uses the default routing like /module/controller/action;
What I want is this: if no match has been found for the default Zend Routing (no action / controller / module has been found ) then route to a desired path with the url endpoint spitted into parameters.
For example:
mydomain.lh/me -> will match the module me, controller index, action index ( as default )
mydomain.lh/my_category_name -> will match the module items, controller index, action index, params: category => my_category_name -> using the desired path route
no my_category_name module exists to match against
I have tried with this, into bootstrap.php:
public function _initRoutes ()
{
$router = $this->_front->getRouter(); // returns a rewrite router by default
$router->addRoute(
'cat-item',
new Zend_Controller_Router_Route('/:category',
array(
'module' => 'items',
'controller' => 'index',
'action' => 'index'))
);
}
Witch points to the correct location ( I know because I var_dump -ed the request url into the items/index/index action and the expected url and parameters were there, but if I do not do var_dump(something);exit; into the action, a blank page is served.
no output is made but also no error is generated, the request status is 200 - OK
Can anybody have a suggestion ?
Thank you!

Hostname and Custom routing in Zend Framework don't work together for me

I am building an application that uses hostname routing to detect subdomains like
user1.example.com
user2.example.com
and also have custom routes like user1.example.com/login
This works well so far, however when I add custom routes they do not work. I have searched and read a lot but seems there is something I am missing. Here is what I have so far:
//my routes in routes.ini
[development]
routes.login.type = "Zend_Controller_Router_Route"
routes.login.route = "/login"
routes.login.defaults.controller = "user"
routes.login.defaults.action = "login"
//This part in Bootstrap file
$this->bootstrap('frontController');
$router = $this->frontController->getRouter();
$routerConfig = new Zend_Config_Ini(
APPLICATION_PATH . '/configs/routes.ini',
'production'
);
//I create a default route
$routeDefault = new Zend_Controller_Router_Route_Module(
array(),
$this->frontController->getDispatcher(),
$this->frontController->getRequest()
);
$router->addConfig($routerConfig, 'routes');
// hostname route
$hostnameRoute = new Zend_Controller_Router_Route_Hostname(
':username.mysite.com',
array(
'module' => 'default',
'controller' => 'index',
'action' => 'index',
)
);
//I add the default route.
$router->addRoute('default', $routeDefault);
//I chain the routes so that all routes have subdomain routing too
foreach ($router->getRoutes() as $key => $theroute) {
$router->addRoute($key, $hostnameRoute->chain($theroute));
}
When I go to a custom route like http://user1.example.com/login I get the error: 'Invalid controller specified (login)' which means my custom route is not being recognized. I am also not sure if the way I am adding the default route is correct and necessary. If I remove that code then it doesn't work. So my problem really is that I would like my hostname matching, custom routes and default routes to all work. If you can spot where I'm going wrong please help, I have read previous related posts all over on routes, chaining, default routes etc (including this very related one: How do I write Routing Chains for a Subdomain in Zend Framework in a routing INI file?) but haven't found the solution so far.
You should be able to setup your routing using a custom param in the route:
routes.testdynamicsubdomain.type = "Zend_Controller_Router_Route_Hostname"
routes.testdynamicsubdomain.route = ":subdomain.domain.dev"
routes.testdynamicsubdomain.defaults.module = public
routes.testdynamicsubdomain.defaults.controller = index
routes.testdynamicsubdomain.defaults.action = index
If your apache/hostfile etc are configured correctly going to test.domain.dev should load the index action in your indexController where you could get the :subdomain param:
echo $this->getRequest()->getParam('subdomain');
Also, as you discovered, the order of the routes is very important. See also Zend Router precedence for more info about this.

Zend View: Domain to Action

I am looking for a method in the bootstrap that looks at the URL then loads a specific module/controller/action.
However I don't want the user to see it.
Is this possible and easy?
I'm unsure wether you are looking for Hostname Routing, or just normal Routing, so I will answer both.
Zend_Controller_Router_Route
ie domain.com/users/layke
Using Zend_Controller_Route you can create a route will will grab "layke" and use that as a parameter. This would be a a standard Route.
$route = new Zend_Controller_Router_Route(
'users/:username',
array(
'controller' => 'profile',
'action' => 'users'
)
);
$router->addRoute('user', $route);
Then also there is hostname matching....
Zend_Controller_Router_Route_Hostname
For instance, (as the guides provide)...
You could use..
:username.domain.com to map to
/default/users/:username.
Zend_Controller_Router
$hostnameRoute = new Zend_Controller_Router_Route_Hostname(
':username.example.com',
array(
'controller' => 'profile',
'action' => 'users'
)
);
$plainPathRoute = new Zend_Controller_Router_Route_Static('');
$router->addRoute('user', $hostnameRoute->chain($plainPathRoute));
Examples Documentation : Zend_Controller_Router
Sounds like you're after hostname routes: http://framework.zend.com/manual/en/zend.controller.router.html#zend.controller.router.routes.hostname
You can use Routes in Zend (http://framework.zend.com/manual/en/zend.controller.router.html) and then mod_rewrite + .htacess for apache (http://httpd.apache.org/docs/current/mod/mod_rewrite.html) or the URL rewrite module in IIS (http://www.iis.net/download/URLRewrite)
These functions are "needed" for using Zend at all, as the URL mysite.com/demo1/demo2/ actually translates to something like mysite.com/index.php?controller=demo1?action=demo2