Welcome Guest, Not a member yet? Register   Sign In
[CI3] - URI class returning Controller name in ucfirst
#1

(This post was last modified: 09-23-2015, 07:27 AM by gccloud.)

Hi everyone,

it seems there's a little problem with 404-errors management in the main CodeIgniter class. Between the lines 429 and 478 of the CodeIgniter.php file, there's the following statement :

PHP Code:
if ($e404)
 {
 if ( ! empty(
$RTR->routes['404_override']))
 {
 if (
sscanf($RTR->routes['404_override'], '%[^/]/%s'$error_class$error_method) !== 2)
 {
 
$error_method 'index';
 }

 
$error_class ucfirst($error_class);

 if ( ! 
class_exists($error_classFALSE))
 {
 if (
file_exists(APPPATH.'controllers/'.$RTR->directory.$error_class.'.php'))
 {
 require_once(
APPPATH.'controllers/'.$RTR->directory.$error_class.'.php');
 
$e404 = ! class_exists($error_classFALSE);
 }
 
// Were we in a directory? If so, check for a global override
 
elseif ( ! empty($RTR->directory) && file_exists(APPPATH.'controllers/'.$error_class.'.php'))
 {
 require_once(
APPPATH.'controllers/'.$error_class.'.php');
 if ((
$e404 = ! class_exists($error_classFALSE)) === FALSE)
 {
 
$RTR->directory '';
 }
 }
 }
 else
 {
 
$e404 FALSE;
 }
 }

 
// Did we reset the $e404 flag? If so, set the rsegments, starting from index 1
 
if ( ! $e404)
 {
 
$class $error_class;
 
$method $error_method;

 
$URI->rsegments = array(
 
=> $class,
 
=> $method
 
);
 }
 else
 {
 
show_404($RTR->directory.$class.'/'.$method);
 }
 } 

Basically, at some point here, the Controller class that is stored as the first rsegments index of the URI class is stored in ucfirst. And it seems this is the only point in CI where it's not stored in lowercase.

So what's my problem here ? I've got (on a previously designed application i'm working on) a 404 override route defined on my routes.php config files, as follows :

PHP Code:
$route['404_override'] = 'home/page404'

Normally it wouldn't be a problem, but that Controller "Home" also handles the application login process. So, in my CI_Controller core override, i've got the following statement :

PHP Code:
if($this->check_logged_in()) {

    // some more stuff here if the user is logged in
}
else {
    if(($this->uri->rsegment(1) != 'home') || ( ! in_array($this->uri->rsegment(2), array('login''login_validation')))) {
        redirect();
    }


So what i'm basically doing here is just check that the user is correctly logged in, or else redirect him to the default login page only if we're not on the "Home" Controller or already on the login page.

What i end up with here is : if the user isn't logged in and try to access a non-existing page of my website, he should see a 404 page. But instead of that, i end up with the previous statement ($this->uri->rsegment(1) != 'home') evaluated to TRUE; because in that case, the rsegment returned by the URI Class is "Home", not "home". Thus the user is redirected on the login page, and never sees the 404 page...

So, while i must admit this is not trully horrible for the user in the end (or that i could handle it myself by manually applying a simple strtolower() on the return value of the rsegment() method), i feel like it shouldn't work that way, thus the reporting...
Reply
#2

Can't you just use
PHP Code:
$this->uri->segment(1
instead of using
PHP Code:
$this->uri->rsegment(1
Reply
#3

This is the indended behavior ... the fact that this is the only place the controller name is stored in Ucfirst inside the URI class is simply because that's the only place it stores an actual controller name.

You can either apply strtolower() or just compare against 'Home' instead of 'home'.

(09-23-2015, 07:30 AM)Martin7483 Wrote: Can't you just use

PHP Code:
$this->uri->segment(1
instead of using

PHP Code:
$this->uri->rsegment(1

Actually, he can't. It's a 404 override ... that's pretty much the only place segment(1) is guaranteed not to match rsegment(1).
Reply
#4

Thanks for the quick answer Narf. This is exactly what i was looking for : whether it is an intended behavior or not. So, as we both said, i'll handle this special case with a strtolower().
Reply
#5

Thanks for the info!
Reply




Theme © iAndrew 2016 - Forum software by © MyBB