2012-05-03 14 views
5

created_by ve modified_by ile created ve modified'un CakePHP'de nasıl çalıştığına benzer bir yöntem olup olmadığını mı merak ediyorum?Oluşturulmuş ve değiştirilmiş olarak CakePHP'de nasıl çalışıldığına benzer şekilde created_by ve modified_by eklemenin bir yolu var mı?

Kekin bu alanları tanıdığı ve modelden bağımsız olarak, bunları uygulamak zorunda kalmadan otomatik olarak bunlarla ilgilenmesi gerçeğini beğeniyorum. Geçerli kullanıcı kimliğini kullanarak benzer bir özellik eklemek istiyorum (uygulamamda, bazen 0 olsa bile, her zaman bir kullanıcı kimliği vardır).

App_model'de başlangıç ​​yerinin before_save() olduğunu mu sanıyorum?

- Ayrıca

, beni otomatik olarak kullanıcı tabloya yabancı anahtar olarak bu tanıma (o user_id nasıl tanıdığı benzer) Pasta almak için herhangi bir yol yoktur, ya da ben vardır eklemek zorunda kalacak/ilişkiye manuel mi aittir? Bunu soruyorum çünkü bu çoğu modelimin üzerine çıkacak, bu yüzden gereksiz kodu azaltmayı tercih ediyorum.

Teşekkür ederiz!

cevap

6

Sorunuzun ilk bölümü için, ben aradığınız tam olarak ne yapmak için bu Davranış kodu kullanın:

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

Sonra sadece Modeli veya AppModel bunu beyan

var $actsAs = array('UserLink'); 

Sorunuzun ikinci kısmı için, muhtemelen davranışa bir beforeFind() geri çağrısı ekleyebilir veolan modeli bağlamak için model->bindModel() işlevini kullanabilirsiniz. Kullanıcı modeli ileve modified_by alanları. Kişisel olarak Her bir modelde bu bağlantıları, gerektiğinde el ile bildirmeyi tercih ediyorum.

+0

anlaşılması kolay olduğundan onun: http://bakery.cakephp.org/articles/danfreak/2009/03/01/whodidit -behavior-automagic-created_by-ve-modified_by-alanları – mark

+0

Bir çekicilik gibi çalışır ... Yine de sorunun ikinci yarısını bulmak isterdim, ama davranış alanları değiştirerek ve yaratmak için mükemmeldir. Teşekkürler! – xtraorange

+0

Bu sadece mükemmel. –

0

Oluşturulan ve değiştirilen alanla aynı olamaz ancak bu alanları istediğiniz yerde denetleyici yöntemine ekleyebilirsiniz. Örn.,

örn. ekle yönteminde aşağıdaki gibi ekleyebilirsiniz.

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

ben this one ve benim için iyi çalışırken buldum bu da uygulamak ve

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