spacemud
spacemud

Reputation: 675

Passing a variable from MY_Controller to a view

On my website I have a 'login prompt' which is visible on every page. I'm using a templating system so this login prompt is present in the header of each page.

When a user is logged in it should show their username and a link to logout. When they're not logged in a link to either login or register is shown.

I have a function in MY_Controller which checks if the user is logged in on every page load which works fine:

if($this->is_logged_in()) {
    $this->username = $this->session->userdata('username');
    $data['login_prompt'] = "Hi, " . $this->username . " " . anchor("account/logout", "Logout");
}

And in my header.php (the view) I have:

<div id="login-prompt" class="transparent">
    <?php
        if (!isset($login_prompt)) $login_prompt = anchor("account/login", "Login") . " or " . anchor("account/register", "register");
        echo $login_prompt;
    ?>
</div>

The problem is in my controllers. Here is the constructor of ucp.php, which extends MY_Controller:

public $data;

function __construct()
{
    parent::__construct();
    $data['login_prompt'] = $this->data['login_prompt'];
}   

I would like $data['login_prompt'] to be available in each method of my controller so it can be passed to the view. However, printing $data['login_prompt'] gives an error of 'undefined index' and as a result the default "Login or register" message as defined in header.php is always visible.

A typical method in ucp.php would be as follows:

function index()
{
    $this->template->build("ucp/ucp_view", $data);
}

As you can see the $data array should be passed to the view. If I were to define $data['login_prompt'] in the method itself instead of the constructor such that:

function index()
{
    $data['login_prompt'] = $this->data['login_prompt'];
    $this->template->build("ucp/ucp_view", $data);
}

The login prompt changes to the correct, logged-in, message. However I'd rather not add this line to every method of every controller in my application.

A similar problem I have found involves simply changing the $data array passed to the view to $this->data, outlined here. This works but breaks several other parts of my application.

I feel like the mistake is something really obvious. What am I doing wrong?

Upvotes: 3

Views: 1609

Answers (3)

Pete Mitchell
Pete Mitchell

Reputation: 2879

You have a couple of options

You can use a $this->data property on your MY_Controller and then make sure you pass $this->data to all your views

// MY_Controller
public $data;

public function __construct()
{
    if($this->is_logged_in()) 
    {
        $this->username = $this->session->userdata('username');
        $this->data['login_prompt'] = "Hi, " . $this->username . " " . anchor("account/logout", "Logout");
    }
}

And then in our controller..

// An example controller. By extending MY_Controller 
// We have the data property available
UcpController extends MY_Controller
{
    public function __construct()
    {
        parent::__construct();
    }

    public function index()
    {
        $this->data['Some extra variable'] = 'Foo';
        // Notice we are giving $this->data rather than $data...
        // this means we will have our login prompt included
        // as it is set by the parent class
        $this->template->build("ucp/ucp_view", $this->data);
    }
}

Alternatively you can set up a global array in MY_Controller and then use the load->vars method to make the array available to all your views

// MY_Controller
public $global_data;

public function __construct()
{
    if($this->is_logged_in()) 
    {
        $this->username = $this->session->userdata('username');
        $this->global_data['login_prompt'] = "Hi, " . $this->username . " " . anchor("account/logout", "Logout");

        $this->load->vars($this->global_data);
    }
}

Upvotes: 2

Joe Flynn
Joe Flynn

Reputation: 7204

Try switching $data['login_prompt'] to $login_prompt in your view.

The error message 'undefined index' is referring to 'login_prompt' not being an index in the associative array $data. Code igniter breaks up that array you pass to $this->load->view(). Similar to how extract() works (php docs, ci docs).

Upvotes: 1

MDEV
MDEV

Reputation: 10838

http://codeigniter.com/user_guide/general/views.html

Scroll about halfway down to "Adding Dynamic Data to the View"

Upvotes: 0

Related Questions