2012-05-03 11 views
5

Zastanawiam się, czy istnieje sposób, aby dodać created_by i modified_by podobne do tego, jak created i modified pracować w CakePHP?Czy istnieje sposób na dodanie created_by i modified_by w sposób podobny do tworzenia i modyfikacji utworów w CakePHP?

Podoba mi się fakt, że ciasto rozpoznaje te pola i zajmuje się nimi automatycznie, niezależnie od modelu, bez konieczności ich implementacji w ogóle. Chciałbym dodać podobną funkcję przy użyciu bieżącego identyfikatora użytkownika (w mojej aplikacji zawsze jest identyfikator użytkownika, nawet jeśli czasem może być 0).

Zakładam, że miejscem startowym jest before_save() w app_model?

-

też jest jakiś sposób dla mnie, aby uzyskać ciasto automatycznie rozpoznaje to jako klucz obcy do tabeli użytkownika (podobny do tego, jak to ujmuje user_id), albo będę musiał dodać posiada/należy do relacji ręcznie? Pytam, ponieważ będzie to dotyczyć większości moich modeli, więc wolałbym zredukować kod nadmiarowy.

Dziękujemy!

Odpowiedz

6

Dla pierwszej części pytania, używam tego kodu Behavior zrobić dokładnie to, czego szukasz:

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

Następnie wystarczy zadeklarować ją w modelu lub swojej AppModel

var $actsAs = array('UserLink'); 

W drugiej części pytania prawdopodobnie można dodać wywołanie zwrotne beforeFind() i zastosować funkcję model->bindModel() w celu połączenia modelu o numerze created_by i modified_by pól z modelem użytkownika. Prywatnie wolę zgłaszać te linki w każdym modelu ręcznie, kiedy ich potrzebuję.

+0

jest również to: http://bakery.cakephp.org/articles/danfreak/2009/03/01/whodidit -behavior-automagic-created_by-and-modified_by-fields – mark

+0

Działa jak urok ... Nadal chciałbym dowiedzieć się drugiej części tego pytania, ale zachowanie jest idealne dla zmodyfikowanych i stworzonych przez pola. Dzięki! – xtraorange

+0

To jest po prostu idealne. –

0

Nie może być jak utworzone i zmodyfikowane pole, ale możesz dodać te pola w metodzie sterownika, gdziekolwiek chcesz.

np. w metodzie dodawania możesz dodać, jak poniżej.

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

znalazłem this one i działa dobrze dla mnie jego łatwe do wdrożenia i zrozumieć

<?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; 
} 
} 
Powiązane problemy