back to Freaky Tutorials

Freaky Tutorials: User Profiles Part Two

This is a follow up of the first part of this tutorial about Freak Auth custom user profile functionality. Now we will build a frontend controller/views to display the profile of our users an to allow the owners of the profile to edit it.


If you missed part one please have a look at it.


Again I assume you have already installed both CI 1.5.2 and at least FreakAuth_light 1.0.2-Beta and that you are a bit familiar with them.


The source code for this tutorial is available here.


I'll call the controller to handle the userprofile visualization/editing myaccount. Before strating we need to add a couple of lines in our application/config/routes.php.

<?
      //...
      $route['myaccount/show/:num'] = "myaccount/show";
      $route['myaccount/edit/:num'] = "myaccount/edit";
      //... 

DISPLAYING USER PROFILES TO EVERYBODY

Well let's start to build the controller to handle the visualization/editing of the userprofile of our users.

I'll call the controller Myaccount and I'll put it in a file called myaccount.php into the application/controllers/ folder:

<?
/**
 * controller to display a user custom profile and allow the owner of the
 * profile to modify it
 * @author Daniel Vecchiato
 * @link 4webby.com
 */
class Myaccount extends Controller
{
    function Myaccount()
    {
      parent::Controller();
    }
   
    // --------------------------------------------------------------------
    function index()
    {
      //write the code to display a list of all registered users here
    }
   
    // -----------------------------------------------
    /**
     * display the profile of an requested user
     * we let everybody see this profile
     */
    function show()
    {
        $id = $this->uri->segment(3);
        $query = $this->usermodel->getUserById($id);
     
    if ($query->num_rows() == 1)
    {
        $row = $query->row();
        $data['user']['id']= $row->id;
        $data['user']['user_name']= $row->user_name;
        $data['user']['email']= $row->email;
       
        //$countries = null;           
        if ($this->config->item('FAL_use_country') && strlen($row->country_id))
        {
            $this->load->model('country');
             
            $query = $this->country->getCountryById($row->country_id);
            $row = $query->row();
             
            //SELECT name FROM country WHERE id= $data['user']['country_id']
              $data['user']['country'] = $row->name;
        }
         
        $query->free_result();
         
        //
        if ($this->config->item('FAL_create_user_profile')==TRUE)
        {
            //get data from the user_profile table
            $data['user_profile']= $this->freakauth_light->_getUserProfile($id);
            $data['f_r'] = $this->freakauth_light->_buildUserProfileFieldsRules();
            $data['label'] = $data['f_r']['fields'];
        }
        
        }
        else
        {
            $data['error_message']='The record you are looking for does not exist';
        }
       
        $this->load->view('view', $data);
    }
}

Everybody will be able to see the userprofile of our users.

The method show() will take care of displaying the userprofile for the user id passed into the URI.

We are not ready yet, because we need a view for the function show() to work properly.

Create a file called view.php with the following inside and drop it in your application/views/ folder:

<!--your HTML header here-->
<h1>Userprofile for user <?=$user['user_name']?></h1>
<p><?=anchor('myaccount/edit/'.$user['id'], 'EDIT')?></p>
<ul>
    <li>username: <?=$user['user_name']?></li>
    <li>e-mail: <?=$user['email']?></li>
    <?php if ($this->config->item('FAL_use_country') && isset($user['country']))
    {?>
    <li>country: <?=$user['country'];?></li>
    <?php
    }?>
<?php if ($this->config->item('FAL_create_user_profile') AND !empty($user_profile))
{
  foreach ($user_profile as $field=>$profile)
  {?>
    <li><?=$label[$field]?>: <?=$profile?></li>
  <?php
  }
}
elseif($this->config->item('FAL_create_user_profile') AND empty($user_profile))
{?>
<p class="error">no data in DB: please add them</p>
<?php
} else {?>
<p class="error">userprofile disabled in config</p>
<?php }?>
</ul>
<!--your HTML footer here-->

Now go to www.yoursite.com/index.php/myaccount/show/1 and you will be able to see the profile of the user with id=1.

LETTING USERS TO EDIT THEIR OWN PROFILE

