Step 3.3 – Administer users with Ion Auth

This tutorial is part of a larger one, called Create a CMS with CodeIgniter 3. So, if you don’t understand how we’ve got to this point, I would advise you to try and read the previous tutorials. At the end of next tutorial I will post an archive with what we’ve done so far.

Once we’ve finished administering the groups, it’s about time for us to administer the users.

So let’s start by creating a Users.php file inside application/controllers/admin directory:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Users extends Admin_Controller
{

  function __construct()
  {
    parent::__construct();
    if(!$this->ion_auth->in_group('admin'))
    {
      $this->session->set_flashdata('message','You are not allowed to visit the Groups page');
      redirect('admin','refresh');
    }
  }

  public function index()
  {
  }

  public function create()
  {
  }

  public function edit()
  {
  }

  public function delete()
  {
  }
}

We will start by working at the list of users. We will display that in the index() method. Also, let’s allow this method to receive a group id so that when this is set the list will only show the users inside that group:

public function index($group_id = NULL)
{
  $this->data['page_title'] = 'Users';
  $this->data['users'] = $this->ion_auth->users($group_id)->result();
  $this->render('admin/users/list_users_view');
}

As you can see, to retrieve the users we’ve used the Ion Auth’s users() method. Now let’s create our list_users_view.php file inside application/views/admin/users directory:

<?php defined('BASEPATH') OR exit('No direct script access allowed');?>
<div class="container" style="margin-top: 60px;">
  <div class="row">
    <div class="col-lg-12">
      <a href="<?php echo site_url('admin/users/create');?>" class="btn btn-primary">Create user</a>
    </div>
  </div>
  <div class="row">
    <div class="col-lg-12" style="margin-top: 10px;">
    <?php
    if(!empty($users))
    {
      echo '<table class="table table-hover table-bordered table-condensed">';
      echo '<tr><td>ID</td><td>Username</td></td><td>Name</td><td>Email</td><td>Last login</td><td>Operations</td></tr>';
      foreach($users as $user)
      {
        echo '<tr>';
        echo '<td>'.$user->id.'</td><td>'.$user->username.'</td><td>'.$user->first_name.' '.$user->last_name.'</td></td><td>'.$user->email.'</td><td>'.date('Y-m-d H:i:s', $user->last_login).'</td><td>';
        if($current_user->id != $user->id) echo anchor('admin/users/edit/'.$user->id,'<span class="glyphicon glyphicon-pencil"></span>').' '.anchor('admin/users/delete/'.$user->id,'<span class="glyphicon glyphicon-remove"></span>');
        else echo '&nbsp;';
        echo '</td>';
        echo '</tr>';
      }
      echo '</table>';
    }
    ?>
    </div>
  </div>
</div>

As you can see, I didn’t allow the user to delete himself (in most parts of the world the suicide is forbidden :))). If you remember, in a previous tutorial we’ve created $current_user object in the Admin_Controller. Now we’ve accessed this object to verify if the current user is the user in the list. We will not allow him/her to change anything regarding himself. He will be able to change this in the personal profile page.

The create user page

The create() method

The Users’ create() method goes almost the same as the Groups‘ one:

public function create()
{
  $this->data['page_title'] = 'Create user';
  $this->load->library('form_validation');
  $this->form_validation->set_rules('first_name','First name','trim');
  $this->form_validation->set_rules('last_name','Last name','trim');
  $this->form_validation->set_rules('company','Company','trim');
  $this->form_validation->set_rules('phone','Phone','trim');
  $this->form_validation->set_rules('username','Username','trim|required|is_unique[users.username]');
  $this->form_validation->set_rules('email','Email','trim|required|valid_email|is_unique[users.email]');
  $this->form_validation->set_rules('password','Password','required');
  $this->form_validation->set_rules('password_confirm','Password confirmation','required|matches[password]');
  $this->form_validation->set_rules('groups[]','Groups','required|integer');

  if($this->form_validation->run()===FALSE)
  {
    $this->data['groups'] = $this->ion_auth->groups()->result();
    $this->load->helper('form');
    $this->render('admin/users/create_user_view');
  }
  else
  {
    $username = $this->input->post('username');
    $email = $this->input->post('email');
    $password = $this->input->post('password');
    $group_ids = $this->input->post('groups');

    $additional_data = array(
      'first_name' => $this->input->post('first_name'),
      'last_name' => $this->input->post('last_name'),
      'company' => $this->input->post('company'),
      'phone' => $this->input->post('phone')
    );
    $this->ion_auth->register($username, $password, $email, $additional_data, $group_ids);
    $this->session->set_flashdata('message',$this->ion_auth->messages());
    redirect('admin/users','refresh');
  }
}

