CakePHP setflash page refresh doesn't keep language in url - cakephp

I have a multi language website, but when I don't do a redirect with a setFlash, it deletes the language from the url. Example: if the contactform doesn't validate, it just does a setFlash without the redirect, so that user input data is not lost. But it does refresh the page and deletes the language part from my url. This does not happen when I do a redirect after my setFlash, because I give the language param with the redirect. Work flow:
I start on the page website.com/eng/contact (notice the language part). I fill in the contact form and fill in all required inputs. It redirects me to website.com/eng/contact/send. That's great and what I want. But when I don't give an valid email adres for example, it display an error (great), but the url has changed to website.com/forms/contact (notice the missing language part, and it doesn't use my routes). What am I doing wrong? My code:
Formscontroller.php
public function contact() {
if ($this->request->is('post')) {
$this->Form->set($this->request->data);
if ($this->Form->validates()) {
if($this->Form->save($this->request->data)){
$this->redirect(array('controller' => 'forms', 'action' => 'contact_success', 'language' => $this->Session->read('Config.language')));
} else {
$this->Session->setFlash(__('Er ging iets mis met het versturen van uw contactformulier, probeer het opnieuw.'), 'flash_error');
}
} else {
$this->Session->setFlash(__('Niet alle verplichte velden zijn ingevuld.'), 'flash_error');
}
}
}
routes.php
Router::connect('/:language/pages/*', array('controller' => 'pages', 'action' => 'display'));
Router::connect('/:language/contact', array('controller' => 'forms', 'action' => 'contact'), array('language' => 'ned|eng'));
Router::connect('/:language/contact/verzonden', array('controller' => 'forms', 'action' => 'contact_success'), array('language' => 'ned'));
Router::connect('/:language/contact/send', array('controller' => 'forms', 'action' => 'contact_success'), array('language' => 'eng'));
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
Router::connect('/:language', array('controller' => 'pages', 'action' => 'display', 'home'), array('language' => 'eng|ned'));
Router::connect('/:language/:controller/:action/*', array(), array('language' => '[a-z]{3}'));
CakePlugin::routes();
require CAKE . 'Config' . DS . 'routes.php';

I was looking in the wrong direction for my problem. As ndm points out in his comment on my question, it had to do with the action of my form, it didn't have the language part in it. So thanks to ndm for pointing me in the right direction!

Related

cakephp 2.5 Router - part of language string in URL

CakePHP Version 2.5.2
Config.Language 'spa'
If i'm in
mydomain.com/backoffice
and i reload (ctrl-r) i get again
mydomain.com/backoffice
If i call in UsersController in action deleteCache at the end:
return $this->redirect('/backoffice');
i get
mydomain.com/users/sbackoffice
Please note the "s" before backoffice. That seems to be a part of the config.language
If i set the Config.language to 'eng' i get
mydomain.com/users/ebackoffice
Please note now the 'e' before backoffice.
My routes.php:
Router::connect('/backoffice', array('controller' => 'users', 'action' => 'backoffice'));
Router::connect('/:language/:controller/:action/*',
array(),
array('language' => 'eng|spa')
);
Router::connect('/:language/:controller',
array('action' => 'index'),
array('language' => 'eng|spa')
);
Router::connect('/:language', array('controller' => 'technologies', 'action' => 'home'),
array('language' => 'eng|spa')
);
Any idea?
How can i debug this?

Cakephp Site Root with username conflict with controllers

I got this code working.
when i go to domain.com/ it will route to home->index(). when i type in domain.com/username.. it will route to users->view(username)
file: config/routes.php
$controllerList = App::objects('Controller');
foreach($controllerList as $controller)
{
$controllerName = str_replace('Controller', '', $controller);
if($controllerName != "App" & $controllerName != "Pages")
{
Router::connect('/' . $controllerName . '/:action/*', array('controller' => $controllerName));
$firstLetterLower = strtolower(substr($controllerName,0,1));
$lowerCaseName = $firstLetterLower . substr($controllerName,1);
Router::connect('/' . $lowerCaseName . '/:action/*', array('controller' => $lowerCaseName));
}
}
Router::connect('/:username', array('controller' => 'users', 'action' => 'views'), array('pass' => array('username')));
Router::connect('/', array('controller' => 'home', 'action' => 'index'));
the problem is that i cannot route my controllers domain.com/controller without putting the action..
This will work: domain.com/blog/index, domain.com/forum/index, domain.com/users/login
This wont work: domain.com/blog it will be treated as username
Exclude the controller names from being matched in the username route. You should have a list of them to prevent people from registering with these names at all.
Put you code like this. this will not treat blog as username
Router::connect('/', array('controller' => 'home', 'action' => 'index'));
Router::connect('/blog', array('controller' => 'blog', 'action' => 'index'));
Router::connect('/:username', array('controller' => 'users', 'action' => 'views'), array('pass' => array('username')));
Thanks..!

How can I stop that cakePHP 2.1 redirects all my new views?

I hope you can forgive my bad english, I hate auto translating services... So I write by my own. xD
I am working in cakePHP 2.1, but the code is not mine. For some reason, when I create a new view with its correct controller created, the system redirectsme to the root. So, I cannot create a new view. Of course, the view exist in the controller becouse I add it.
For example, I add this code in cake/Controller/DocumentsController.php:
function add_pago() {
//I code for food.
}
And I create a new file called cake/Views/Documents/add_pago.ctp with this random code after the php tag:
echo "hello, world!";
There's no beforeFilter() function in DocumentsController.php. In AppController.php, the beforeFilter function is shown bellow:
public function beforeFilter() {
//Configure AuthComponent
//$this->Auth->allow('display');
$this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
$this->Auth->logoutRedirect = array('controller' => 'users', 'action' => 'login');
$this->Auth->loginRedirect = array('controller' => 'pages', 'action' => 'display', 'home');
if(!empty($this->data)) array_walk_recursive($this->data, array($this, '__whitespace'));
}
Simple ACL is active. The programmer can't remeber what he did to get this behavior. And I can't figure how to fix this.
Do you have any suggestion to find where in the code is programmed this?
Use $this->Auth->allow('add_pago'); in your beforeFilter callback.
public function beforeFilter() {
//Configure AuthComponent
//$this->Auth->allow('display');
$this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
$this->Auth->logoutRedirect = array('controller' => 'users', 'action' => 'login');
$this->Auth->loginRedirect = array('controller' => 'pages', 'action' => 'display', 'home');
if(!empty($this->data)) array_walk_recursive($this->data, array($this, '__whitespace'));
$this->Auth->allow('add_pago');
parent::beforeFilter();
}

CakePHP - how to translate current URL after changing language and reloading Routing table

I'm using different routing tables for every language, and I have wrote action which change language and redirects to the same page but in target language (and target url).
The main problem is that my action is way too complicated - how can I make it simple?
It should change language and redirect to new url (in target language).
In short: We had random valid cake url in one language and we had to translate it to adequate url in another language.
My routing table:
if( 'en' == Configure::read('Config.language') ) {
Router::connect('/help', array('controller' => 'pages', 'action' => 'display', 'help') );
} else {
Router::connect('/pomoc', array('controller' => 'pages', 'action' => 'display', 'help') );
}
Action changing language:
function lang($lang) {
// getting previous url table
$url = $this->referer();
$url = Router::parse($url);
// changing language
if( in_array($lang, Configure::read('Languages.valid') ) ) {
$this->Session->write('Language', $lang);
Configure::write('Config.language', $lang);
}
// saving base params
$requestInfo = array(Router::getParams(), Router::getPaths());
// reload routing table
Router::reload();
include(CONFIGS.'routes.php');
// restore base params
Router::setRequestInfo($requestInfo);
// fix for 'pass' params
if(!empty($url['pass']) && is_array($url['pass'])) {
$url = array_merge($url, $url['pass']);
unset($url['pass']);
}
$this->redirect($url);
}
About 'pass' key in url table:
/pages/display/help
after Router::parse(), parameter is extracted:
pass => array(
0 => 'help'
)
and later return value from Router::url() look like that:
/pages/display/pass:Array
so I have to fix it by merging 'pass' value with whole array and removing key
I have my routes.php like this
Configure::write('Config.language', $_SESSION['lang']);
Router::connect(__('/help',true), array('controller' => 'pages', 'action' => 'display', 'help') );
so I use the __() to translate the url. It seaches the translation in the po files. And in your lang() function, after changing the Session to the current lang, all you need to do is:
$this->redirect(__('/help'));
Hope this helps
I know it is too late to answer that, but for those who experience the similar needs:
In routes.php p1 identifies the static page (same for all languages), could be any string that uniquely identifies the page.
Router::connect('/:language/p1/:translation', array(
'controller' => 'pages',
'action' => 'display',
'help',
'options' => array('language' => '[a-zA-Z]{2}')
) );
In your view
$this->Html->link('Click me', array(
'language' => Configure::read('Config.language'),
'controller' => 'pages',
'action' => 'display',
'help',
'translation' => __('help') // could be any string in fact
));
will generate link to /en/p1/help in English, else to /xx/p1/pomoc.
Injection of language parameter into every link could be done in AppHelper::url() instead of providing it in every link occurence.
If you want to redirect in controller:
$this->redirect(array(
'language' => Configure::read('Config.language'),
'controller' => 'pages',
'action' => 'display',
'help',
'translation' => __('help')
));

Cakephp localization routes

My localization files (.po) work if I change the default language, but I can't make the routes working, here's what I've got atm:
Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
Router::connect('/login/*', array('controller' => 'users', 'action' => 'login'));
Router::connect('/logout/*', array('controller' => 'users', 'action' => 'logout'));
Router::connect('/register/*', array('controller' => 'users', 'action' => 'register'));
Router::connect('/:lang/:controller/:action/*', array('lang' => 'en'), array('lang' => 'en|fr'));
But when I try : domain.com/fr/login, the cake is looking for the "fr" controller.
I am using this function in the AppController beforeFilter to switch between languages:
function setLanguage() {
if(!isset($this->params['lang']))
{
$this->params['lang'] = 'en';
}
$lang = $this->params['lang'];
App::import('Core', 'i18n');
$I18n =& I18n::getInstance();
$I18n->l10n->get($lang);
foreach (Configure::read('Config.languages') as $lang => $locale)
{
if($lang == $this->params['lang'])
{
$this->params['locale'] = $locale['locale'];
}
}
}
Cheers,
Nicolas.
You do not have a login controller. So your bottom route does not match and Cake then tries the default by looking for an fr controller.
Routes don't interact as you expect them to:
/login - would match your second route
/fr/users/login - would match your last route.
/fr/login - does NOT intelligently "merge" the two routes. You need to explicitly make such a route.

Resources