A bit of an obscure question, I think. I've successfully set up the language prefix for all of my routing rules to handle localization. Everything works great when a user requests controllers which exist in the application (e.g., /users/view/4). In my AppController I have the application successfully redirect any requests which are missing a language prefix to a URL that has one (e.g., /eng/users/view/4).
The problem arises when a user requests an invalid controller. In this case, after redirecting the user, the application throws a MissingControllerException (which it should) but the controller it reports as invalid is the language prefix itself (e.g., "EngController"), not the controller that comes after this in the request URI.
This indicates that in an error state, the Cake application is no longer aware of any language prefix routing. This suggests I need to add another routing rule to routes.php which will target only invalid requests and ensure that a language prefix is expected and accounted for in any requests which are handled by CakeErrorController (which is the core controller that takes over for these types of exceptions).
But I've scoured the docs and I have no idea how to craft such a route. Thanks for your help!
Here is my routes.php file:
<?php
$lang_settings = ['language' => '[a-z]{3}'];
// ElStats homepage vs tenant homepage
if(!TENANT) {
Router::connect('/', ['controller' => 'pages', 'action' => 'index'], $lang_settings);
Router::connect('/:language', ['controller' => 'pages', 'action' => 'index'], $lang_settings);
} else {
Router::connect('/', ['controller' => 'pages', 'action' => 'index'], $lang_settings);
Router::connect('/:language', ['controller' => 'pages', 'action' => 'index'], $lang_settings);
}
/**
* ...and connect the rest of 'Pages' controller's urls.
*/
Router::connect('/:language/pages/*', ['controller' => 'pages', 'action' => 'display'], $lang_settings);
Router::connect('/:language/contests/search/*', ['controller' => 'contests', 'action' => 'index'], $lang_settings);
Router::connect('/:language/contests/:action/*', ['controller'=>'contests'], $lang_settings);
Router::connect('/:language/contests/*', ['controller' => 'contests', 'action' => 'index'], $lang_settings);
Router::connect('/:language/candidates/search/*', ['controller' => 'candidates', 'action' => 'index'], $lang_settings);
Router::connect('/:language/candidates/:action/*', ['controller'=>'candidates'], $lang_settings);
Router::connect('/:language/candidates/*', ['controller' => 'candidates', 'action' => 'index'], $lang_settings);
// If just /search, then default to /contests/search
Router::connect('/:language/search/*', ['controller' => 'contests', 'action' => 'index'], $lang_settings);
/**
* Full-controller alias routing
*/
// ballot_questions => contests
Router::connect('/:language/ballot_questions/search/*', ['controller' => 'contests', 'action' => 'index'], $lang_settings);
Router::connect('/:language/ballot_questions/:action/*', ['controller'=>'contests'], $lang_settings);
Router::connect('/:language/ballot_questions/*', ['controller'=>'contests', 'action' => 'index'], $lang_settings);
Router::connect('/:language/admin/ballot_questions/:action/*', ['controller'=>'contests','admin' => true], $lang_settings);
Router::connect('/:language/admin/ballot_questions/*', ['controller'=>'contests', 'action' => 'index', 'admin' => true], $lang_settings);
// Admin Routing
Router::connect('/:language/admin', [ 'controller'=> 'pages', 'action'=> 'index','admin' => true], $lang_settings);
Router::connect('/:language/admin/:controller/:action/*',['admin' => true], $lang_settings);
Router::connect('/:language/admin/:controller/*',['admin' => true], $lang_settings);
Router::connect('/:language/:controller/:action/*',[], $lang_settings);
require CAKE . 'Config' . DS . 'routes.php';