Codeigniter - Extending my own controllers - php

I'd like to know if it's possible to extend my own controllers. I've been working on web-based applications for a while and I'm now starting to find each customer that wishes to use the application has different requirements of how it should work. My thoughts are that if I generate a base structure and then extend the controllers to override any of the functions that the customers require to work differently.
First of all, could you tell me if I'm on the correct track, and secondly, how do I go about extending my own controllers (if I can)? I've tried the usual:
Class Reports2 extends Reports { }
This doesn't work but I'm guessing it has something to do with the location of the file I'm trying to extend. My file structure is as follows:
Application
--->controllers
-------->control_panel
------------>reports.php

If I am not mistaken then you should be able to easily do this:
reports2.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
require_once(APPPATH.'controllers/control_panel/reports.php');
Class Reports2 extends Reports {
public function __construct(){
parent::_construct();
}
public function index(){
}
}

Related

Change default controller directory of Codeigniter

I want to have two folders where save codeigniter's controllers:
/application/controllers
/application/buckets
i'm a order paranoic person and i want to separate two types of my controllers.
In bucket folders the structure app was this:
/application/buckets/example/index.php
/application/buckets/example2/index.php
/application/buckets/example3/index.php
¿Maybe extending the router class?
A working example:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/*
Extended the core Router class to allow for sub-sub-folders in the controllers directory.
*/
class App_Router extends CI_Router {
function __construct()
{
parent::__construct();
}
function _validate_request($segments)
{
if (count($segments) == 0)
{
return $segments;
}
if (file_exists(APPPATH.'buckets/'.$segments[0].'/index.php'))
{
$this->set_directory(APPPATH.'buckets/'.$segments[0]);
$this->set_class(ucfirst($segments[0]));
$this->set_method(isset($segments[1]) ? $segments[1] : 'index');
return $segments;
}
}
}
You can use Hierarchical MVC(HMVC) with Codeigniter to accomplish this.
For reference, see Modular Extensions - HMVC
You may want to look into parent-child controller ...one extending another. To be more clear you can make as many controller you want.
I Agreed with #Brian Gottier : "what does changing their location do?"
You can perform anything if you have core functionalities in your hands.
You can play around with hooks (CodeIgniter's Hooks feature provides a means to tap into and modify the inner workings of the framework without hacking the core files. When CodeIgniter runs it follows a specific execution process, diagramed in the Application Flow page.)
Create "Base"/"Admin"/"Public"/"XYZ" Controllers in
application/core/MY_Controller.php
and keep rest of your controllers in same application/controller folder
MY_Controller is a basic core library extension. Whenever you create a class with the MY_ prefix the CodeIgniter Loader class will load this after loading the core library.
All we have done here is create a base class that all of our Controllers and "controller types" will inherit. Anything we put in here and assign to $this will be available to anything that extends this class.
Base Controllers are a nice simple way to give you global data, logic and shared code which can be specific to a certain part of your site. They can do all sorts of crazy stuff which I will leave for you to think about.
I Hope this help.

Codeigniter - load a model in my library

I'm about to write my own library in codeigniter to check if the logged in user is an admin or not. To do that I need to compare a value with the value of the typeAccount in the DB.
Because I'm still learning the MVC pattern I had a question about this before starting to write my library.
Can I load a model in my library? Or should I communicate directly to my DB in my library? Or is there a better way to approach this?
Yes, you can load your model to into your library, simply add CI.
class Validator
{
private $CI = null;
function __construct()
{
$this->CI =& get_instance();
}
public function validate_merchantaccount_status($param)
{
//Code Here
$this->CI->load->model('merchantaccount_model');
$res_merchant = $this->CI->merchantaccount_model->get_list($param);
}
}
Dont forget to make your model.
Since the library is some kind of logic, you can see it as a piece of the Controller.
The Controller usually just loads a Model to use it.
So yes just load the Model from CodeIgniter instead of connecting to the database yourself.
Makes your code more DRY too.
Make you models
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class My_model extends CI_Model
{
/// Here the code
}
And then in controller use
$this->load->model('my_model');
Ant i think that is best approach :)

