Welcome Guest, Not a member yet? Register   Sign In
How to use variables from class globally in views
#1

[eluser]mabright[/eluser]
I am working on a new site and I am new to CI. I have a controller called messages that contains a variable called $inbox_count that contains the number of inbox messages in the database for the logged in user.

I can retrieve the variable fine in my messages view which is called from my messages controller but when I try to use the variable in my user navigation menu to display to the user if there are new messages (i.e. if the user is on another page other than the message center, the navigation bar would display the number of messages next to the inbox link.

I.e. Navigation menu bar: Home | Account | (2) Inbox | Order Overview |
---------------------------------------------

I tried calling $this->messages->inbox_count and $this->messages->get_inbox_count() from within my template page that contains the navigation menu code but I get the below error.

Fatal error: Call to a member function get_inbox_count() on a non-object in....


Code:
<?php
class Messages extends Controller {
    
    var $inbox_count = 0;
    var $sent_count  = 0;
    var $trash_count = 0;
    
    public function __construct()
    {
        parent::Controller();
        
        $this->load->model('member/Messages_model');
        
        $this->load->library('input');                
        $this->load->library('form_validation');        
        $this->form_validation->set_error_delimiters('<span class="input_error">', '</span>');
        
        $this->inbox_count = $this->Messages_model->get_folder_count('INBOX');
        $this->sent_count = $this->Messages_model->get_folder_count('SENT');
        $this->sent_count = $this->Messages_model->get_folder_count('TRASH');
    }

    public function index()
    {
        if($this->session->userdata('logged_in') != TRUE)
      {
          redirect('member/login');
      }      
        $this->_display();
    }

    public function inbox()
    {
        $this->inbox_count = $this->Messages_model->get_folder_count('INBOX');
        $this->_display();
    }
    ................
#2

[eluser]Colin Williams[/eluser]
In the controller constructor, pass these "global" template variables with $this->load->vars()

If you need to do this across many controllers, extend the base Controller class with a MY_Controller class (using your own prefix) and do it in the constructor there.

You can read more about all of this in the User Guide and the Wiki
#3

[eluser]mabright[/eluser]
Is there another way to accomplish this? Like a dynamic global variable? I have a sub folder under controllers caller member and I need all classes here to know what $inbox_count is.
#4

[eluser]laytone[/eluser]
Fast Answer:

Create a class called MY_Controller in your libraries folder

and create a function that retrieves your message count so like this:

Code:
class MY_Controller extends Controller {
  function MY_Controller(){
    parent::Controller();
  }

  function _get_mailbox_count($mailbox){
    $this->load->model('member/Messages_model');
    return $this->Messages_model->get_folder_count($mailbox);
  }
}

Now your controller:

Code:
class Messages extends MY_Controller {
  function Message(){
   parent::MY_Controller();
  }

  function Anyfunction(){
    $inbox_count = $this->_get_mailbox_count('INBOX');
    $sentbox_count = $this->_get_mailbox_count('SENT');
    //etc...
  }
}

Doing this will solve your problem.


This is how I set up my controllers. Notice I crate a _showPage function to load my template and views, this way I can make sure I can send any variables I want to my pages plus I can make sure views get loaded with a set of pre-defined variable plus the new ones I send to it. _showPage is always avail in any controller as long as my controller extends MY_Controller and not Controller

First I extend the controller like this:

Code:
class MY_Controller extends Controller {
    
    var $current_controller;
    var $current_method;
    var $default_image_folder = '';
    var $default_css_folder = '/css/';
    
    public function __construct(){
        parent::Controller();
        $this->current_controller = $this->uri->segment(1);
        $this->current_method = $this->uri->segment(2);
//I get my controller name and that is the same as the 'view' folder
    }
    
    function _showpage($pagename = '', $pagedata = array(), $pagetitle = "Default Page Title", $controller = ''){
        $controller = ($controller == '') ? $this->current_controller : $controller;
        
        $pagedata['page_title'] = 'Sitename - '.$pagetitle;
        $pagedata['css_folder'] = $this->default_css_folder;
        $pagedata['images_folder'] = $this->default_image_folder;
        $pagedata['message'] = (!isset($pagedata['message'])) ? $this->session->flashdata('message') : $pagedata['message'];
        $pagedata['page_body'] = $this->load->view($controller.'/'.$pagename, $pagedata, TRUE);
        $pagedata['top_menu'] = $this->load->view('template/top_nav', $pagedata, TRUE);
        $pagedata['side_bar'] = $this->load->view($controller.'/side_bar', $pagedata, TRUE);
        $this->load->view('template/default.php', $pagedata);
    }
}

Use the constructor to load the values that you need between all of your pages. Then add values to the $pagedata array (before you load the views for nave and body). Like this:

Code:
...
function __construct(){
  $this->load->model('Message_model');
  $this->inbox_count = $this->Message_model->get_message_count('inbox');
}
function _showPage(...){
   ...
   //I would add a line like this:
   $pagedata['inboxcnt'] = $this->inbox_count();
}

Now your regular controllers just extend MY_Controller instead of Controller and you call the _showPage() function to load you views and you global variables are always available to you in any you views.

This method words great for templates and stuff

Hope I helped, This is the best way to do this (even if you don't use a _pageload function like I like to.... Like the guy said before me.. extend your controller and load the variables with a constructor.

Layton
#5

[eluser]mabright[/eluser]
Thanks for the detailed explanation. This resolved my issue.
#6

[eluser]laytone[/eluser]
You are welcome, I'm glad I could help.




Theme © iAndrew 2016 - Forum software by © MyBB