0
votes

I'm working on a Social Network app. I'm facing a problem in which I'm trying to get the name and username from a table called users in my database. To be able to do this without accessing to all the controllers individually I had to create a Core controller with the name of MY_Controller.

Here is the problem(MY_Controller without the public $users):

<?php

class MY_Controller extends CI_Controller
{

//public $users = array('username' => $this->input->post('username')); 


    function __construct()
    {
        parent::__construct();

        //Get user data to make it available for both Admin and Public Controllers
        $this->load->model('User_model');
        $this->users = $this->User_model->get_list();

        //Load Menu Library
        $this->load->library('menu');
        $this->pages = $this->menu->get_pages();

        // Brand/Logo
        $this->favicon = 'https://blogpersonal.net/wp-content/uploads/2017/08/favicon-v2-150x150.png';
        $this->brand = 'Some Name';
        $this->description = 'Some Description';
        $this->credits = 'https://blogpersonal.net/';
        $this->version = '1.1.1';
    }
}

class Admin_Controller extends MY_Controller
{

    function __construct()
    {
        parent::__construct();

        if (!$this->session->is_admin) {
            redirect('admin/login');
        }

        //some code here

    }
}

class Public_Controller extends MY_Controller{
    function __construct(){
        parent::__construct();

        //some code here

    }

}

class Social_Controller extends MY_Controller
{

    function __construct()
    {
        parent::__construct();

        if (!$this->session->is_member) {
            redirect('dashboard/login');
        }

        //some code here

    }
}

As you can see I loaded the User_model using the __construct function to make it available and use it in all controllers.

I want to fetch data in a folder called templates. views>templates>any document but when I try to fetch it in a view like this:

    <?php if($this->users) : ?>
        <li class="dropdown user user-menu">
          <!-- Menu Toggle Button -->
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">
            <!-- The user image in the navbar-->
            <img src="<?php echo base_url(); ?>assets/img/user2-160x160.jpg" class="user-image" alt="User Image">
            <!-- hidden-xs hides the username on small devices so only the image appears. -->
            <span class="hidden-xs"><?php echo $this->users['username']; ?></span>
          </a>

        </li>
    <?php endif; ?>

THIS IS THE OLD ERROR. it shows me an error. Am I doing something wrong? Can somebody explain me how to fix it. This is the first time in which I'm unable to fetch data. This is the result that I get:

A PHP Error was encountered

Severity: Notice

Message: Undefined variable: users

Filename: Templates/public.php

Line Number: 161

Backtrace:

File: C:\xampp\htdocs\codeigniter\application\views\Templates\public.php Line: 161 Function: _error_handler

File: C:\xampp\htdocs\codeigniter\application\libraries\Template.php Line: 34 Function: view

File: C:\xampp\htdocs\codeigniter\application\controllers\Pages.php Line: 12 Function: load

File: C:\xampp\htdocs\codeigniter\index.php Line: 315 Function: require_once

Here is my model(User_model) in case you might need it:

<?php

class User_model extends CI_MODEL
{

    function __construct()
    {
        parent::__construct();
        $this->table = 'users';
    }

    public function get_list()
    {
        $query = $this->db->get($this->table);
        return $query->result();
    }

    public function get($id)
    {
        $this->db->where('id', $id);
        $query = $this->db->get($this->table);
        return $query->row();
    }

    public function add($data)
    {
        $this->db->insert($this->table, $data);
    }

    public function update($id, $data)
    {
        $this->db->where('id', $id);
        $this->db->update($this->table, $data);
    }

    public function delete($id)
    {
        $this->db->where('id', $id);
        $this->db->delete($this->table);
    }

    public function login($username, $password)
    {
        $this->db->select('*');
        $this->db->from($this->table);
        $this->db->where('username', $username);
        $this->db->where('password', $password);
        $this->db->limit(1);

        $query = $this->db->get();

        if ($query->num_rows() == 1) {
            return $query->row()->id;
        } else {
            return false;
        }
    }
}

Now with the changes that were suggested to me, it now shows a new error:

The New error:

A PHP Error was encountered

Severity: Notice Message: Undefined index: username Filename: Templates/public.php Line Number: 168

Backtrace:

File: C:\xampp\htdocs\codeigniter\application\views\Templates\public.php Line: 168 Function: _error_handler

File: C:\xampp\htdocs\codeigniter\application\libraries\Template.php Line: 34 Function: view

File: C:\xampp\htdocs\codeigniter\application\controllers\public\Dashboard.php Line: 13 Function: load