How do i tackle a situation where in i need to use same functions in multiple places

I am creating a order fulfillment system for mu E-commerce system. I am stuck in a situation. Every 1 hour 1 cron job runs and it assigns ware house and does other processes.So this is a class where i do 1 full process. I need to give option for user to do each of them individually also manually i.e. assign warehouse manually etc. So this warehouse functions will be used in multiple places i.e in cron class and warehouse class. So should i create these functions in 1 library like warehouse.php or else in cron class create instance of each class and call its functions? i am using Codeigniter.
Hope below code makes my self clear. So should i create a warehouse library or a controller is my question.
Main question is to use like this
class cron extends CI_Controller{
function index(){
$this->load->library('blacklist');
$this->load->library('warehouse');
$this->load->library('lsp');
$this->blacklist->function1();
$this->warehouse->function2();
}
}
or
class cron extends CI_Controller{
function index(){
$blacklist = new blacklist();
$warehouse = new warehouse();
$lsp = new lsp();
$blacklist->function1();
$warehouse->function2();
}
}
Set up a MY_Controller in your Core folder which extends CI_Controller - make your normal controllers extend MY_Controller instead of CI_Controller and put the functions you need to access from multiple controllers in there. I did something similar and then restricted my cron controller to cli requests only using an if(!$this->input->is_cli_request()){ exit(); } for added security.
Sample:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class MY_Controller extends CI_Controller {
public function __construct() {
parent::__construct();
}
protected function _order_export()
{
// Export routine goes here
}
}
/* End of file MY_Controller.php */
/* Location: ./application/core/MY_Controller.php */
Make calls to this function using $this->_order_export(); in your other controllers.
Yes, you can. Write a warehouse class/controller or set of functions that can adapt to multiple uses in different part of your system. You can then logically programme the class/function to work for each use.
Very basic pseudo-code:
If (CLI)
{
// do this
} elseif (BATCH) {
// do that
} elseif (MANUAL) {
// do other
}
Helping you any further than this is impossible at this point as we're like blind men in a minefield.

codeigniter -> having trouble loading multiple libraries/classes

