Codeigneter : How to call model method from controller class? - php

I've recently started to learn OOP and Codeigniter. I've set up 2 new files in core; MY_Controller.php extending CI_Controller and MY_Model.php extending CI_Model. These files are both working, i'm able to call their methods in various controllers and models. However, I have a method in MY_Controller that checks if a user's logged in, if so it calls a method from MY_Model that updates the last active field in the user table. This method is working when I call it from say Login_model, but when I call it from MY_Controller it passes an error:
Call to undefined method Feed::update_last_active()
Why is this? I'm trying to call a core model from my core controller, should I not be doing this? Below is my code.
MY_Controller.php:
class MY_Controller extends CI_Controller{
public function __construct(){
parent::__construct();
}
/**
* Check if the users sessions logged in
*/
public function logged_in(){
//Check the flag logged_in exists in the session
if ($this->session->userdata('logged_in')){
//Update the last active field in the user db
$this->update_last_active($this->session->userdata('user_id'));
return true;
} else {
return false;
}
}
}
MY_Model.php:
class MY_Model extends CI_Model{
/**
* Updates users last active
*/
public function update_last_active($id){
$this->db->where('id', $id);
$this->db->update('users', array('last_active' => date('Y-m-d H:i:s')));
}
}
MY_Controller updated to #Tiger response (Returns Call to undefined method CI_Loader::update_last_active()):
public function logged_in(){
//Check the flag logged_in exists in the session
if ($this->session->userdata('logged_in')){
//Load my model
$my_model = $this->load->model('MY_Model');
//Update the last active field in the user db
$my_model->update_last_active($this->session->userdata('user_id'));
return true;
} else {
return false;
}
}

Controller file:
public function __construct(){
parent::__construct();
$this->load->model('My_Model'); //Load the Model here
}
public function logged_in(){
if ($this->session->userdata('logged_in')){
//Now Load Only Model Method
$my_model = $this->MY_Model->update_last_active();
$my_model->update_last_active($this->session->userdata('user_id'));
return true;
} else {
return false;
}
}

You didn't load the model in the controller, load the model in my_controller
public function __construct(){
parent::__construct();
//load the model
$this->load->model('My_Model');
}
This should solve the issue. logged_in function too have some errors, try loading the model in the _construct() first

Related

How to load a model in a master controller on codeigniter framework?

I am creating a master controller so that every other controllers on my app extend the master (MY_Controller).
My problem is how to make loading a model more abstract, let me show you the code to better explain.
class MY_Controller extends CI_Controller
{
protected $model;
function __construct()
{
parent::__construct();
}
function get($order_by)
{
$this->load->model($this->model);
$query = $this->$this->model->get($order_by);
return $query;
}
}
I declare a protected variable $model in the master controller so that on the extending controller i can asign it a value:
class Home extends MY_Controller {
public function __construct() {
parent::__construct();
$this->model = "home_model";
}
public function index()
{
$test = $this->get('id');
}
}
The problem is that on MY_Controller i cant load the model
$this->$this->model->get();
i get the following error: Message: Object of class Home could not be converted to string
any help will be appreciated , thank you !
Why do not save the value you assign to protected global $model variable in a variable inside the function as such:
class MY_Controller extends CI_Controller{
protected $model;
function __construct(){
parent::__construct();
}
function get($order_by){
$_model = $this->model // I added this line.
$this->load->model($_model); // I modified this line.
$query = $this->$_model->get($order_by); // I modified this line.
return $query;
}
}
The $this->$this->model->get() is your problem. If you want to use an object property ($this->model) inside a chain like this, you need to wrap it in braces: $this->{$this->model}->get().

CodeIgniter: Undefined property $db

In CodeIgniter 3.1.3 I extended CI_Model in application/core/MY_Model.php:
class MY_Model extends CI_Model {
public function __construct($id = NULL) {
parent::__construct();
$this->load($id);
}
public function load($id) {
$this->db->where('id', $id);
$this->db->limit(1);
$query = $this->db->query($this->_table);
if ($row = $query->result()) {
// #todo Process results
}
// Free the resources.
$query->free_result();
}
}
My User_model looks like this:
class User_model extends MY_Model {
public function __construct($id = NULL) {
parent::__construct($id);
}
}
I also extended the CI_Controller in application/core/MY_Controller as follows:
class MY_Controller extends CI_Controller {
public function __construct() {
parent::__construct();
$this->load->model('User_model');
}
}
I autoloaded the database connection in application/config/autoload.php as:
$autoload['libraries'] = array('database');
Without loading the User_model in the controller I was able to run migrations, so the database connection is configured correctly. But when I added $this->load->model('User_model') I get the error "Undefined property: User_model::$db".
If I let User_model extend CI_Model it runs without errors and with a var_dump in the homepage's controller it shows that the database is autoloaded correctly. But as soon as I put MY_Model in between, the database class is undefined in the model and also $this->load in the model returns NULL, so it appears the model is not properly constructed.
I can only imagine this to be a very small mistake, but I've been staring at it for hours with several breaks in between and I just don't see it. Can anyone else help me?
From a controller, lets say A_controller
$this->load->library('MyLib');
In MyLib, my original issue is this block
$ci = &get_instance();
$ci->load->model('my_model');
$this->active_model = $ci->my_model;
Then the miracle come when it become
$ci = &get_instance();
$ci->load->model('my_model');
$ci->my_model->db = & $ci->db;
$this->basic_model = $ci->my_model;
When CI loads a model $db property come along with CI.
So, when you call $this->db in model which means you want "my_model" have the property, right?
What I did just link the property from CI to my_model!!!

