2010-01-27 14 views
11

Moveré algunos de mis códigos de búsqueda dentro de los modelos.CakePHP: obtener información del usuario en los modelos

Anteriormente en mi controlador de E tenían

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

así que en mi modelo de revisión puse algo así como

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

Así que estoy llamando AuthComponent estática del modelo. Sé que puedo hacer esto para el método AuthComponent :: password(), que es útil para la validación. Pero me estoy errores utilizando el método AuthComponent :: usuario(), en 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

¿Hay una manera de obtener la información sobre el usuario actualmente conectado a un modelo?

Respuesta

3

Hay una buena solución de Matt Curry. Usted almacena los datos del usuario registrado actual en el app_controller utilizando la devolución de llamada beforeFilter y lo accede más tarde utilizando llamadas estáticas. Una descripción se puede encontrar aquí: http://www.pseudocoder.com/archives/2008/10/06/accessing-user-sessions-from-models-or-anywhere-in-cakephp-revealed/


EDIT: el enlace de arriba no está actualizado: https://github.com/mcurry/cakephp_static_user

+0

Gracias, esto parece la mejor solución! – Andrea

+0

El enlace graznó – mikermcneil

+0

que hizo un complemento para esa función .. ver la edición anterior – harpax

1

La manera más sucia sería simplemente acceder a la información del usuario en la Sesión. Menos cantidad de sobrecarga asociada con eso.

La forma "correcta" probablemente sería crear una instancia del objeto AuthComponent, para que haga todo lo que necesita para estar en pleno funcionamiento. Al igual que una estrella de la muerte, AuthComponent realmente no funciona bien cuando no está completamente configurado.

para obtener un nuevo objeto de CA, en el modelo:

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

Ahora puede usar $ this-> autenticación en el modelo, al igual que lo haría en el controlador.

+0

Aviso (8): Undefined property: AuthComponent :: $ Sesión [CORE/cake/libs/controller/componentes/auth.php, la línea 663] Fatal error: Call a una comprobación de función de miembro() en un no objeto en /var/www/MathOnline/cake/libs/controller/components/auth.php en la línea 663 – Andrea

+0

La creación de instancias por su cuenta, especialmente Controladores o Componentes, es una tarea complicada. Mejor uso 'ClassRegistry :: getInstance()' o 'ClassRegistry :: init()' (fuera de mi cabeza). – deceze

+0

@deceze ¿recomendaría usar esas funciones (en cambio) siempre en lugar de App :: import? He usado App :: import para modelos dentro de AppController bastantes veces, nunca he tenido ningún problema. Pero estoy dispuesto a cambiar si crees que es una mejor manera de hacerlo, ¿lo recomiendas? –

6

Creo que el código está bien como está y pertenece en el controlador, o por lo menos necesita recibir los identificadores del Controlador y no tratar de obtenerlos por sí mismo. El Modelo solo debe preocuparse de obtener datos de un almacén de datos y devolverlos. No debe preocuparse por cómo se manejan los datos en el resto de la aplicación o de dónde provienen los parámetros a su solicitud. De lo contrario, te pones en una esquina donde ReviewModel solo puede recuperar datos para los usuarios que han iniciado sesión, lo que puede no ser siempre lo que deseas.

Como tal, que haría uso de una firma función como esta:

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

$this->Review->findByBookAndUserId($id, $this->Auth->user('id')); 
+0

Tengo muchas solicitudes que solo captan datos vinculados al usuario actual. Solo trato de simplificar el código sin tener que pasar el ID de usuario a todas partes. – Andrea

+0

Solo para agregar algunos ejemplos, al hacer que su modelo de método espere un controlador (con datos de sesión), ya no puede usar fácilmente ese método de modelo en shells o casos de prueba (en los que no hay ningún controlador o sesión). – deizel

+0

@deizel Buen punto, también. Este movimiento puede crear dependencias innecesarias solo por el bien de guardar ~ 20 caracteres de código ... – deceze

10

La forma en que yo uso es la siguiente:

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

Parece que funciona bastante bien :-)

+0

Probado en Cake/2.2.x, funciona bien. –

+0

también funciona en 2.6.0 –

+0

funciona en 2.9.1. No necesitaba la aplicación: importar. –

13

Crea una nueva función en "app_model.php" ("AppModel.php" en CakePHP 2.x), por lo que estará disponible en todos los modelos dentro de nuestra aplicación:

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; 
} 

en el modelo:

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

utilizo torta 2.2 y éstos tanto trabajo grande:

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

También puede obtener un campo del usuario actualmente conectado:

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

Sin embargo, no en un modelo. – Scottymeuk

+0

En beforeFilter de su Controlador, asigne una variable de usuario en la variable de Model como: $ this-> MyModel-> user = $ this-> Session-> read ('Auth.user'); Ahora puede llamar a 'usuario' en su modelo. –

+0

El único problema es que debe asignarlo para cada modelo, lo que significa que va a terminar consumiendo mucha memoria. – Scottymeuk

1

Creo que esta no es una buena idea para obtener valor de la sesión. Una mejor solución para conseguir registra identificador de usuario en el interior de cualquier modelo simplemente puede hacer esto:

AuthComponent::user('id'); 

Esto funciona casi en todas partes. Vista, modelo y controlador

0

Ninguna de estas soluciones funciona en CakePHP versión 3. ¿Alguien sabe de una manera de hacer esto? En este momento, estoy caminando completamente por el marco accediendo a la variable $ _SESSION directamente desde mi modelo.

+1

Esto no es recomendado por cake: http://book.cakephp.org/3.0/en/development/sessions.html#sessions: generalmente se evita el uso de $ _SESSION en CakePHP – Bob

+1

Entendido, pero ¿cómo se accede al objeto de sesión? de un modelo luego en 3.0? La única forma que he encontrado para hacerlo es a través de $ _SESSION –

+0

Creé lo siguiente para obtener los datos de autenticación en todas partes ... http://cakemanager.org/docs/utils/1.0/components/globalauth/. Es algo;) ... ¡Y útil! – Bob

1

Para CakePHP 3.x este fácil componente está disponible: http://cakemanager.org/docs/utils/1.0/components/globalauth/. El acceso directo a la sesión no es posible debido a diferentes SessionKeys.

Con GlobalAuthComponent puede acceder a sus datos de usuario en todas partes con: Configure::read('GlobalAuth');.

Greetz

Bob

Cuestiones relacionadas