Autoload controller in CodeIgniter - codeigniter

I have question to you.
I try add to my page calendar and some events in this calendar. I know how I can load calendar in page, but I didn`t now how I can load this calendar on every page automatically.
Controller:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Calendar extends CI_Controller {
function index()
{
$data = array(
3 => 'Polska - Anglia',
);
$this->load->library('calendar');
$vars['calendar'] = $this->calendar->generate('', '', $data);
$this->load->view('main/calendar', $vars);
}
}
and In view I call:
<?php echo $calendar;?>
I use CodeIgniter 2.1.3

Instead of creating controller for calendar, create a library class and then add it to autoload configuration file
class MyCalendar{
public function get()
{
$CI =& get_instance();
$data = array(
3 => 'Polska - Anglia',
);
$CI->load->library('calendar');
return $CI->calendar->generate('', '', $data);
}
}
Add this library to autoload file and then you can call it anywhere you want by using this statement.
$data['calendar'] = $this->MyCalendar->get();

You can autoload your library by changing the application/config/autoload.php file.
Find :
$autoload['libraries'] = array();
Replace by :
$autoload['libraries'] = array('calendar');
To load the same calendar on all your pages, I suggest to build a parent controller in the application/core folder.
abstract class BaseController extends CI_Controller
{
protected $data;
public function __construct()
{
parent::__construct();
$this->data = array();
$calendarData = array(
3 => 'Polska - Anglia'
);
$this->data['calendar'] = $this->calendar->generate('', '', $calendarData);
}
}
You can then extend that BaseController class on all your controllers.
class Calendar extends BaseController {
function index()
{
$this->load->view('main/calendar', $this->data);
}
}
Be sure to always use $this->data to build on the protected member of your class.
Lastly, your BaseController will not be autoloaded, you probably don't want to include it everywhere. I suggest you to add the following method at the end of your autoload or config file.
/**
* Extra autoload function. Loads core classes automatically.
* #param type $class The class to load.
*/
function __autoload($class)
{
if (strpos($class, 'CI_') !== 0)
{
if (file_exists($file = APPPATH . 'core/' . $class . EXT))
{
include $file;
}
}
}
This will allow you to autoload any classes you have in your application/core folder. This solution might seems complex, but once it's setup. You can add functionality to your BaseController that is applicable for all pages, for example, header and footer stuff.
Hope this helps!

Related

Data available for all views in codeigniter

I have a variable, contaning data that should be present in the entire site. Instead of passing this data to each view of each controller, I was wondering if there is a way to make this data available for every view in the site.
Pd. Storing this data as a session variable / ci session cookie is not an option.
Thanks so much.
Create a MY_Controller.php file and save it inside the application/core folder. In it, something like:
class MY_Controller extends CI_Controller {
public $site_data;
function __construct() {
parent::__construct();
$this->site_data = array('key' => 'value');
}
}
Throughout your controllers, views, $this->site_datais now available.
Note that for this to work, all your other controllers need to extend MY_Controllerinstead of CI_Controller.
You need to extend CI_Controller to create a Base Controller:
https://www.codeigniter.com/user_guide/general/core_classes.html
core/MY_Controller.php
<?php
class MY_Controller extend CI_Controller {
public function __construct() {
parent::__construct();
//get your data
$global_data = array('some_var'=>'some_data');
//Send the data into the current view
//http://ellislab.com/codeigniter/user-guide/libraries/loader.html
$this->load->vars($global_data);
}
}
controllers/welcome.php
class Welcome extend MY_Controller {
public function index() {
$this->load->view('welcome');
}
}
views/welcome.php
var_dump($some_var);
Note: to get this vars in your functions or controllers, you can use $this->load->get_var('some_var')
Set in application/config/autoload.php
$autoload['libraries'] = array('config_loader');
Create application/libraries/Config_loader.php
defined('BASEPATH') OR exit('No direct script access allowed.');
class Config_loader
{
protected $CI;
public function __construct()
{
$this->CI =& get_instance(); //read manual: create libraries
$dataX = array(); // set here all your vars to views
$dataX['titlePage'] = 'my app title';
$dataX['urlAssets'] = base_url().'assets/';
$dataX['urlBootstrap'] = $dataX['urlAssets'].'bootstrap-3.3.5-dist/';
$this->CI->load->vars($dataX);
}
}
on your views
<title><?php echo $titlePage; ?></title>
<!-- Bootstrap core CSS -->
<link href="<?php echo $urlBootstrap; ?>css/bootstrap.min.css" rel="stylesheet">
<!-- Bootstrap theme -->
<link href="<?php echo $urlBootstrap; ?>css/bootstrap-theme.min.css" rel="stylesheet">
If this is not an Variable(value keep changing) then I would suggest to create a constant in the constant.php file under the config directory in the apps directory, if it's an variable keep changing then I would suggest to create a custom controller in the core folder (if not exist, go ahead an create folder "core") under apps folder. Need to do some changes in other controller as mentioned here :
extend your new controller with the "CI_Controller" class. Example
open-php-tag if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class LD_Controller extends CI_Controller {
}
close-php-tag
Here LD_ is my custom keyword, if you want to change you can change it in config.php file under line# 112 as shown here : $config['subclass_prefix'] = 'LD_';
and extend this class in all your controllers as "class Mynewclass extends LD_Controller..
And in LD_controller you've to write the method in which you want to define the variable/array of values & call that array in all over the application as shown here :
defining variable :
var $data = array();
Method to get values from db through the Model class:
function getbooks()
{
$books = $this->mybooks_model->getbooks(); //array of records
$this->data = array('books'=>$books);
}
to call this variable in the views : print_r($this->data['books']);); you will get all the array values... here we've to make sure atleast one "$data" parameter needs to be passed if not no problem you can define this $data param into the view as shown here :
$this->load->view('mybookstore',$data);
then it works absolutely fine,,, love to share... have a fun working friends
you can use $this->load->vars('varname', $data);[ or load data at 1st view only] onse and use in any loaded views after this
Use sessions in your controllers
$this->session->set_userdata('data');
then display them in your view
$this->session->userdata('data');
Or include a page in base view file e.g index.php
include "page.php";
then in page.php,
add $this->session->userdata('data'); to any element or div
then this will show on all your views
I read all answers, but imho the best approch is via hook:
Create hook, let's get new messages for example:
class NewMessages {
public function contact()
{
// Get CI instance CI_Base::get_instance();
$CI = &get_instance(); // <-- this is contoller in the matter of fact
$CI->load->database();
// Is there new messages?
$CI->db->where(array('new' => 1));
$r = $CI->db->count_all_results('utf_contact_requests');
$CI->load->vars(array('new_message' => $r));
}
}
Attach it to some of the flow point, for example on 'post_controller_constructor'. This way, it will be loaded every time any of your controller is instantiated.
$hook['post_controller_constructor'][] = array(
'class' => 'NewMessages',
'function' => 'contact',
'filename' => 'NewMessages.php',
'filepath' => 'hooks',
'params' => array(),
);
Now, we can access to our variable $new_message in every view or template.
As easy as that :)
You could override the view loader with a MY_loader. I use it on a legacy system to add csrf tokens to the page where some of the forms in views don't use the builtin form generator. This way you don't have to retrospectively change all your controllers to call MY_Controller from CI_Controller.
Save the below as application/core/MY_Loader.php
<?php
class MY_Loader extends CI_Loader {
/**
* View Loader
*
* Overides the core view function to add csrf token hash into every page.
*
* #author Tony Dunlop
*
* #param string $view View name
* #param array $vars An associative array of data
* to be extracted for use in the view
* #param bool $return Whether to return the view output
* or leave it to the Output class
* #return object|string
*/
public function view($view, $vars = array(), $return = FALSE)
{
$CI =& get_instance();
$vars['csrf_token'] = $CI->security->get_csrf_hash();
return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_prepare_view_vars($vars), '_ci_return' => $return));
}
}

HMVC MX_Controller not loading CI' _output function

Normally, extending CI_Controller lets you use the function _output for rendering html outputs.
I'm using HMVC. MX_Controller doesn't load _output function.
I've tested it and run a couple of times.
Questions:
1 - Does MX_Controller inherits CI_Controller?
2 - How can I implement _output?
It seems like codeigniter-modular-extensions-hmvc does indeed break the _output() functionality. I can't figure out how to submit the bug on bitbucket: https://bitbucket.org/wiredesignz/codeigniter-modular-extensions-hmvc
My workaround involved overriding the Output class & adding a hook to fire a custom output method. Here's what I did.
Overwrite the main Output class:
class MY_Output extends CI_Output
{
function __construct()
{
parent::__construct();
}
// Overwrite the output
public function my_output()
{
$content = $this->get_output();
// do stuff to $content here
$this->set_output($content);
$this->_display();
}
}
Then enable hooks in your config.
$config['enable_hooks'] = TRUE;
Then add this to your hooks config.
$hook['display_override'][] = array(
'class' => '',
'function' => 'custom_output',
'filename' => 'custom_output.php',
'filepath' => 'hooks'
);
Finally add the "custom_output.php" file to your hooks directory and add this.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/*
* Customize the output
*/
function custom_output()
{
$CI =& get_instance();
$CI->output->my_output();
}
If you don't need to access any class variables, you can just edit the output right in the custom_output() function and not worry about overriding the Output class.
Very hacky, but it works. :)

Autoload libraries in Codeigniter

I am a newbie to Codeigniter.
I have 3 libraries in autoload in config.php .
But in one of my controllers I don't want to load the libraries. Is this possible?
If you need any library throughout the application you can load it in the config file and it will be auto loaded. But if you need a library only in a specific controller you can load it in the controller where you need it.
Class test Extends CI_Controller{
function index()
{
$this->load->library('mylibrary');
$this->mylibrary->somemethod();
}
}
Or if you need library through out the controller you can load it in the constructor.
Class test Extends CI_Controller{
function __construct()
{
parent::__construct();
$this->load->library('mylibrary');
}
function index(){
$this->mylibrary->somemethod();
}
function test(){
$this->mylibrary->someothermethod();
}
}
Extend CI_Controller in your libraries.
Something like this:
class MyLibrary extends CI_Controller {
var $ci;
function __construct() {
$this->ci = &get_instance();
$route = $this->ci->router->fetch_class();
if( $route == strtolower('YourController') ) return false;
}
}
you can remove libraries from autoload file. then they will not be activ in the framwork.
If you want to use them, you can call them in constructors if you want them in a class. If you want to use them in just method, you load them in the method.

how can i make my own $this->load->view in codeigniter

the default of CI of loading views is:
$this->load->view('path');
but what if i wanted to do something like
$this->load->adminView('path')
then i can prefix the path in adminView followed by the path
how would i do this?
thanks
go to ../System/Core/Loader.php, line 417 -> 210 (CI 2.10)
public function view($view, $vars = array(), $return = FALSE)
{
return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_return' => $return));
}
change your function name (and maybe some code else) as you wish, be careful!
In application/core/ make a new Controller:
<?php
if(!defined('BASEPATH'))
exit('No direct script access allowed');
class Admin_Controller extends CI_Controller
{
function __construct()
{
parent::__construct();
}
function load_admin_view($path, $data = '', $return = false)
{
return $this->load->view("admin_dir/" . $path, $data, $return);
}
}
?>
Then make your current controller extend this controller:
class Page extends Admin_Controller
Instead of
class Page extends CI_Controller
Then you can use:
$this->load_admin_view("path");

Call to a member function insert() on a non-object, codeigniter

I am trying to insert data to mysql in codeigniter. Controller class :
class Ci_insert extends CI_Controller
{
function __construct()
{
parent::__construct();
}
function index()
{
$data = array(
"USN" => "TRE5rCS89G",
"name" => "NITISH DOLAKASHARIA",
"branch" => "CS"
);
$this->load->model('ci_insert_model');
$this->ci_insert_model->addToDb($data);
}
}
Model Class :
class ci_insert_model extends CI_Model
{
function __construct()
{
parent::__construct();
}
function addToDb($data)
{
//var_dump($data);
$this->db->insert('class_record',$data);
}
}
But when I tried to run the code, it shows Fatal error: Call to a member function insert() on a non-object in C:\wamp\www\CodeIgniter\application\models\ci_insert_model.php on line 12.
Whats wrong with the code above?
You're missing $this->load->database();
$this->db->method_name(); will only work when the database library is loaded.
If you plan on using the database throughout your application, I would suggest adding it to your autoload.php in /application/config/.
As others have mentioned, remove the CI_ prefix from your class names. CI_ is reserved for framework classes.
You have to use '$this->load->library('database')' in the model before '$this->db->insert()' or
autoload the database library. Go to config folder select autoload.php search for $autoload['libraries'] and replace your empty array() with array('database').
Add autoload libraries in config folder open autoload.php and set $autoload['libraries'] = array('database');
Try out.
Controller : insert.php
class Insert extends CI_Controller
{
function __construct()
{
parent::__construct();
}
function index()
{
$data = array(
"USN" => "TRE5rCS89G",
"name" => "NITISH DOLAKASHARIA",
"branch" => "CS"
);
$this->load->model('insert_model');
$this->insert_model->addToDb($data);
}
}
Model: insert_model.php
class Insert_model extends CI_Model
{
function __construct()
{
parent::__construct();
}
function addToDb($data)
{
//var_dump($data);
$this->db->insert('class_record',$data);
}
}
Please write capital first latter of class, don't add prefix like ci_.

Resources