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?
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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With