12
votes

I'm moving some of my find code inside models.

Previously in my controller I had

$this->Book->Review->find('first', array(
    'conditions' => array(
        'Review.book_id' => $id,
        'Review.user_id' => $this->Auth->user('id')
    )
));

so in my Review model I put something like

function own($id) {
    $this->contain();
    $review = $this->find('first', array(
        'conditions' => array(
            'Review.book_id' => $id,
            'Review.user_id' => AuthComponent::user('id')
        )
    ));
    return $review;
}

So I'm calling AuthComponent statically from the Model. I know I can do this for the method AuthComponent::password(), which is useful for validation. But I'm getting errors using the method AuthComponent::user(), in particular

Fatal error: Call to a member function check() on a non-object in /var/www/MathOnline/cake/libs/controller/components/auth.php on line 663

Is there a way to get the info about the currently logged user from a model?

9

9 Answers

3
votes

There is a nice solution by Matt Curry. You store the data of the current logged user in the app_controller using the beforeFilter callback and access it later using static calls. A description can be found here: http://www.pseudocoder.com/archives/2008/10/06/accessing-user-sessions-from-models-or-anywhere-in-cakephp-revealed/


EDIT: the above link is outdated: https://github.com/mcurry/cakephp_static_user

13
votes

Create a new function in the "app_model.php" ("AppModel.php" in CakePHP 2.x), so it will be available at all models within our application:

function getCurrentUser() {
  // for CakePHP 1.x:
  App::import('Component','Session');
  $Session = new SessionComponent();

  // for CakePHP 2.x:
  App::uses('CakeSession', 'Model/Datasource');
  $Session = new CakeSession();


  $user = $Session->read('Auth.User');

  return $user;
}

in the model:

$user = $this->getCurrentUser();
$user_id = $user['id'];
$username = $user['username'];
11
votes

The way that I use is this:

App::import('component', 'CakeSession');        
$thisUserID = CakeSession::read('Auth.User.id');

It seems to work quite nicely :-)

6
votes

I think the code is fine as it is and belongs in the Controller, or at the very least it needs to receive the ids from the Controller and not try to get them itself. The Model should only be concerned with fetching data from a data store and returning it. It must not be concerned with how the data is handled in the rest of the application or where the parameters to its request are coming from. Otherwise you paint yourself into a corner where the ReviewModel can only retrieve data for logged in users, which might not always be what you want.

As such, I'd use a function signature like this:

function findByBookAndUserId($book_id, $user_id) {
    …
}

$this->Review->findByBookAndUserId($id, $this->Auth->user('id'));
2
votes

I think this is not good idea to get value from Session. Better solution to get logged user id inside any model simply try this:

AuthComponent::user('id');

This will work almost every where. View, Model and Controller

1
votes

Dirtiest way would be to just access the user information in the Session. Least amount of overhead associated with that.

The "proper" way would probably be to instantiate the AuthComponent object, so that it does all the stuff it needs to be fully operational. Much like a death star, the AuthComponent doesn't really work well when not fully setup.

To get a new AC object, in the model:

App::import( 'Component', 'Auth' );
$this->Auth = new AuthComponent();

Now you can use $this->Auth in the model, same as you would in the controller.

1
votes

For CakePHP 3.x this easy component is available: http://cakemanager.org/docs/utils/1.0/components/globalauth/. Direct accessing the Session is not possible because of different SessionKeys.

With the GlobalAuthComponent you can access your user-data everywhere with: Configure::read('GlobalAuth');.

Greetz

Bob

0
votes

I use cake 2.2 and these both work great:

$this->Session->read('Auth.User');
//or
$this->Auth->user();

You can also get a field of currently logged in user:

$this->Session->read('Auth.User.email');
//or
$this->Auth->user()['email'];
0
votes

None of these solutions work in CakePHP version 3. Anyone know of a way to do this? Right now, I'm completely stepping around the framework by accessing the $_SESSION variable directly from my model.