The create_user_view view

<?php defined('BASEPATH') OR exit('No direct script access allowed');?>
<div class="container" style="margin-top: 60px;">
  <div class="row">
    <div class="col-lg-4 col-lg-offset-4">
      <h1>Create user</h1>
      <?php echo form_open('',array('class'=>'form-horizontal'));?>
      <div class="form-group">
        <?php
        echo form_label('First name','first_name');
        echo form_error('first_name');
        echo form_input('first_name',set_value('first_name'),'class="form-control"');
        ?>
      </div>
      <div class="form-group">
        <?php
        echo form_label('Last name','last_name');
        echo form_error('last_name');
        echo form_input('last_name',set_value('last_name'),'class="form-control"');
        ?>
      </div>
      <div class="form-group">
        <?php
        echo form_label('Company','company');
        echo form_error('company');
        echo form_input('company',set_value('company'),'class="form-control"');
        ?>
      </div>
      <div class="form-group">
        <?php
        echo form_label('Phone','phone');
        echo form_error('phone');
        echo form_input('phone',set_value('phone'),'class="form-control"');
        ?>
      </div>
      <div class="form-group">
        <?php
        echo form_label('Username','username');
        echo form_error('username');
        echo form_input('username',set_value('username'),'class="form-control"');
        ?>
      </div>
      <div class="form-group">
        <?php
        echo form_label('Email','email');
        echo form_error('email');
        echo form_input('email','','class="form-control"');
        ?>
      </div>
      <div class="form-group">
        <?php
        echo form_label('Password','password');
        echo form_error('password');
        echo form_password('password','','class="form-control"');
        ?>
      </div>
      <div class="form-group">
        <?php
        echo form_label('Confirm password','password_confirm');
        echo form_error('password_confirm');
        echo form_password('password_confirm','','class="form-control"');
        ?>
      </div>
      <div class="form-group">
        <?php
        if(isset($groups))
        {
          echo form_label('Groups','groups[]');
          foreach($groups as $group)
          {
            echo '<div class="checkbox">';
            echo '<label>';
            echo form_checkbox('groups[]', $group->id, set_checkbox('groups[]', $group->id));
            echo ' '.$group->name;
            echo '</label>';
            echo '</div>';
          }
        }
        ?>
      </div>
      <?php echo form_submit('submit', 'Create user', 'class="btn btn-primary btn-lg btn-block"');?>
      <?php echo form_close();?>
    </div>
  </div>
</div>

Well… it should work…

The edit page

The edit() method

