Force user to use language route - zend-framework

I am changing my application routes so that I can use subdirectories with gTLDs(example.com/de/) instead of URL params (example.com?loc=de). As It is in http://devzone.zend.com/1765/chaining-language-with-default-route/ , I used the following route configuration:
protected function _initRoutes() {
$locale = $this->getResource('locale');
// Create route with language id (lang)
$routeLang = new Zend_Controller_Router_Route(
':lang', array(
'lang' => $locale->getLanguage()
), array('lang' => '[a-z]{2}')
);
// Now get router from front controller
$front = Zend_Controller_Front::getInstance();
$router = $front->getRouter();
// Instantiate default module route
$routeDefault = new Zend_Controller_Router_Route_Module(
array(), $front->getDispatcher(), $front->getRequest()
);
// Chain it with language route
$routeLangDefault = $routeLang->chain($routeDefault);
// Add both language route chained with default route and
// plain language route
$router->addRoute('default', $routeLangDefault);
$router->addRoute('lang', $routeLang);
// Register plugin to handle language changes
$front->registerPlugin(new Sistema_Plugin_Language());
}
I am using baseUrl to whole website links.
However my old links(example.com/news/) returns an error saying "No route matched the request", How could I force the user or redirect the user to new URLs(example.com/en/news/)?

Related

How to set router for earch module in zend framework

I have 1 zend (v1) application, and 2 module : default + admin
I want when call default module will be set router in configs/router/default.ini
and if in module admin do not any thing
I tried using plugin but it doesn't work
in my plugin
class Australian_Controller_Plugin_DefaultRouter extends Zend_Controller_Plugin_Abstract {
public function routeShutdown(Zend_Controller_Request_Abstract $request) {
$currModule = $request->getModuleName();
if ($currModule != 'default') {
return;
}
$fontController = Zend_Controller_Front::getInstance();
$router1 = new Zend_Controller_Router_Rewrite();
$fontController->getRouter()->removeDefaultRoutes();
$myRoutes = new Zend_Config_Ini(APPLICATION_PATH . '/configs/router/default.ini', 'production');
$router1->addConfig($myRoutes, 'routes');
$fontController->setRouter($router1);
}
}
and /default/Bootstrap.php
protected function _initRoutes() {
$fontController = Zend_Controller_Front::getInstance();
$fontController->registerPlugin(new Australian_Controller_Plugin_DefaultRouter());
}
thanks
Note that you are adding new router after Routing so Zend already decoded address using old routes. This way you can generate URLs using new routes, but they will not e recognized by Zend. You need to call $router->route($request); again to set module/controller/action using new set of routes.
Sadly this is not working when its called in routeShutdown and has to be added to preDispatch(). Sadly I'm quite new to Zend too and still not grasping why it is so.
Code i used:
$fontController = Zend_Controller_Front::getInstance();
$router = $fontController->getRouter();
$r = new Zend_Controller_Router_Route(
'/testnew',
array(
'module' => 'user',
'controller' => 'index',
'action' => 'myaccount',
));
$router->addRoute('testnew', $r);
$router->route($request);

Have a default controller in Zend

I have a module-based arhitecture in Zend Framework 1.11 (site.com/module/controller/action).
I've setup my site to have a default module, so that if I have the site module as default, and you go to site.com/something1/something2, it will actually take you to site.com/site/something1/something2.
I want to achieve the same thing 1 level further: say if you go to site.com/something, it should take you to site.com/site/index/something. I'm not talking about a redirect, just a re-routing.
Would something like this be possible?
If I understand correctly, it is possible and here is an example you can put in your Bootstrap:
protected function _initControllerDefaults()
{
$this->bootstrap('frontcontroller');
$front = Zend_Controller_Front::getInstance();
// set default action in controllers to "something" instead of index
$front->setDefaultAction('something');
// You can also override the default controller from "index" to something else
$front->setDefaultControllerName('default');
}
If you need the default action name to be dynamic based on the URL accessed, then I think you are looking for a custom route. In that case try:
protected function _initRoutes()
{
$router = Zend_Controller_Front::getInstance()->getRouter();
// Custom route:
// - Matches : site.com/foo or site.com/foo/
// - Routes to: site.com/site/index/foo
$route = new Zend_Controller_Router_Route_Regex(
'^(\w+)\/?$',
array(
'module' => 'site',
'controller' => 'index',
),
array(1 => 'action')
);
$router->addRoute('actions', $route);
}

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 framework route

