2012-01-01 20 views
1

私のユーザーモデルに対して次の検証コードが処理されています。ユーザーを作成するとうまくいきますが、更新するときには機能しません。私は'on' => 'create'を知っていますが、編集中にもルールを適用したいと思っています。ユーザーがユーザー名を変更できるようにしましたが、ユーザーが変更しているものがすでにDbになっている場合は、投稿を拒否する必要があります。ユーザー編集時のCakePHP isUnique検証

var $validate = array(
    'username' => array(
     'alphaNumeric' => array(
       'rule' => 'alphaNumeric', 
       'message' => 'Usa letras ou numeros como o teu <<Usuario>>', 
     ), 
     'between' => array(
       'rule' => array('between' , 5, 15), 
       'message' => 'O <<Usuario>> tens que ter entre 5 a 15 letras/numeros', 
     ), 
     'isUnique' => array(
       'rule' => 'isUnique', 
       'message' => 'O <<Usuario>> que escolhestes ja foi utilizado. Escolhe um outro.' 
     ) 
    ) 
); 

ユーザーがカスタム検証ルールがに作成することができ、編集ページに到達するにはログインする必要があるため:送信されたユーザ名がすでにAuth->ユーザー(に属している場合

  1. チェック'id')とそれが正常に提出されている場合
  2. しかし、送信されるユーザー名がAuth-> User( 'username')と異なる場合は、他のユーザーがこのユーザー名を持っていないかどうかを確認する必要があります。
  3. Auth-> User()がNULLの場合、これは通常、新しいユーザーの作成時に適用されるため、isUniqueは通常通り処理されます。

おかげキーが検証ルールに指定されていない、またはnullに設定されている「オン」、ルールの作成と更新操作の両方に適用される場合

チェック

答えて

2

私は次を使用して私の問題を解決することができました:

選択的に作成&アップデートが行くための正しい方法することができますが、一意性制約のために、それは普通ではない上、異なる検証する「on」に使用
var $validate = array(
    'username' => array(
     'third' => array(
       'rule' => array('checkUniqueName'), 
       'message' => 'O <<Usuario>> que escolhestes ja foi utilizado. Escolhe um outro.' 
     ) 
    ), 
    'email' => array(
     'second' => array(
      'rule' => array('checkUniqueEmail'), 
      'message' => 'Este email ja foi registado anteriormente. Contacta-nos se foi por engano' 
     ) 
    ) 
); 


function checkUniqueName($data) { 

    $isUnique = $this->find(
       'first', 
       array(
        'fields' => array(
         'User.id', 
      'User.username' 
        ), 
        'conditions' => array(
         'User.username' => $data['username'] 
        ) 
       ) 
     ); 

    if(!empty($isUnique)){ 

     if($this->authUserId == $isUnique['User']['id']){ 
      return true; //Allow update 
     }else{ 
      return false; //Deny update 
     } 
    }else{ 
     return true; //If there is no match in DB allow anyone to change 
    } 
    } 

function checkUniqueEmail($data) { 

    $isUnique = $this->find(
       'first', 
       array(
        'fields' => array(
         'User.id' 
        ), 
        'conditions' => array(
         'User.email' => $data['email'] 
        ) 
       ) 
     ); 

    if(!empty($isUnique)){ 

     if($this->authUserId == $isUnique['User']['id']){ 
      return true; //Allow update 
     }else{ 
      return false; //Deny update 
     } 
    }else{ 
     return true; //If there is no match in DB allow anyone to change 
    } 
    } 
+0

これはusersテーブルに対してのみ機能します。もっと一般的な解決策を用意していいですか? – geoidesic

1

、両方1.32.0手動で指定されるように:「更新」または「作成」:

「オン」キーは、次のいずれかの値のいずれかに設定することができます。これにより、新しいレコードの作成中またはレコードの更新中に特定のルールを適用できるようにするメカニズムが提供されます。

ルールで 'on' => 'create'が定義されている場合、ルールは新しいレコードの作成時にのみ適用されます。同様に、 'on' => 'update'と定義されている場合は、レコードの更新中にのみ適用されます。

'on'のデフォルト値はnullです。 'on'がnullの場合、ルールは作成と更新の両方で強制されます。

フォームにログインしているユーザーのIDを必ず含めている限り、入力したコードは編集フォームでも検証する必要があります。たとえば、次のようになります。

<?php echo $this->Form->create('User'); ?> 
<?php echo $this->Form->hidden('id', array('value' => AuthComponent::user('id'))); ?> 
<?php echo $this->Form->input('username'); ?> 
<?php echo $this->Form->end('Update Username'); ?> 

フォームがユーザー作成フォームの場合は、非表示のIDフィールドは含めません。

+0

- 例えばユーザーが1つの電子メールを使用してサインアップした後に、別の既存のユーザーの電子メールに変更して、システムから他のユーザーをロックしたり、アカウントをハイジャックしたりする可能性を排除する必要があります。 –

+0

良い点。そのため、上記の関数を作成することにしました。ありがとう! –

+0

IDは**表示されないようにしてください**。悪意のあるユーザーがフォームを送信する前にIDを変更して、別のレコードのフィールドを上書きできるようにするのは簡単です。代わりに '$ this-> request-> data ['User'] ['id'] = $ this-> Auth-> user( 'id'); > save($ this-> request-> data) 'を実行します。 – beporter