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.
Related
I have a Controller called Stats which is responsible to get some stats and show them in my application.
Stats.php:
<?php
class Stats Extends CI_Controller{
public function index()
{
$this->load->model('Stats_model');
$return['users'] = $this->Stats_model->get_users();
$return['photos'] = $this->Stats_model->get_photos();
$return['members'] = $this->Stats_model->get_members();
$this->load->view('stats',$return);
}
}
In my application i have 3 total views with their controllers. Home,About,Contact - Home_controller, About_controller, Contact_controller.
In start of any of these 3 views i have a section which i want to place the the stats. So the stats will be visible in any page of my application.
How can i load a view (stats) to take data from a controller (Stats) without calling it? When the home view called then the Home controller called , NO the stats.
I don't want to call a separate stats page. I want the stats to be visible in top of any page in my app. How can i achieve that in CI?
Thanks
You can customize CI_Controller by adding MY_Controller in directory ./application/core/ and move the codes in Stats controller into it's constructor
like:
<?php
class MY_Controller Extends CI_Controller
{
protected $_stat_view;
public function __construct()
{
$this->load->model('Stats_model');
$return['users'] = $this->Stats_model->get_users();
$return['photos'] = $this->Stats_model->get_photos();
$return['members'] = $this->Stats_model->get_members();
//specify true to view's third parameter will make it return
//view content instead of render and display it on browser
$this->_stat_view = $this->load->view('stats',$return, true);
}
}
And then your Home,About,Contact controller need extends this new MY_Controller
<?php
class Home_Controller extends MY_Controller
{
public function __construct()
{
parent::__construct();
}
public function index()
{
$data[stats_section] = $this->_stat_view;
//In home view just echo $stat_section
$this->load->view('home', $data);
}
}
FYI you can modify prefix MY_ in ./application/config/config.php, set what prefix name you like to config item $config['subclass_prefix'].
I have the following controller structure:
with the following code:
MAIN CONTROLLER:
class MY_Controller extends CI_Controller {
public function __construct() {
parent::__construct();
$this->load_defaults();
}
public function load_defaults() {
}
}
CHILD CONTROLLER 1:
class Child1 extends MY_Controller {
public function __construct() {
parent::__construct();
$this->main();
}
public function main() {
echo "function in Child Controller 1";
}
}
CHILD CONTROLLER 2:
class Child2 extends MY_Controller {
public function __construct() {
parent::__construct();
$this->main();
}
public function main() {
echo "function in Child Controller 2";
}
}
My question: How do I call a function located in Child1 controller, from the Child2 controller?
If you have to call a controller from another controller, you're doing it wrong. Controllers are there to accept URI requests from the client.
Please try to revisit the problem and see if you can move the common logic to MY_Controller - it will be accessible because all other controllers extending it.
Also a model will be good place to have common functions that will be called from controllers.
I think what you are looking for is redirect. Considering that by CI convention each controller function should be an endpoint for the user, if you want to access a function from another controller then what you are really trying to do is redirect them to that controller.
function someEndPoint(){
$this->load->helper('url');
redirect('someOtherEndPoint', 'refresh');
}
I am trying to get scroll news in any page of the website from database without having to pass the variable in every controller of the site. So I decided to use hooks instead of passing scroll variable in every controller.
I did create a class like this
class Scroll
{
function getScroller()
{
$data = array();
$CI =& get_instance();
$CI->db->where('a_status','active');
$CI->db->limit(4);
$CI->db->order_by('id','desc');
$Q = $CI->db->get('news');
if($Q->num_rows() > 0){
foreach($Q->result_array() as $row){
$data[] = $row;
}
}
$Q->free_result();
return $data;
}
}
What I get now is
Severity: Notice
Message: Trying to get property of non-object
Call to a member function get() on a non-object in E:\xampp\htdocs\
Can anyone please help me how to do this ? Thanks I want to get scrollernews in any controller's view automatically without having to pass in each controller. Thanks
If you are defining that on a view level, there is no need for that.
You can define db requests directly in a view.
Other approach would be to have separated controller which with separate view and load it in the page through iframe. It's often used for "web widgets" that can be later on loaded in to another pages.
Extending the core class of CI Controller will should cause you less troubles.
http://ellislab.com/codeigniter/user-guide/general/core_classes.html
application/core/MY_Controller.php
class MY_Controller extends CI_Controller {
public function __construct() {
parent::__construct();
//By do this, all controllers who use this class as parent controller
//will have $news in their views
$this->load->vars(array(
'news' => array()
));
}
}
application/controller/welcome.php
class Welcome extends MY_Controller {
public function index()
{
$this->load->view('welcome_message');
}
}
application/views/welcome_message.php
var_dump($news);
use separated library or helper and call that method on controller's constructs like :
class My_Controller extends CI_Controller(){
function __construct(){
parent::__construct();
//load your library
//call your library method
}
}
In my project, I have one search section with 3 select box. I passed the value to it using
$data['restaurant_all']=$this->restaurant_model->get_all('','','','','','yes')->result();
$data['state_all']=$this->state_model->get_all();
$data['menu_all']=$this->menu_model->get_all('all','','','','','','yes')->result();
$data['restaurant']=$this->input->post('restaurant');
$data['state']=$this->input->post('area');
$data['food_type']=$this->input->post('menu');
I need this statement in all my pages. In there any way to accomplish this without writing these statements in all the pages
a. extend the default controller by creating a file MY_Contoller.php at a suitable location.
b. create a custom class that will extend the default controller.
c. add a protected or public variable $data to custom class.
e. do something with data using __construct()
d. make every controller extend the custom controller.
e. you can access this variable like any other class variable.
example code:
MY_Controller.php
class APP extends CI_controller {
protected $data;
function __construct() {
parent::__construct();
$this->_init();
}
function _init() {
$this->data['state'] = $this->input->post('area');
}
}
normal controllers:
class Welcome extends APP {
function __construct() {
parent::__construct();
}
function view() {
/* pass this data value like normal data param */
$this->load->view('some_view', $this->data);
}
}
hope it helps.
Use constants, in /config/constants.php
I want to create two parent controllers: one for admin and one for user site. They have to extend a regular Controller class but each of them has to do different things.
I wrote up an article showing how you do this.
http://philsturgeon.co.uk/news/2010/02/CodeIgniter-Base-Classes-Keeping-it-DRY
You need to create an __autoload() function in your config.php or directly include the base controller above the class definition.
This is pretty easy. 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 MY_Controller.php 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();
}
}