File: C:\xampp\htdocs\codeigniter\index.php Line: 315 Function: require_once

Now if a un-comment the public $users in the Core controller(MY_Controller) ,it shows me a new error as well:

New error with public $users out of __construct function

Fatal error: Constant expression contains invalid operations in C:\xampp\htdocs\codeigniter\application\core\MY_Controller.php on line 6 A PHP Error was encountered

Severity: Compile Error

Message: Constant expression contains invalid operations

Filename: core/MY_Controller.php

Line Number: 6

Backtrace:

Here is a picture in which I'm trying to get the data to:

enter image description here

Am I doing something wrong? thanks for helping.

Here is the view (public.php) file:

<ul class="nav navbar-nav">
          <?php if(!$this->session->is_member) : ?>
          <li><?php echo anchor('public/users/login', 'Login'); ?></li>
          <li><?php echo anchor('public/users/register', 'Register'); ?></li>
          <?php else : ?>
            <!-- Messages: style can be found in dropdown.less-->
            <li class="dropdown messages-menu">
              <!-- Menu toggle button -->
              <a href="#" class="dropdown-toggle" data-toggle="dropdown">
                <i class="fa fa-envelope-o"></i>
                <span class="label label-success">4</span>
              </a>
              <ul class="dropdown-menu">
                <li class="header">You have 4 messages</li>
                <li>
                  <!-- inner menu: contains the messages -->
                  <ul class="menu">
                    <li><!-- start message -->
                      <a href="#">
                        <div class="pull-left">
                          <!-- User Image -->
                          <img src="<?php echo base_url(); ?>assets/img/user2-160x160.jpg" class="img-circle" alt="User Image">
                        </div>
                        <!-- Message title and timestamp -->
                        <h4>
                          Support Team
                          <small><i class="fa fa-clock-o"></i> 5 mins</small>
                        </h4>
                        <!-- The message -->
                        <p>Why not buy a new awesome theme?</p>
                      </a>
                    </li>
                    <!-- end message -->
                  </ul>
                  <!-- /.menu -->
                </li>
                <li class="footer"><a href="#">See All Messages</a></li>
              </ul>
            </li>
            <!-- /.messages-menu -->
            <!-- Notifications Menu -->
            <li class="dropdown notifications-menu">
              <!-- Menu toggle button -->
              <a href="#" class="dropdown-toggle" data-toggle="dropdown">
                <i class="fa fa-bell-o"></i>
                <span class="label label-warning">10</span>
              </a>
              <ul class="dropdown-menu">
                <li class="header">You have 10 notifications</li>
                <li>
                  <!-- Inner Menu: contains the notifications -->
                  <ul class="menu">
                    <li><!-- start notification -->
                      <a href="#">
                        <i class="fa fa-users text-aqua"></i> 5 new members joined today
                      </a>
                    </li>
                    <!-- end notification -->
                  </ul>
                </li>
                <li class="footer"><a href="#">View all</a></li>
              </ul>
            </li>
            <!-- Tasks Menu -->
            <li class="dropdown tasks-menu">
              <!-- Menu Toggle Button -->
              <a href="#" class="dropdown-toggle" data-toggle="dropdown">
                <i class="fa fa-flag-o"></i>
                <span class="label label-danger">9</span>
              </a>
              <ul class="dropdown-menu">
                <li class="header">You have 9 tasks</li>
                <li>
                  <!-- Inner menu: contains the tasks -->
                  <ul class="menu">
                    <li><!-- Task item -->
                      <a href="#">
                        <!-- Task title and progress text -->
                        <h3>
                          Design some buttons
                          <small class="pull-right">20%</small>
                        </h3>
                        <!-- The progress bar -->
                        <div class="progress xs">
                          <!-- Change the css width attribute to simulate progress -->
                          <div class="progress-bar progress-bar-aqua" style="width: 20%" role="progressbar" aria-valuenow="20" aria-valuemin="0" aria-valuemax="100">
                            <span class="sr-only">20% Complete</span>
                          </div>
                        </div>
                      </a>
                    </li>
                    <!-- end task item -->
                  </ul>
                </li>
                <li class="footer">
                  <a href="#">View all tasks</a>
                </li>
              </ul>
            </li>
            <!-- User Account Menu -->
            <?php if($this->users) : ?>
                <li class="dropdown user user-menu">
                  <!-- Menu Toggle Button -->
                  <a href="#" class="dropdown-toggle" data-toggle="dropdown">
                    <!-- The user image in the navbar-->
                    <img src="<?php echo base_url(); ?>assets/img/user2-160x160.jpg" class="user-image" alt="User Image">
                    <!-- hidden-xs hides the username on small devices so only the image appears. -->
                    <span class="hidden-xs"><?php echo $this->users['username']; ?></span>
                  </a>
                  <ul class="dropdown-menu">
                    <!-- The user image in the menu -->
                    <li class="user-header">
                    <img src="<?php echo base_url(); ?>assets/img/user2-160x160.jpg" class="img-circle" alt="User Image">
                      <p><?php echo $this->users['name']; ?> - Web Developer<small>Member since Nov. 2012</small></p>
                    </li>
                    <!-- Menu Body -->
                    <li class="user-body">
                      <div class="row">
                        <div class="col-xs-4 text-center">
                          <a href="#">Followers</a>
                        </div>
                        <div class="col-xs-4 text-center">
                          <a href="#">Sales</a>
                        </div>
                        <div class="col-xs-4 text-center">
                          <a href="#">Friends</a>
                        </div>
                      </div>
                      <!-- /.row -->
                    </li>
                    <!-- Menu Footer-->
                    <li class="user-footer">
                      <div class="pull-left">
                        <a href="#" class="btn btn-default btn-flat">Profile</a>
                      </div>
                      <div class="pull-right">
                        <a href="<?php echo base_url(); ?>public/users/logout" class="btn btn-default btn-flat">Sign out</a>
                      </div>
                    </li>
                  </ul>
                </li>
            <?php endif; ?>
            <li>
                <a href="#" data-toggle="control-sidebar"><i class="fa fa-gears"></i></a>
            </li>
          <?php endif; ?>
          </ul>
