Codeigniter - load a model in my library - php

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 :)

Related

Codeigniter and Mongodb library - do I need a model?

I am trying my hand out with mongodb as a backend to my codeigniter application.
I found and followed this example: http://www.surfinme.com/codeigniter-mongodb/
So I have the following structure:
+application\
libraries\
Mongo_db.php
config\
mongodb.php
controllers\
api.php
This is what my api.php file looks like so far:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Api extends CI_Controller {
public function __construct()
{
parent::__construct();
//loading the mongodb library
$this->load->library('mongo_db');
}
public function index()
{
$data['main_content'] = "dashboard";
$this->load->view('includes/template',$data);
}
public function list_available()
{
//connect to mongodb collection (i.e., table) named as ‘surfinme_index’
$collection = $this->mongo_db->db->selectCollection('testcollection');
$result=$collection->find();
foreach($result as $data)
{
var_dump($data);
}
}
}
And the code seems to be working. It gets my data out of the database and dumps it to my browser. But this "feels" wrong becuase I don't have a model.
Or should I be viewing the library as my model layer?
I could just as easily create a file in the models folder called api_model and make the calls to the library from there.
But is that overkill?
Any comments would be appreciated.
Thanks.
Depends on how tightly you want to adhere to MVC principals.
By creating a model for database operations you get several potential benefits. First, it provides a source that can be reused by multiple controllers. For example, there may be more than one controller that uses selectCollection. Second, if for some reason you decide to change databases you only have to modify the Models as opposed to every controller that makes calls to mongo_db.

Codeigniter - Extending my own controllers

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(){
}
}

CodeIgniter : Using both core classes and extended classes ?

I'm currently working on CI for my website, and i'm having some trouble about extending Controller_CI.
I have one controller that deals with login/signin actions, which doesn't need authentication, and others controllers that check if a user session exists before loading content.
For that purpose, I created MY_Controller class and add authentication code in the constructor.
Then I made all my controller extend MY_Controller, except the first one that still extends Controller_CI
My question is : Is it the right way to deals with authentication ? Is it still possible to use Controller_CI even if it's extended ?
I found another pattern :
http://philsturgeon.co.uk/blog/2010/02/CodeIgniter-Base-Classes-Keeping-it-DRY
I guess it's better, but still, I don't understand why not using the first solution.
Thanks
Extending controller class for that purpose will work, but this solution is not much flexible. I would rather create a library that handles authentication, and run it from a controller when it is desired. Please read http://ellislab.com/codeigniter/user-guide/general/creating_libraries.html for details about creating custom libraries in CI.
Please remember you can only extend the CI_Controller with MY_Controller only once. In that aspects it's not a good idea. Suppose you want to implement another feature (e.g. a piece of code that makes a specific entry in the log) for some controllers, but not necessarily the controllers that need authentication you cannot make another MY_Controller.
Using a library is a better thing.
I'm using the flexi auth library on a big CI site. On every controller that requires authentication I just add the following:
public function __construct() {
parent::__construct();
$this->load->library('flexi_auth');
if (!$this->flexi_auth->is_logged_in())
redirect('auth/login');
}
I think a combination of what Phil Sturgeon suggests in that blog post and using a library would be best. So I would create a core controller (by that I mean a controller you place into application/core that extends CI_Controller) called MY_Controller which will look something like this
class MY_Controller extends CI_Controller
{
function __construct()
{
parent::__construct();
}
//Any other functions you want
}
Then judging by your question you currently have controllers that fit into two categories
Controllers that do require a logged in user before they do
anything
Controllers that don't require a logged in user before they do anything
So I would then create another controller in the /application/core directory that extends MY_Controller but in its constructor it checks to see if the user is logged in
class Auth_Controller extends My_Controller
{
function __construct()
{
parent::__construct();
//Check to see if the user is logged in
$this->load->library('authentication');
if(!$this->authentication->user_logged_in())
{
redirect('/login');
}
}
//Any other functions you want
}
Now when you create you controller you can choose which one of the core controllers you want to extend. If its a controller than doesn't require a logged in user you can extend MY_Controller but if it does required a logged in user you can extend Auth_Controller. That way it means you only need to do the user login check once in your code.
Like others have said if may be a good idea to place any authentication code into a library as that's a better place to put it than in a controller.
Summary
So to summarise by having all of your controllers extend core controllers rather than CI_Controller it should cut down on code repetition.
I also currently working on a CI project and had the same issue. I have came up with a different solution to deal with the authentication.
I extended the core controller as bellow,
class MY_Controller extends CI_Controller
{
public $data = array();
public $calledClass ;
public $calledMethod ;
public function __construct()
{
parent::__construct();
$authException['authentication']['login'] = true;
$authException['authentication']['logout'] = true;
$authException['welcome']['index'] = true;
$this->load->library("router");
$this->calledClass = $this->router->fetch_class();
$this->calledMethod = $this->router->fetch_method();
if(!#$authentication[$this->calledClass][$authentication->calledMethod] && !Auth::isUserLoggedIn())
{
# IS_AJAX is a contant defined in the contants.php
# define('IS_AJAX', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');
if(IS_AJAX)
{
# if this is an AJAX call, it sets a value in the header ,
# which can be captured in the AJAX response
# to redirect the user to the login page.
$this->output->set_header("auth-him:1");
exit;
}
else
{
redirect("authentication/login");
}
}
}
}
Hope the code above is clear and this helps.
To extend core controller more than one time, If you still need to use 2 controllers to handle authentication, I have followed this method
https://stackoverflow.com/a/22125436/567854
Hope this also helps :)

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.

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