codeigniter global array for a model

In my controller I want to declare a global variable which will always fetch all areas from my db
currently I'm passing $data['dropdowns']
in all methods in my class
{
$data['dropdowns']=loading some other model method
$this->load->view('commons/header',$data);
}
{
$data['dropdowns']=loading some other model metod
$this->load->view('commons/header',$data);
}
{
$data['dropdowns']=loading some other model metod
$this->load->view('commons/header',$data);
}
{
$data['dropdowns']=loading some other model metod
$this->load->view('commons/header',$data);
}
the thing is I want to now send $data['area'] to all the views without having to declare it again and again in each method
$data['area']= $this->area_model->get_all_locations();
You want to add global variable , but as per my suggest to use global function to use any where to using to send parameter, so please check below my code.
Note : please load your model in application/config/autoload.php file
This is simple demo :
controller
{
$data['dropdowns']=$this->your_model_name->get_records('table_name','select field like id, name');
$this->load->view('commons/header',$data);
}
{
$data['dropdowns']=$this->your_model_name->get_records('table_name','select field like id, name,user_name');
$this->load->view('commons/header',$data);
}
Your model
function get_records($table_name,$field_name)
{
$this->db->select("$field_name");
$this->db->from("$table_name");
$query=$this->db->get();
return $query->result_array();
}
create a base_controller and placed in application/core
class base_controller extends CI_Controller
{
public $area = array();
function __construct()
{
// Call the Controller constructor
parent::__construct();
$this->get_area();
}
public function get_area() {
$this->load->model('area_model');
$this->area= $this->area_model->get_all_locations();
}
}
now $this->area is available in all controller which extends base_controller and all common functionality you can put here
class homepage extends base_controller{
function __construct()
{
// Call the Controller constructor
parent::__construct();
}
public function index()
{
$data = $this->area; // call this wherever u need
$this->load->view('commons/header',$data);
}
}
importantly $this->area; one can use directly inside view
Create a helper for your custom functions
Eg: custom_helper.php then load your custom helper in autoload.php
In custom_helper.php, create a function for getting area.
if (!function_exists('get_area')) {
function get_area() {
$CI = & get_instance();
$area= $CI->area_model->get_all_locations();
return $area;
}
}
You can call get_area() in your views without declaring in controllers..

Access an array in all views in codeigniter

I made an array in MY_Controller class placed on core folder. In its constructor i fetched records from db so as to make navigation menu in my views. Since i have different page layouts so i cannot call the same header view every where. for this reason i made a core class as per my understanding which i am not sure is right or not. below is the code for my controller
class MY_controller extends CI_Controller
{
function __construct()
{
parent::__construct();
$this->load->model('Category_model');
$data['parent'] = $this->Category_model->getParentCategories();
$data['child'] = $this->Category_model->getChildCategories();
}
}
my default controller is main
class Main extends MY_controller {
public function __construct()
{
parent::__construct();
}
public function index()
{
$this->load->view('home/header',$data);
$this->load->view('home/footer');
}
Now in my header view i am receiving undefined variable parent and child error. I want this two variables available in all the views so that i do not have to define those two variables in every controller.
Thanks
You may try something like this:
class MY_controller extends CI_Controller
{
$commonData = array();
function __construct()
{
parent::__construct();
$this->load->model('Category_model');
$this->commonData['parent'] = $this->Category_model->getParentCategories();
$this->commonData['child'] = $this->Category_model->getChildCategories();
}
}
Then use $this->comonData in your index method instead of $data to pass to the view:
public function index()
{
$this->load->view('home/header', $this->comonData);
$this->load->view('home/footer');
}
Now it'll be available in the header view and since it's at the top of other views then you may use it further, unless you override it with other value in any class.

is_logged_in check on every page

I am using CodeIgniter. I have a controller named abc and i has functions named index,a,bandc.
www.example.com/abc/
I want that user can only access the area he is logged in.
www.example.com/abc/ //if loggged in else back to homepage
or
www.example.com/abc/a/ //if loggged in else back to homepage
Now to check login. I use:
if($this->auth->is_logged_in()) { .. } else { redirect('/'); }
on every function individually.
Is there any other way to do so ??
I think you can do this by overriding the constructor and call your function in it.
<?php
class Blog extends CI_Controller {
public function __construct()
{
parent::__construct();
// check login
}
}
?>
For a particular controller you can put your if check in the constructor of the controller so that when any method of the controller is called it will pass through your if check
class Abc extends CI_Controller {
public function __construct()
{
parent::__construct();
//your if goes here
}
}
And if you want to check the user is logged in or not in the whole application you can use the constructor method __construct() of CI_Controller so it will be validated when user access any of the controllers within your application
class CI_Controller {
private static $instance;
/**
* Constructor
*/
public function __construct()
{
//your if goes here
}
}

Categories