custom core controller not found - php

I created a core controller named Role_Admin and set the config prefix
$config['subclass_prefix'] = 'Role_';
Here is the code for the Role_Admin.php in the core folder
class Role_Admin extends CI_Controller {
function __construct() {
}
}
In the controller folder when I write
class admin extends Role_Admin { ... }
I get
Fatal error: Class 'Role_Admin' not found
Is something wrong in what I am doing.
edit: (i created a quick fix that is much better, any new core file that you create just extend the MY_Controller. Then in your controller directory you can extend any Core controller that you created
class MY_Controller extends CI_Controller {
function __construct() {
parent::__construct();
//include custom core classes
$core_path = DOCUMENT_ROOT . '/application/core';
$this->load->helper('file');
foreach(get_filenames($core_path) as $file) {
if ($file != 'MY_Controller.php') {
if(file_exists($file)) {
include_once($file);
}
}
}
}
}

The setting you have for $config['subclass_prefix'] is fine, but your file name is incorrect. CI is looking for the file Role_Controller.php, not Role_Admin.php.
There's an easier way to do this, and although it might appear to be a hack it is totally legit. Go back to the MY_ prefix, create MY_Controller.php, and in that file, just define the controller classes you want to use. You actually don't even need a MY_Controller class. Example:
// application/core/MY_Controller.php
class Role_Admin extends CI_Controller {}
class AnotherClass extends Role_Admin {}
class SomeOtherClass extends AnotherClass {}
All these classes will be available for your controllers to extend.

Related

Extending and extended class in CodeIgniter 3

I have a controller "MY_Controller.php" in "application/core" that extends "CI_Controller":
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class MY_Controller extends CI_Controller
{
function __construct()
{
parent::__construct();
$this->load->helper('form');
$this->load->helper('url');
$this->load->helper('security');
$this->load->helper('language');
// Load language file
$this->lang->load('en_admin', 'english');
}
}
I created another controller called "Auth.php" in "application/controllers" that extends "MY_Controller":
class Auth extends MY_Controller
{
function __construct()
{
parent::__construct();
$this->load->library('ion_auth');
if ($this->ion_auth->logged_in() === FALSE) {
redirect('user/login');
}
}
}
I created a third controller "Dashboard.php" that should extend "Auth", but throws an error:
class Dashboard extends Auth
{
public function index()
{
echo 'Hello from the dashboard';
}
}
Fatal error: Class 'Auth' not found in /home/user/www/forum/application/controllers/Dashboard.php on line 5
Would appreciate your advice to solve this problem.
The link in my comment has multiple ways to solve your problem. I prefer to use the #3 method - "Using an autoload function with hooks". Here's what works for me.
application/config/config.php
$config['enable_hooks'] = TRUE;
application/config/hooks.php
$hook['pre_system'][] = array(
'class' => '',
'function' => 'register_autoloader',
'filename' => 'Auto_load.php',
'filepath' => 'hooks'
);
application/hooks/Auto_load.php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
function register_autoloader()
{
spl_autoload_register('site_autoloader');
}
/*
* Custom autoloader.
* This piece of code will allow controllers and other classes
* that do not start with "CI_" to be loaded when
* extending controllers, models, and libraries.
*/
function site_autoloader($class)
{
if(strpos($class, 'CI_') !== 0)
{
if(file_exists($file = APPPATH.'core/'.$class.'.php'))
{
require_once $file;
}
elseif(file_exists($file = APPPATH.'libraries/'.$class.'.php'))
{
require_once $file;
}
elseif(file_exists($file = APPPATH.'models/'.$class.'.php'))
{
require_once $file;
}
}
}
Your first extend of CI_Controller - class MY_Controller extends CI_Controller - should probably be in application/core/MY_Controller.php. Any classes that extend MY_Controller should be in application/libraries/.
The linked page labels the "hook" method as "the slow and right way" but the profiling I did comparing it to "2. Using an autoload function (the fast and dirty way)" showed a time difference of slightly over a microsecond. That's not worth worrying about.
I used the "fast and dirty way" for many years but kept forgetting about it when upgrading CI and I'd overwrite the config file resulting in a lost autoloader routine. Don't have that problem using the hook method other than remembering to set $config['enable_hooks'] to TRUE.
This is the regular behavior. Controllers do not extend each other. They may only extend MY_Controller (or CI_Controller). This is true for all MVC frameworks.
The way to use ion_auth, is not to extend Auth controller. You have already loaded ion_auth library, so you may directly use its methods in all controllers, the same way you use them in Auth controller.
Documentation for ion_auth here.
Well I've never used MY_Controller. I specify my class names.
I create all my classes under application/libraries and my structure is
Admin extends Common_Controller
Common_Controller handles the auth stuff for admin and members login/auth etc
Admin is a Controller up in application/modules/admin/controllers/Admin.php
Common_Controller extends Base_Controller
Base_Controller handles all the stuff common to all controllers like the templating etc
Base_Controller extends MX_Controller
MX_Controller is the wiredesignz HMVC Controller
MX_Controller extends CI_Controller
and we are done.
This is of course a HMVC setup but the principle is the same. Just don't use MY_Controller, give it a real name and use it normally.
And of course HMVC uses MY_Loader and other classes MY_xxx it uses to hook itself into CI and they live under application/core and it all plays nicely.
So as far as I can tell, there isn't a limit on how many classes deep you can go when you are extending them.

CodeIgniter creating MY_Controller

How can i create MY_Controller. Where is right place to put this file, i put it in core, folder, and i add into autoload file
code
function __autoload($class)
{
if(strpos($class, 'CI_') !== 0)
{
#include_once( APPPATH . 'core/'. $class . EXT );
}
}
then i created MY_Controller
class My_Controller extends CI_Controller
{
public function __construct() {
parent::__construct();
$this->load->view('view_header');
$this->load->view('includes/nav_home');
$this->load->view('view_home');
$this->load->view('view_footer');
}
}
but i keep getting error
Class 'MY_Controller' not found in C:\wamp\www\vezba\application\controllers\pages.php on line 4
i called MY_Controller in file
class Pages extends MY_Controller
{
function __construct() {
parent::__construct();
}
}
Where could be problem??
Double check the case on your class name and file name.
class MY_Controller extends CI_Controller
Notice how MY_ is all upper-case. Make sure this file is saved as application/core/MY_Controller.php, again note the case.
CodeIgniter should auto-load this file for you.
Docs: https://www.codeigniter.com/user_guide/general/core_classes.html
P.S. Check the $config['subclass_prefix'] option in your application/config/config.php file.
You don't need the autoloading functionality. Codeigniter will automatically load My_Controller as long as it's in your application/core directory.
You don't need to autoload your class, the framework will do it for you. In your case check the config file whether the subclass_prefix is 'MY_'. Eg; $config['subclass_prefix'] = 'MY_';
Put your class in application/core. Make sure the class name and the file name is the same.

Extending CI_Controller

All I'm trying to do is something fairly simple :
Create a class (let's say brandNewClass - NOT MY_Controller) which extends CI_Controller
Create other controllers which extend brandNewClass
E.g.
class brandNewClass extends CI_Controller {
public function index()
{
}
public function info()
{
}
}
used like (in a file under /controllers) :
<?php
class newController extends brandNewClass
{
}
?>
The thing is, although it works when I'm copying the file under /application/core and naming it as MY_Controller, when I change the name to something more... self-explanatory, it doesn't.
Fatal error: Class 'brandNewClass' not found in .... on line ..
I've even tried using the __autoload function mentioned here, but without any luck.
Any ideas?
Have a look at this excellent tutorial - I hope it helps
http://codeigniter.tv/a-10/Extending-the-core-MY_Controller-and-beyond
The autoloader doesn't automaticly include other controllers. you will have to include it manually like this:
if (!defined('BASEPATH'))exit('No direct script access allowed');
include_once(APPPATH . 'controllers/brandnewclass.php');
If you want to create a custom base controller and make other controllers extend there, you can do it in following ways:
Create MY_Controller extending CI_Controller in application/core/ folder and make other controllers extend MY_Controller as MY_Controller will be autoloaded from core (This I guess you already know but want other alternatives.
Create MY_Controller in application/core/. Then create other level of Controllers that can primarily be Admin_Controller and Frontend_Controller. Now, one of these controllers will make base for your actual used controllers.
e.g. in application/core/MY_Controller.php
class MY_Controller extends CI_Controller {
public function __construct(){
parent::__construct();
}
}
Then Admin and Frontend controllers will be created in application/libraries/ and will extend MY_Controller like
class Admin_Controller extends MY_Controller {
public function __construct(){
parent::__construct();
}
}
Now, Any controller can extend one of these 2 controllers but for doing that you will have to autoload them. For autoloading in this case there can be a confusion because setting autoload['libraries'] in config/autoload.php will not work . That autoload works inside a controller but here we need to autoload before that i.e. in the class declaration. Will need to set this code in config/config.php
function __autoload($class)
{
$path = array('libraries');
if(strpos($class, 'CI_') !== 0) {
foreach($path as $dir) {
$file = APPPATH.$dir.'/'.strtolower($class).'.php';
if (file_exists($file) && is_file($file))
#include_once($file);
}
}
}
Now you can create your own controller
class newController extends Admin_Controller
{
}
This is the most suggested method making your structure quite clean and effective. May take some effort in understanding for the first time but is definitely worth it.
Third method is just a tweak of the second one, just based on the condition you mentioned of not using MY_Controller
You can make Admin_Controller or Frontend_Controller extend CI_Controller directly and not extend MY_Controller
That may just lead to some duplicity of code in both these controllers if that may be the case
http://philsturgeon.co.uk/blog/2010/02/CodeIgniter-base-Classes-Keeping-it-DRY
I suspect you're trying something similar?
There's an autoload function that you can add to the config file so that you needen't require_once() the class all the time.
You should declare the class as abstract, since it shouldn't be instantiated directly.
You'll need to modify the CodeIgniter autoloader configuration file and add your class to it, or change the actual autoloader.
You really should consider not using CodeIgniter :)

Accessing controller public controllor properties from a hmvc module

Am working with wiredesignz modular extensions for codeigniter, and i was wondering if its possible to access a regular codeigniter controller's public property from a module's controller
for example, this is a regular ci controller
<?php
class Dog extends CI_Controller {
public $name;
function __construct()
{
$this->name = "xyz";
}
}
and this a module controller
<?php
class Test extends MX_Controller {
function get_name()
{
//access the $name property of the dog controller here
}
}
If you're using HMVC there's no reason why all or any of your controllers can't inherit from MX_Controller. You can have controllers in your normal application/controllers or application/core folders that inherit MX_Controller, they don't have to be "module" controllers.
If you need to access properties from one controller in another why not create a base controller e.g. MY_Controller that extends MX_Controller, put it in either application/controllers or application/core and then every time you create a "module" controller simply inherit from MY_Controller instead of MX_Controller.
Don't forget you can load any module controller and use it like a library class.

Putting a base model extended class in the application/models folder

I created a base_model extends CI_Model class and put it in application/model. Then, I created another class that extends base_model, but I get the following error:
Cannot find this class
Other resources told me to put the base_model in:
application/core
or:
application/libraries
However, I would like to put it in application/models for convenience. Can I put this class in application/models and still have it work correctly?
Try putting a MY_Model class in your application/core folder instead. First-level inheritance was built into CI by default, i.e.:
{APPATH}/core/MY_Model.php:
<?php
class MY_Model extends CI_Model {
public function __construct()
{
parent::__construct();
}
}
In that same file, if you want alternate parent classes, try:
...
class Base_model extends MY_Model {
public function __construct()
{
parent::__construct();
}
}
...
If you don't put it in MY_Model, YOU ARE RESPONSIBLE for loading the base model first (before an extended class references it), AND you can't have a file in your models/ folder called Base_model.php, for example.

Categories