2
You should use as a property. public $users; and in your construct ($this->users = $this->User_model->get_list();. When you declare a variable in a function, will only be accessible in that function (or if you pass as parameter to another). - webmasterdro
Well, I made the change as you suggested on my __construct function but it just works if I do a foreach; doing an if condition is still not working. What do you mean by using it as a property?. I tried doing my __construct function public but I was unable to see any difference. Thanks for helping. - Kirasiris
@Kevin - you would have fired up Google and looked up what a Property of a class is and after that "ah ha" moment would have implemented webmasterdo's suggestion. So can you show your updated code with the changes? - TimBrownlaw
Ok, so can we see the code where you are loading the view? That is where your issue is - TimBrownlaw
For what reason did you attempt - public $users = array('username' => $this->input->post('username')); public $users=array(); is ALL you need to define it and init it. You cannot go running code in there. - TimBrownlaw

2 Answers

1
votes

You currently have this... and I am only showing snippets here...

class MY_Controller extends CI_Controller
{
    function __construct()
    {
        parent::__construct();

        //Get user data to make it available for both Admin and Public Controllers
        $this->load->model('User_model');
        $data['users'] = $this->User_model->get_list();

<<<<snip>>>>

It was suggested that you turn your locally defined $data['users'] into a "Property"

So we now have two changes...

1 Declare the Property

2 Set the property.

class MY_Controller extends CI_Controller
{
    public $users = array(); // Add the property $user, safe def of an empty array

    function __construct()
    {
        parent::__construct();

        //Get user data to make it available for both Admin and Public Controllers
        $this->load->model('User_model');
        //$data['users'] = $this->User_model->get_list();
        // Give the property something to share. 
        $this->users = $this->User_model->get_list();


    <<<<snip>>>>

Now all of your controllers that extend your MY_Controller now have access to $this->users created in MY_Controller...

So you reference $this->users where you want to use it.

I'd suggest you read up on Classes, Properties, Methods and Inheritance to begin with. Usually that is enough to make you dangerous. It takes a little getting used to but its worth the effort...

Update: In your controller that calls your View you would do $data['users'] = $this->users;

And in your view, you now refer to it as $users->field_name just like before. All we have done is define $users in your base class which is now accessible as $this->users so it's accessible to all your controllers / methods that extend the MY_Controller class.

0
votes

you currently have this.

class MY_Controller extends CI_Controller
{

function __construct()
{
    parent::__construct();

    //Get user data to make it available for both Admin and Public Controllers
    $this->load->model('User_model');
    $data['users'] = $this->User_model->get_list();

you should use $this->data['users'] in place of $data

class MY_Controller extends CI_Controller
{

function __construct()
{
    parent::__construct();

    //Get user data to make it available for both Admin and Public Controllers
    $this->load->model('User_model');
    $this->data['users'] = $this->User_model->get_list();

when you load your view use the code below

$this->load->view('view_name',$this->data);

it will show all your variable(in view) stored in parent classes construct function