Ok, so in my base controller (page.php) I have the following code which works fine:
$this->load->library('Siteclass');
$mysite = new site_model();
The siteclass library references a model named site_model and instantiates based on data received from that model. All is good.
Now I want to load another library so that I can instantiate another object as well. So I add this to page.php:
$this->load->library('Memberclass');
$mysite = new member_model();
But now I get the following error:
Message: Undefined property: Memberclass::$site_model
Filename: libraries/Loader.php
Line Number: 1035
From what I can tell, it seems that the loader class, when being applied to the Memberclass, is somehow still referencing the site_model instead of the member_model. I've checked my code and I am definitely calling the correct files.
Here's what Siteclass.php looks like:
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Siteclass extends Controller {
function __construct() {
parent::Controller();
$this->load->model('Site_model');
$data = $this->Site_model->load_site_data();
// etc etc
and here's what Memberclass.php looks like:
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Memberclass extends Controller {
function __construct() {
parent::Controller();
$this->load->model('Member_model');
$data = $this->Member_model->load_member_data();
// etc etc
Thanks in advance for any help!
Gary
I think you're confused about how MVC works in CodeIgniter. Why are you using the loader class to create a controller? Why are you creating a stand-alone instance of your model outside of your controller class?
In CodeIgniter, your URLs represent paths to your controllers' methods. That means that your "base controller" should automatically be instantiated if you go to:
www.example.com/memberclass
Or perhaps more to the point, if you have a link like this:
www.example.com/page
You should have a file in your /application/controllers directory called page.php which looks like this:
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Page extends Controller {
function __construct() {
parent::Controller();
// etc etc
Furthermore, unless you're loading data from your model to be used every single time you call this controller, you'll want to put your model calls inside a non-constructor method of this class. Something like:
class Page extends Controller {
function __construct() {
parent::Controller();
}
function index() {
$this->load->model('Member_model');
$data = $this->Member_model->load_member_data();
$this->load->view('myview', array('data'=>$data));
}
}
So again...not entirely sure what context you're doing this all in, but it seems like you're not standing firmly within the framework. There's basically no reason you should be using the loader class to load controllers, and furthermore there's no reason you should be creating stand-alone instances of model classes using PHP's new keyword.

How do I extend the code igniter controller class?

In my CI system\libraries directory I have a new class named DD_Controller.php. This file looks like this:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class DD_Controller extends Controller
{
protected $ddauthentication;
function __construct()
{
parent::Controller();
$this->ddauthentication = "Authenticated";
}
}
?>
My application controller is defined like this:
class Inquiry extends DD_Controller
{...}
The Inquiry class works fine when I extend Controller, but I get a
Fatal error: Class 'DD_Controller' not
found in
C:\development\localhost\applications\inquiry\controllers\inquiry.php
on line 4
When I extend DD_Controller. In the config file I have the prefix defined as such:
$config['subclass_prefix'] = 'DD_';
Any idea of what I'm missing?
TIA
This is a better approach. Do the following:
Go to the following directory: your_ci_app/application/core/ and create a php file called MY_Controller.php (this file will be where your top parent classes will reside)
Open this the file you just created and add your multiple classes, like so:
class Admin_Parent extends CI_Controller {
public function __construct() {
parent::__construct();
}
public function test() {
var_dump("from Admin_Parent");
}
}
class User_Parent extends CI_Controller {
public function __construct() {
parent::__construct();
}
public function test(){
var_dump("from User_Parent");
}
}
Create your children controllers under this directory your_ci_app/application/controllers/ . I will call it adminchild.php
Open adminchild.php and create your controller code, make sure to extend the name of the parent class, like so:
class Adminchild extends Admin_Parent {
function __construct() {
parent::__construct();
}
function test() {
parent::test();
}
}
DD_Controller.php should be in /system/application/libraries/
If you're using the same CI for multiple apps, and you want them all to be able to extends their controllers to your custom one then you can extend the base Controller class in the same file.
In system/libraries/Controller.php below the Controller class:
class Mega_Controller extends Controller {
function Mega_Controller()
{
parent::Controller();
// anything you want to do in every controller, ye shall perform here.
}
}
Then you'll be able to do this in your app controllers:
class Home extends Mega_Controller {
....
Since the extended controller class you created will be available. I think this is better then overwriting the base controller, but that would work as well.
I recommend to avoid "cracking" CodeIgniter core files.
Better use its native extending possibilities and try to fit into them.
The same rule I would recommend for any PHP library / CMS.
This rule has few reasons:
- ability to quiclky upgrade without takint into account thousands of notes where and how was cracked in core files;
- portability;
- possibility to share your code - eg, this will be usable by both you and your friends in case of need, and it will help them to keep their library up to date, the same as you.
In other words, this is much more professional and it pays to you in the future by usability, portability and by update application possibility.
Regarding your personal question...
As for me, there is nothing bad to create your own library with everything you need to extend native CodeIgniter Controller, then load this library in Controller's constructor and you are done. The only thing to make better usability is to give short name to your library.
This way you can even divide what you need in different pieces and put into separate libraries:
WebFeatures
AdminFeatures
etc.
Then you just load needed libraries in your controller's constructor and you are done.
P.S. I know that proposed way does not fit into "right" OOP concept, but in the same time you must never forget about the integrity of the libraries used.
Everything above is just one more view of mine 7-years experience in professional web development, so I hope it will be helpful if not to follow, then at least to take into account.
Regards,
Anton

Categories