Welcome Guest, Not a member yet? Register   Sign In
Autoload problem
#1

[eluser]weedy[/eluser]
EDIT: Solved, see post #4 for info.
http://ellislab.com/forums/viewthread/79175/#397322

I put core session class to autoload, it works in a pre-controller hook, but calling it in the controller results in "Message: Undefined property: User::$session" and "Fatal error: Call to a member function userdata() on a non-object in /usr/local/www/casting/system/application/controllers/user.php on line 21".

Any ideas what might be causing it?

(and yes I'm a CI newb)

Below the code:
config.php
Code:
$autoload['libraries'] = array('database', 'session');

hooks.php
Code:
$hook['pre_controller'][] = array(
                                'class'    => 'Auth',
                                'function' => 'index',
                                'filename' => 'auth.php',
                                'filepath' => 'hooks',
                                );

hooks/auth.php
Code:
class Auth extends Controller
{
    function Auth()
    {
        parent::Controller();
    }
    function index()
    {
        $uri = $this->uri->uri_string();
        
        //check versus recurrency
        if($uri != '/user/login')
        {
            //id should be known
            if(!$this->session->userdata('id'))
            {
                //save current uri to redirect back to it after login
                $this->session->set_userdata('redirect' , $uri);
                 redirect('/user/login');
            }
        }
    }
}
Note - I had to extend the controller in order to get $this->session working here $CI & = get_instance() didn't work at all (any ideas here too? ).

controllers/user (constructor is blank apart from parent::Controller call)
Code:
function login()
{
    $email = $this->input->post('email');
    $password = $this->input->post('password');
    
    if($email && $password)
    {
        $this->load->model('user_model', 'user');
        if($auth = $this->user->auth(array('email' => $email, 'password' => $password)))
        {
            foreach($auth as $key => $value)
            {
                $this->session->set_userdata($key, $value);
            }
            if($redirect = $this->session->userdata('redirect'))
            {
                redirect($redirect);
            }
            else
            {
                redirect('');
            }
        }
    }
    $this->load->view('user/login');
}
#2

[eluser]wiredesignz[/eluser]
Autoload occurs in the Controller constructor, and because you are using the pre-controller hook, autoload has not yet run.

get_instance() will also fail if the Controller is not instaniated yet.
#3

[eluser]weedy[/eluser]
Well, hook DOES work WITH preloaded stuff (uri, session classes and url helper) without problem, it's the controller that fails.
#4

[eluser]weedy[/eluser]
Basically, for some reason my User class, which extends Controller class appears to not have $this->session although the log says session has been initialized (and when I try to add another init it says that I am attempting to init it twice and the second instance is ignored).
#5

[eluser]weedy[/eluser]
Problem solved - CodeIgniter doesn't support extending Controller twice per request (or so does it seem) - I extended Controller with Auth and then tried to do the same with User - I ended up making the auth hook a function which worked post-controller and all conflicts were resolved. Smile
#6

[eluser]garaget[/eluser]
[quote author="weedy" date="1210534947"]Problem solved - CodeIgniter doesn't support extending Controller twice per request (or so does it seem) - I extended Controller with Auth and then tried to do the same with User - I ended up making the auth hook a function which worked post-controller and all conflicts were resolved. Smile[/quote]

Hey Weedy,

Can you explain how you hooked a function to work post-controller? I am reading about hooks in the user-guide but it is a little confusing.

Thanks a bunch in advance
#7

[eluser]weedy[/eluser]
Yeah, what I did was made the hook a function (It could've been a class but since I can't have 2 controllers, it would be useless anyway):

Code:
<?
/**
* Auth
*
* Check if the user has been logged in. Uses Session class with DB sessions.
*
*
* @access    public
*
*/

function auth()
{    
    $CI =& get_instance();
    
    $CI->load->library('session');
    
    $uri = $CI->uri->uri_string();
    
    //check versus recurrency
    if($uri != '/user/login')
    {
        //id should be known
        if(!$CI->session->userdata('id'))
        {
            //save current uri to redirect back to it after login
            $CI->session->set_userdata('redirect' , $uri);
             redirect('/user/login');
        }
        else
        {
            $CI->load->model('user_model', 'user');
            $CI->user->log(array('id' => $CI->session->userdata('id')));
        }
    }
}
?>

This is loaded post controller:
Code:
$hook['post_controller'][] = array(
                                'class'    => '',
                                'function' => 'auth',
                                'filename' => 'auth.php',
                                'filepath' => 'hooks',
                                );

Uses user_model:
Code:
<?
class User_model extends Model {

    function User_model()
    {
        // Call the Model constructor
        parent::Model();
    }
    
    function auth($user)
    {
        $this->
            db->
                select('id, name, surname, email, company')->
                from('_users')->
                where('username = "' . $this->db->escape_str($user['username']) . '" AND password = MD5("' . $this->db->escape_str($user['password']) . '")');

        $query = $this->db->get();
        
        $result = $query->row();
        
        if (!empty($result->id))
        {
            $this->log(array('id' => $result->id));
        }    
            
        return $query->row();
    }

    function log($user)
    {
        if(!empty($user['id']))
        {
            //rework to use AR!
            return $this->db->query('UPDATE _users SET `last` = "' . time() . '" WHERE `id` = ' . (int)$user['id']);
        }
        return false;
    }

    function insert($user)
    {
        return $this->db->insert('_users', $user);
    }

    function update($user)
    {
        return $this->db->update('_users', $user, array('id' => $user['id']));
    }

}
?>
(the query in log function does not use active record and therefore is sub-optimal, I've noted that and will rework it to use AR once I have time)

And supplemented by User class:
Code:
<?php

class User extends Controller {

    function User()
    {
        parent::Controller();
    }
    
    function index()
    {
        $this->login();
    }
    
    function login()
    {
        $user = $this->input->post('user');
        $password = $this->input->post('password');
        
        if($user && $password)
        {
            $this->load->model('user_model', 'user');
            if($auth = $this->user->auth(array('username' => $user, 'password' => $password)))
            {
                foreach($auth as $key => $value)
                {
                    $this->session->set_userdata($key, $value);
                }

                if($redirect = $this->session->userdata('redirect'))
                {
                    if ($redirect == '/user/logout' || $redirect == '/user/')
                    {
                        $redirect = '/plan';
                    }
                    //move back to original request url
                    redirect($redirect);
                }
                
                //if no original request url, move to index
                redirect('/plan');
            }
        }
        
        $vars = array('title' => false);
        $this->load->view('common/header',$vars);
        $this->load->view('user/login');
        $this->load->view('common/footer');
    }
    
    function logout()
    {
        $this->session->destroy();
        redirect('');
    }
}
?>


Hope that helps. Smile




Theme © iAndrew 2016 - Forum software by © MyBB