Next step will be to add the method edit() in our controller in order to let our users to edit their own profile. Therefore we will need to restrict the access to this method not only to valid logged in users, but we will also check that they are the effective owners of the profile with the following statement:

<?
//let's restrict access to just the owner of this account
//if number and number==userdata['id']
if (belongsToGroup('user') AND $id === $this->db_session->userdata('id'))
{
    //...
}


The method edit() requires some custom validation sules (callbacks), I won't cover them here but you will find them in the ready to plug downloadable code. Then download the source code for this tutorial if you want to test the edit() method properly.


Let's open our file myaccount.php again and add the method edit() to the Myaccount class:

<?
// -----------------------------------------------
/**
 * necessary for the user to edit his own profile
 * only the user owning this profile can access this method
 *
 * We allow him to edit everything apart from his username that must be unique
 * and therefore not changed after registration
 */
function edit()
{
    //www.yourdomain.com/index.php/myaccount/edit/1
    $id = $this->uri->segment(3);
 
    //let's restrict access to just the owner of this account
    //if number and number==userdata['id']
    if (belongsToGroup('user') AND $id === $this->db_session->userdata('id'))
    {
        //loading necessary stuff
        $this->lang->load('freakauth');
        $this->load->model('FreakAuth_light/usermodel', 'usermodel');
        $this->load->library('validation');
        $this->validation->set_error_delimiters($this->config->item('FAL_error_delimiter_open'), $this->config->item('FAL_error_delimiter_close'));
   
        //set validation rules
        $rules['password'] = 'trim|xss_clean|callback__password_check';
        $rules['password_confirm'] = "trim|xss_clean|matches[password]";
        $rules['email'] = 'trim|required|valid_email|xss_clean|callback__email_duplicate_check';
    }
    else
    {
        $msg = 'your must login to access this restricted area';
        $this->db_session->set_flashdata('flashMessage', $msg, 1);
        redirect('' , 'location');
    }
     
    //do we want to set the country?
    //(looks what we set in the freakauth_light.php config)
    if ($this->config->item('FAL_use_country'))
    {
        $rules['country_id'] = $this->config->item('FAL_user_country_field_validation_register');
    }
    
    //getting user profile custom data and setting fields and rules for validation
    if ($this->config->item('FAL_create_user_profile')==TRUE)
    {
        $data = $this->freakauth_light->_buildUserProfileFieldsRules();
        $rules_profile= $data['rules'];
        $fields = $data['fields'];
        $this->validation->set_rules($rules_profile);
    }
     
    $this->validation->set_rules($rules);
    
    $fields['password'] = $this->lang->line('FAL_user_password_label');
    $fields['password_confirm'] = $this->lang->line('FAL_user_password_confirm_label');
    $fields['email'] = $this->lang->line('FAL_user_email_label');
    
    //if activated in config, sets the select country box
    if ($this->config->item('FAL_use_country'))
    {
        $fields['country_id'] = $this->lang->line('FAL_user_country_label');
    }
    
    $this->validation->set_fields($fields);
     
    //this avoid 1 extra query if validation doesn't return true
    {
        //gets values for the edit form
        $query = $this->usermodel->getUserById($id);

        foreach ($query->result() as $row)
        {
            $data['user']['id']= $row->id;
            $data['user']['email']= $row->email;
            $data['user']['country_id']= $row->country_id;
        }
           
        $query->free_result();


        if ($this->config->item('FAL_create_user_profile')==TRUE)
        {
            $data['user_prof']= $this->freakauth_light->_getUserProfile($id);
            $data['f_r'] = $this->freakauth_light->_buildUserProfileFieldsRules();
            $data['fields'] = $data['f_r']['fields'];
        }
    }

    //$countries = null;
    if ($this->config->item('FAL_use_country'))
    {
        $this->load->model('country');
 
        //SELECT * FROM country
        $data['countries'] = $this->country->getCountriesForSelect();
    }
 
    if ($this->validation->run() == FALSE)
    {
        $this->load->view('edit', $data);
        $this->output->enable_profiler(TRUE);
    }
   
    //if everything ok
    else
    {
        //get form values
        $values = $this->_get_form_values();
        
        $id = $this->db_session->userdata('id');
        
        //update data in DB
        $where=array('id' => $id);
        $this->usermodel->updateUser($where, $values['user']);
       
        //if we want the user profile as well
        if($this->config->item('FAL_create_user_profile'))
        {
            //let's get the last insert id
            $this->load->model('Userprofile');
            $this->Userprofile->updateUserProfile($id, $values['user_profile']);
        }
        //set a flash message
        $msg = $this->db->affected_rows().$this->lang->line('FAL_user_edited');
        $this->db_session->set_flashdata('flashMessage', $msg, 1);
    
        //redirect to list
        redirect('myaccount/show/'.$this->db_session->userdata('id'), 'location');
    }
} 