I have the following controllers in my modules..
UserController.php
AdminUserController.php
Now the route for admin controller goes to: module/admin-user/ (default behaviour)
How do I make a route so all admin- will be changed to:
/admin/module/user
You will have to write a custom route.
In code:
$front = Zend_Controller_Front::getInstance();
$router = $front->getRouter();
$route = new Zend_Controller_Router_Route(
'admin/:module/user', array('controller' => 'admin-user'));
$router->addRoute('module-admin-router', $route);
In a .ini file (I like to keep mine separate from application.ini):
[routes]
routes.module-admin-router.type = "Zend_Controller_Router_Route"
routes.module-admin-router.route = "archive/:module/user"
routes.module-admin-router.defaults.controller = "admin-user"
Then you will have to bootstrap that application section to enable the routes;
protected function _initRoutes ()
{
// setup routes here.
$front = $this->getResource('frontcontroller');
$router = $front->getRouter();
$config = new Zend_Config_Ini(APPLICATION_PATH . '/configs/routes.ini', 'routes');
$router->addConfig($config->routes);
}
This route will match any admin/module/user request and send it to the AdminUserController within the matching module.
Something like that should work. Now if things get really complicated, you'll probably need to dig into the regex router - but this is as simple as I can think of it needing to be.

Zend Framework: Zend_translate and routing related issue

I have implemented Zend_Navigation, Zend_Translate in my application.
The routing is setup in Bootstrap.php like below.
$fc = Zend_Controller_Front::getInstance();
$zl=new Zend_Locale();
Zend_Registry::set('Zend_Locale',$zl);
$lang=$zl->getLanguage().'_'.$zl->getRegion();
$router = $fc->getRouter();
$route = new Zend_Controller_Router_Route(':lang/:module/:controller/:action/*',
array(
'lang'=>$lang, 'module'=>'default', 'controller'=>'index', 'action'=>'index'
));
$router->addRoute('default', $route);
$fc->setRouter($router);
$fc->registerPlugin( new Plugin_LanguageSetup());
in LaunguageSetup Plugin i have defined the dispatchLoopStartup method to do the checking of the language param
public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request) {
$this->createLangUrl($request);
$this->_language = $request->getParam('lang');
if ((!isset($this->_language)) || !in_array($this->_language, $this->_languagesArray)) {
$this->_language = 'en_US';
$request->setParam('lang', 'en_US');
}
$file = APPLICATION_PATH.$this->_directory.$this->_language.'.csv';
$translate = new Zend_Translate('csv', $file, $this->_language);
Zend_Registry::set('Zend_Translate', $translate);
$zl = Zend_Registry::get('Zend_Locale');
$zl->setLocale($this->_language);
Zend_Registry::set('Zend_Locale', $zl);
// $fc = Zend_Controller_Front::getInstance();
// $router = $fc->getRouter();
// $route = new Zend_Controller_Router_Route(':lang/:module/:controller/:action/*', array(
// 'lang'=>$this->_language, 'module'=>'default', 'controller'=>'index', 'action'=>'index'
// ));
// $router->addRoute('default', $route);
// $fc->setRouter($router);
}
What happen is the language always have the default value, the 'lang' param never default lang value in route, even if i type it in the address bar manually i.e /en_US/module/controller/action/ It always get revert back to the default Zend_locale();
Only way i can fix it is to setup the route again in the plugin and inject a correct language value as default. Any Idea why?
try and do a var_dump of the 2 vars ( _language, _languagesArray ) before this line
if ((!isset($this->_language)) || !in_array($this->_language, $this->_languagesArray)) {
I suspect that there it should be the problem, because you put yor plugin on dispatchLoopStartup, and then the params might not be populated, i put my plugin on routeShutdown see my implementation of the languange plugin.
Sort of a partial solution.
in dispatchLoopStartup
add
$fc = Zend_Controller_Front::getInstance();
$router = $fc->getRouter();
$router->setGlobalParam('lang',$this->_language);
better than redefine and overwrite the route again and 'fake' the language param by changing the default 'lang' value.
it's just less than perfect. Zend_router suppose to pick up the 'lang' param and have them placed in Zend_navigation->menu();