public function edit($user_id = NULL)
{
  $user_id = $this->input->post('user_id') ? $this->input->post('user_id') : $user_id;
  $this->data['page_title'] = 'Edit user';
  $this->load->library('form_validation');

  $this->form_validation->set_rules('first_name','First name','trim');
  $this->form_validation->set_rules('last_name','Last name','trim');
  $this->form_validation->set_rules('company','Company','trim');
  $this->form_validation->set_rules('phone','Phone','trim');
  $this->form_validation->set_rules('username','Username','trim|required');
  $this->form_validation->set_rules('email','Email','trim|required|valid_email');
  $this->form_validation->set_rules('password','Password','min_length[6]');
  $this->form_validation->set_rules('password_confirm','Password confirmation','matches[password]');
  $this->form_validation->set_rules('groups[]','Groups','required|integer');
  $this->form_validation->set_rules('user_id','User ID','trim|integer|required');

  if($this->form_validation->run() === FALSE)
  {
    if($user = $this->ion_auth->user((int) $user_id)->row())
    {
      $this->data['user'] = $user;
    }
    else
    {
      $this->session->set_flashdata('message', 'The user doesn\'t exist.');
      redirect('admin/users', 'refresh');
    }
    $this->data['groups'] = $this->ion_auth->groups()->result();
    $this->data['usergroups'] = array();
    if($usergroups = $this->ion_auth->get_users_groups($user->id)->result())
    {
      foreach($usergroups as $group)
      {
        $this->data['usergroups'][] = $group->id;
      }
    }
    $this->load->helper('form');
    $this->render('admin/users/edit_user_view');
  }
  else
  {
    $user_id = $this->input->post('user_id');
    $new_data = array(
      'username' => $this->input->post('username'),
      'email' => $this->input->post('email'),
      'first_name' => $this->input->post('first_name'),
      'last_name' => $this->input->post('last_name'),
      'company' => $this->input->post('company'),
      'phone' => $this->input->post('phone')
    );
    if(strlen($this->input->post('password'))>=6) $new_data['password'] = $this->input->post('password');

    $this->ion_auth->update($user_id, $new_data);

    //Update the groups user belongs to
    $groups = $this->input->post('groups');
    if (isset($groups) && !empty($groups))
    {
      $this->ion_auth->remove_from_group('', $user_id);
      foreach ($groups as $group)
      {
        $this->ion_auth->add_to_group($group, $user_id);
      }
    }

    $this->session->set_flashdata('message',$this->ion_auth->messages());
    redirect('admin/users','refresh');
  }
}

The edit_user_view view

<?php defined('BASEPATH') OR exit('No direct script access allowed');?>
<div class="container" style="margin-top: 60px;">
  <div class="row">
    <div class="col-lg-4 col-lg-offset-4">
      <h1>Edit user</h1>
      <?php echo form_open('',array('class'=>'form-horizontal'));?>
        <div class="form-group">
          <?php
          echo form_label('First name','first_name');
          echo form_error('first_name');
          echo form_input('first_name',set_value('first_name',$user->first_name),'class="form-control"');
          ?>
        </div>
        <div class="form-group">
          <?php
          echo form_label('Last name','last_name');
          echo form_error('last_name');
          echo form_input('last_name',set_value('last_name',$user->last_name),'class="form-control"');
          ?>
        </div>
        <div class="form-group">
          <?php
          echo form_label('Company','company');
          echo form_error('company');
          echo form_input('company',set_value('company',$user->company),'class="form-control"');
          ?>
        </div>
        <div class="form-group">
          <?php
          echo form_label('Phone','phone');
          echo form_error('phone');
          echo form_input('phone',set_value('phone',$user->phone),'class="form-control"');
          ?>
        </div>
        <div class="form-group">
          <?php
          echo form_label('Username','username');
          echo form_error('username');
          echo form_input('username',set_value('username',$user->username),'class="form-control"');
          ?>
        </div>
        <div class="form-group">
          <?php
          echo form_label('Email','email');
          echo form_error('email');
          echo form_input('email',set_value('email',$user->email),'class="form-control"');
          ?>
        </div>
        <div class="form-group">
          <?php
          echo form_label('Change password','password');
          echo form_error('password');
          echo form_password('password','','class="form-control"');
          ?>
        </div>
        <div class="form-group">
          <?php
          echo form_label('Confirm changed password','password_confirm');
          echo form_error('password_confirm');
          echo form_password('password_confirm','','class="form-control"');
          ?>
        </div>
        <div class="form-group">
          <?php
          if(isset($groups))
          {
            echo form_label('Groups','groups[]');
            foreach($groups as $group)
            {
              echo '<div class="checkbox">';
              echo '<label>';
              echo form_checkbox('groups[]', $group->id, set_checkbox('groups[]', $group->id, in_array($group->id,$usergroups)));
              echo ' '.$group->name;
              echo '</label>';
              echo '</div>';
            }
          }
          ?>
        </div>
        <?php echo form_hidden('user_id',$user->id);?>
        <?php echo form_submit('submit', 'Edit user', 'class="btn btn-primary btn-lg btn-block"');?>
      <?php echo form_close();?>
    </div>
  </div>