Ok, again for the method edit() to work we need to build a edit.php view and drop it in the application/views directory:

<?
<!--your HTML header here-->
<h2>Myaccount EDIT myprofile</h2>
<?=form_open('/myaccount/edit/'.$user['id'])?>
<!--USERPROFILE DATA-->
<p><label for="email">e-mail:</label>
    <?=form_input(array('name'=>'email',
                       'id'=>'email',
                       'maxlength'=>'120',
                       'size'=>'35',
                       'value'=>(isset($user['email']) ? $user['email'] : $this->validation->{'email'})))?>
    <span><?=(isset($this->validation) ? $this->validation->{'email'.'_error'} : '')?></span>
    </p>
    <p><label for="password">password:</label>
    <?=form_password(array('name'=>'password',
                       'id'=>'password',
                       'maxlength'=>'16',
                       'size'=>'16',
                       'value'=>(isset($this->validation->{'password'}) ? $this->validation->{'password'} : '')))?>
    <span><?=(isset($this->validation) ? $this->validation->{'password'.'_error'} : '')?></span>
    </p>

    <p><label for="password_confirm">retype password:</label>
    <?=form_password(array('name'=>'password_confirm',
                       'id'=>'password_confirm',
                       'maxlength'=>'16',
                       'size'=>'16',
                       'value'=>(isset($this->validation) ? $this->validation->{'password_confirm'} : '')))?>
    <span><?=(isset($this->validation) ? $this->validation->{'password_confirm'.'_error'} : '')?></span>
    </p>
       
    <?php if ($this->config->item('FAL_use_country'))
    {?>
   
        <p><label for="country_id">country:</label>
        <?=form_dropdown('country_id',
                     $countries,
                     (isset($user['country_id']) ? $user['country_id'] :  $this->validation->country_id))?>
            <span><?=(isset($this->validation) ? $this->validation->{'country_id'.'_error'} : '')?></span>
        </p>
    <?php } ?>
   
    <?php if ($this->config->item('FAL_create_user_profile') AND !empty($fields))
    {
        foreach ($fields as $field=>$label)
        {?>
        <p><label for="<?=$field?>"><?=$label?>:</label>
        <?=form_input(array('name'=>$field,
                        'id'=>$field,
                        'maxlength'=>'45',
                        'size'=>'25',
                        'value'=>(isset($user_prof[$field]) ? $user_prof[$field] : $this->validation->{$field})))?>
            <span><?=(isset($this->validation) ? $this->validation->{$field.'_error'} : '')?></span></p>

    <?php }
    }
    elseif($this->config->item('FAL_create_user_profile') AND empty($user_profile)) {?> <p class="error">no data in DB: please add them</p>
    <?php } else {?><p class="error">userprofile disabled in config</p><?php }?>
   
    <!-- END USERPROFILE DATA-->
   
    <input type="submit" name="Submit" value="save" />
    <input type="button" name="back" class="submit" value="back" onclick="location.href = '<?=base_url();?>index.php/myaccount/<?=$user['id']?>'"/>
   
</form>
<!--your HTML footer here-->

Now if you are:

  • logged in
  • and you have an user id=1

go to www.yourdomain.com/index.php/myaccount/edit/1 and you will be able to edit your profile.

WHAT'S LEFT?

Well we are done with user profile visualization and editing. It would also be nice to add a method to our controller in order to display all registered users with a link to their public profile.

I leave this last task to you: the method is ready in the Myaccount class and is called index(), just fill in the code in the curly brackets {//your code here...} .

We hope this tutorial has helped you to discover a bit better the custom user profile feature of FreakAuth_light.

Attachments