2012-05-03 5 views
5

Mi chiedo se sia possibile aggiungere created_by e modified_by in modo simile a come funzionano created e modified in CakePHP?C'è un modo per aggiungere created_by e modified_by in modo simile a come sono stati creati e modificati i lavori in cakePHP?

Mi piace il fatto che la torta riconosca quei campi e si prenda cura di loro automaticamente, indipendentemente dal modello, senza che io debba implementarli del tutto. Vorrei aggiungere una funzionalità simile usando l'id utente corrente (nella mia applicazione, c'è sempre un ID utente, anche se a volte può essere 0).

Suppongo che il punto di partenza sia before_save() in app_model?

-

Inoltre, c'è un modo per me di ottenere torta di riconoscere questo come una chiave esterna per la tabella utente automaticamente (simile a come riconosce user_id), o dovrò aggiungere l'ha/appartiene alla relazione manualmente? Chiedo perché questo accadrà sulla maggior parte dei miei modelli, quindi preferirei ridurre il codice ridondante.

Grazie!

risposta

6

Per la prima parte della tua domanda, io uso questo codice di comportamento per fare esattamente quello che stai cercando:

class UserLinkBehavior extends ModelBehavior 
{ 
    /** 
    * The string to use to retrieve the user id from CakeSession 
    * 
    * @var string 
    */ 
    var $user_id_key = 'Auth.User.id'; 

    function setup(&$model, $settings) 
    { 
     if(isset($settings['user_id_key'])) 
     { 
      $this->user_id_key = $settings['user_id_key']; 
     } 
    } 

    function beforeSave(&$model) 
    { 
     App::uses('CakeSession', 'Model/Datasource'); 

     $logged_user_id = CakeSession::read($this->user_id_key); 

     if(isset($logged_user_id)) 
     { 
      $this->set_user_on_current_model($model, $logged_user_id); 
     } 

     return true; 
    } 

    /** 
    * Set the created_by and modified_by user id on the current model 
    * 
    * @param Model $model 
    * @param int $logged_user_id 
    * @return void 
    */ 
    private function set_user_on_current_model(&$model, $logged_user_id) 
    { 
     if(isset($logged_user_id)) 
     { 
      /* 
      * Id is not set -> it is a creation 
      */ 
      if($model->hasField('created_by') && (!isset($model->data[$model->alias]['id']) || empty($model->data[$model->alias]['id']))) 
      { 
       if(!isset($model->data[$model->alias]['created_by'])) 
       { 
        $model->data[$model->alias]['created_by'] = $logged_user_id; 

        /* 
        * If the save is called with a whitelist, add 'created_by' to the whitelist 
        * in order to have this field saved as well 
        */ 
        if(!empty($model->whitelist) && !in_array('created_by', $model->whitelist)) 
        { 
         $model->whitelist[] = 'created_by'; 
        } 
       } 
      } 

      /* 
      * Id is set -> it is an update 
      */ 
      if($model->hasField('modified_by') && isset($model->data[$model->alias]['id']) && !empty($model->data[$model->alias]['id'])) 
      { 
       $model->data[$model->alias]['modified_by'] = $logged_user_id; 

       /* 
       * If the save is called with a whitelist, add 'modified_by' to the whitelist 
       * in order to have this field saved as well 
       */ 
       if(!empty($model->whitelist) && !in_array('modified_by', $model->whitelist)) 
       { 
        $model->whitelist[] = 'modified_by'; 
       } 
      } 
     } 
    } 
} 

Poi basta dichiararlo nel vostro modello o il vostro AppModel

var $actsAs = array('UserLink'); 

Per la seconda parte della domanda, è possibile aggiungere probabilmente un callback beforeFind() al comportamento e utilizzare la funzione model->bindModel() per collegare il modello con lo created_by e modified_by campi con un modello utente. Personalmente preferisco dichiarare manualmente questi collegamenti in ogni modello quando ne ho bisogno.

+0

c'è anche questo: http://bakery.cakephp.org/articles/danfreak/2009/03/01/whodidit -behavior-automagic-created_by-and-modified_by-fields – mark

+0

Funziona come un incantesimo ... Mi piacerebbe ancora capire la seconda parte della domanda, ma il comportamento è perfetto per essere modificato e creato dai campi. Grazie! – xtraorange

+0

Questo è semplicemente perfetto. –

0

Non può essere come il campo creato e modificato, ma è possibile aggiungere questi campi nel metodo controller ovunque si desideri.

es. nel metodo add è possibile aggiungere come segue.

$this->request->data['ModelName']['created_by'] = $this->Auth->user['userid']; 
0

ho trovato this one e lavorare bene per me la sua facile da implementare e capire

<?php 

App::uses('Model', 'Model'); 

class AppModel extends Model { 
//get current logged-in user 
    public function getCurrentUser() { 
    App::uses('CakeSession', 'Model/Datasource'); 
    $Session = new CakeSession(); 
    $user = $Session->read('Auth.User'); 
    return $user['id']; 
    } 

//populate created_by and modified_by 
    public function beforeSave($options = array()) { 
    parent::beforeSave($options); 
    //find all fields from table created_by/modified_by exists 
    $fields = array_keys($this->getColumnTypes()); 

    //get modal name to feed in data in appropriate array key   
    $modal = array_keys($this->data); 
    $modal = $modal[0]; 

    //add created_by value 
    if(in_array('created_by', $fields) && !isset($this->data[$modal]['id'])){ 
     //correct this line 
     $this->data[$modal]['created_by'] = $this->getCurrentUser()==null?-1:$this->getCurrentUser(); 
     return true; 
    }elseif(in_array('modified_by', $fields)){ 
     $this->data[$modal]['modified_by'] = $this->getCurrentUser()==null?-1:$this->getCurrentUser(); 
     return true; 
    } 
    return true; 
} 
}