</div>

Now that was a looooooong one…

But… we should return to the edit() method because we actually need to do some form validation callbacks for the username and email. We need to make sure that if those are changed by the admins, they do not already exist in the users table. I leave this to you.

The delete page

The delete() method

public function delete($user_id = NULL)
{
  if(is_null($user_id))
  {
    $this->session->set_flashdata('message','There\'s no user to delete');
  }
  else
  {
    $this->ion_auth->delete_user($user_id);
    $this->session->set_flashdata('message',$this->ion_auth->messages());
  }
  redirect('admin/users','refresh');
}

Cool, finished the the Users controller too.

But let’s return for a moment to the application/views/admin/groups/list_groups_view.php and make the group name clickable so that the links will send to the users of that group:

<?php defined('BASEPATH') OR exit('No direct script access allowed');?>
<div class="container" style="margin-top: 60px;">
  <div class="row">
    <div class="col-lg-12">
      <a href="<?php echo site_url('admin/groups/create');?>" class="btn btn-primary">Create group</a>
    </div>
  </div>
  <div class="row">
    <div class="col-lg-12" style="margin-top: 10px;">
      <?php
      if(!empty($groups))
      {
        echo '<table class="table table-hover table-bordered table-condensed">';
        echo '<tr><td>ID</td><td>Group name</td></td><td>Group description</td><td>Operations</td></tr>';
        foreach($groups as $group)
        {
          echo '<tr>';
          echo '<td>'.$group->id.'</td><td>'.anchor('admin/users/index/'.$group->id,$group->name).'</td><td>'.$group->description.'</td><td>'.anchor('admin/groups/edit/'.$group->id,'<span class="glyphicon glyphicon-pencil"></span>');
          if(!in_array($group->name, array('admin','members'))) echo ' '.anchor('admin/groups/delete/'.$group->id,'<span class="glyphicon glyphicon-remove"></span>');
          echo '</td>';
          echo '</tr>';
        }
        echo '</table>';
      }
      ?>
    </div>
  </div>
</div>

And that’s it. Next we look at our profile page.

11 comments

  1. Great tutorial! Thanks for all your great lessons.
    Just a note…maybe there is a missing “)” at line 18 in the list_groups_view.php., to close the first anchor.
    Sorry for that.
    Ciao

  2. Hi, Y encountred a one problem to create a new user, in database table not insert a username, but the others things ok and edit the username correctly.

    1. Solved. The problem is in Ion_auth_model on $data array

      $data = array(
      $this->identity_column => $identity,
      ‘password’ => $password,
      ’email’ => $email,
      ‘ip_address’ => $ip_address,
      ‘created_on’ => time(),
      ‘active’ => ($manual_activation === false ? 1 : 0)
      );
      change to

      $data = array(
      $this->identity_column => $identity,
      ‘username’ => $identity,
      ‘password’ => $password,
      ’email’ => $email,
      ‘ip_address’ => $ip_address,
      ‘created_on’ => time(),
      ‘active’ => ($manual_activation === false ? 1 : 0)
      );

    2. That might have happened because you didn’t set “username” as identity column in the configuration file of the Ion Auth.

        1. Is the “Username” a field name in your table? Or “username”? Always make sure you know which is which…

  3. Hello Avenirer! When I try create a new user but I get the error “Field ‘username’ doesn’t have a default value”, I want that the email column is the identity column.

  4. I have found one mistake. For example, yourdomain.com/admin/users/edit/0 or yourdomain.com/admin/users/edit/sometext return the data of admin.

    I think, reason is that (int) $user_id returns 0 and $this->ion_auth->user((int) $user_id)->row() returns the data of admin. Line 20 in the edit() method.

    Sorry for my bad English. 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *

No spam? * Time limit is exhausted. Please reload CAPTCHA.