Part of the EllisLab Network
   
 
Extending a controller subclass
Posted: 01 December 2009 03:05 PM   [ Ignore ]  
Summer Student
Total Posts:  25
Joined  08-16-2009

Hello I have a weird issue. I have a custom controller that extends the core CI Controller

<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');

class 
RA_AdminController extends Controller 
{
    
public function RA_AdminController()
    
{
        parent
::Controller();
    
}

This file is in application/libraries/RA_AdminController.php

I have changed the application/config.php to include my prefix

$config['subclass_prefix''RA_'

I also have a custom controller that extends the RA_AdminController

<?php
//require_once(APPPATH.'libraries/RA_AdminController.php');
class Home extends RA_AdminController {

    
function Home()
    
{
        parent
::RA_AdminController();
    
}
    
    
function index()
    
{
        $this
->load->view('admin/home');            
    
}

this is in the application/controllers/admin/home.php

Now every time I try to load the home.php I get the following error

[Tue Dec 01 21:01:38 2009] [error] [client 127.0.0.1] PHP Fatal error:  Class ‘RA_AdminController’ not found in D:\\applications\\Apache2.2\\ciproject\\application\\controllers\\admin\\home.php on line 3


I have searched the forum and I saw that many people had the same problem in the past. Unfortunately none of the proposed solutions worked for me. I’d appreciate any ideas/help I can get.

Regards

Panos

Profile
 
 
Posted: 01 December 2009 04:46 PM   [ Ignore ]   [ # 1 ]  
Summer Student
Total Posts:  12
Joined  09-22-2008

It looks like you can change the “subclass_prefix” but you cannot change the name of the library to anything else than [subclass_prefix]+“Controller.php”..

CodeIgniter looks like it’s unable to guess what is after your “subclass_prefix”... in the name of the library… so it cannot automatically include [subclass_prefix]_* but just [subclass_prefix]_Controller

Profile
 
 
Posted: 01 December 2009 06:33 PM   [ Ignore ]   [ # 2 ]  
Research Assistant
Avatar
RankRankRank
Total Posts:  672
Joined  07-16-2008

I suggest that you build your extending cotroller something like this:

libraries/MY_Controller.php

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class 
MY_Controller Extends Controller
{
    
    
function __construct()
    
{
        parent
::__construct();
    
}
}

class Admin_controller Extends MY_Controller
{

    
function __construct()
    
{
        parent
::__construct();
    
}

..and in controllers/home.php

class Home extends Admin_controller {

    
function __construct()
    
{
        parent
::__construct();
    
}
    
    
function index()
    
{
        $this
->load->view('admin/home');            
    
}

This way you can add classes to your MY_Controller as you wish and extend those in your controllers as you need. Typical usage would be to create Frontend_controller and Backend_controller classes for example..

Profile
 
 
Posted: 01 December 2009 06:55 PM   [ Ignore ]   [ # 3 ]  
Summer Student
Total Posts:  25
Joined  08-16-2009

Actually I would like to have each of my sub-controllers on a separate file. And I would also like them to start with RA_. Is this possible?

Profile
 
 
Posted: 01 December 2009 07:58 PM   [ Ignore ]   [ # 4 ]  
Research Assistant
Avatar
RankRankRank
Total Posts:  672
Joined  07-16-2008

Well if you want them to be in separate files, you can include them like you have included them in your original code(that was commented out). If you want to extend core libraries with your own prefix, you can do so but take note what Artemis Mendrinos said.

If you just want to extend the controller, you can leave it to MY_ and do something like this:


libraries/MY_Controller.php

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class 
MY_Controller Extends Controller
{
    
    
function __construct()
    
{
        parent
::__construct();
    
}
}

require_once(APPPATH.'libraries/RA_AdminController.php'); 

libraries/RA_AdminController.php

class RA_AdminController Extends MY_Controller
{

    
function __construct()
    
{
        parent
::__construct();
    
}


controllers/home.php

class Home extends RA_AdminController
{

    
function __construct()
    
{
        parent
::__construct();
    
}
    
    
function index()
    
{
        $this
->load->view('admin/home');            
    
}
Profile
 
 
Posted: 02 December 2009 07:06 AM   [ Ignore ]   [ # 5 ]  
Summer Student
Total Posts:  25
Joined  08-16-2009

So basically this is a restriction CI imposes on naming the sub-controllers. Thanks everyone for your help.

Regards

Panos

Profile
 
 
Posted: 02 December 2009 08:11 AM   [ Ignore ]   [ # 6 ]  
Sr. Research Associate
Avatar
RankRankRankRankRank
Total Posts:  2774
Joined  07-27-2006

No. I’d like to clarify that there is no restriction. There is a set of conventions CI uses when loading resources. When you don’t follow those conventions when naming and locating your resources, CI doesn’t load them. I would hardly call that a restriction.

 Signature 

Check out the Template Library
Oh yeah, I tweet, too (regarding CodeIgniter on occassion).

Profile
 
 
Posted: 30 December 2009 02:12 PM   [ Ignore ]   [ # 7 ]  
Grad Student
Rank
Total Posts:  65
Joined  11-10-2008

Restriction or broken convention, it amounts to the same thing in the end. How ya gonna support front end ve backend, cron job vs home page etc. Only one level subclassing for controllers is all that can be easily accomplished with no further thought.

Neither solution seems very appealing.

In the case of including everything, I don’t feel I gained any memory/space/clarity/separation. Every controller script gets every controller class definition. It may become bloated.

In the case of hard-coding require APPPATH etc: years later these will be littered throughout your scripts. Just the sort of maintenance headace conventions are meant to address.

A cursory glance at the code tells me behaviour might be modified by overriding what the router returns for fetch_directory, fetch_class and friends.

I met and modified Magento recently, my first exposure to the Zend framework. Looks like they have taken this concept and run with it: folder/naming conventions allow for more than one level of subclassing.

Needs must at this time, and I will use “require_once”.

I would be interested to hear how others are thinking about this problem. Or whether it is even a problem.

In biology they have a saying “evolution is smarter than you”. At the moment I am operating on the principle that “CI is smarter than me”. I’m almost inclined to use neither approach and have one big fat controller.

Has anyone considered extending the router to implement a convention that takes subclassing for controllers a step further? Or found a better thought/solution.

Happy holidays to all.

Profile