2012-11-23 30 views

Trả lời

5

Trong mô hình của bạn, bạn phải làm một cái gì đó như thế này:

public function rules() { 
    return array(
     array('name, username, email, password', 'required', 'on' => 'create'), 
     array('name, username, email', 'required', 'on' => 'update'), 
    ); 
} 

Cho phép nói rằng kịch bản mà bạn chạy ngay bây giờ là bản cập nhật. Vì vậy, tôi không yêu cầu mật khẩu ở đó. Tôi yêu cầu nó chỉ trong kịch bản tạo ra mà bạn có thể có. Vì vậy, trong tệp xem bạn đã loại bỏ trường mật khẩu và bên trong hành động mà bạn có bạn bao gồm:

$model->setScenario('update'); 

vì vậy nó sẽ không yêu cầu mật khẩu và nó sẽ giữ nguyên.

Để thay đổi mật khẩu, bạn có thể tạo hành động mới (ví dụ: actionPassChange), nơi bạn sẽ yêu cầu nhập hai lần mật khẩu mới.

+0

Cảm ơn bạn đã giúp đỡ ur.but này không hoạt động –

+0

nếu bạn làm theo các tùy chọn kịch bản sau đó cho hành động mà bạn chạy ngay bây giờ, bạn phải đặt kịch bản ngay sau khi tải mô hình $. Bằng cách loại bỏ trường mật khẩu khỏi khung nhìn, việc xác thực sẽ không yêu cầu thuộc tính này. Vui lòng chỉ định lỗi của bạn để có ý tưởng tốt hơn về sự cố của bạn. –

+0

u có thể giải thích cho tôi breifly ?? –

2
$model->attributes=$_POST['JbJsJobResume']; 

thay vì assign tất cả các thuộc tính chỉ gán những chỉ bạn muốn lưu, như

$model->name=$_POST['JbJsJobResume']['name']; 
$model->save(); 
+0

$ model-> name = $ _ POST ['JbJsJobResume' ]['Tên']; cho dù là ['name'] là tên trường db hay tên trường biểu mẫu? –

+0

$ model-> tên ở đây tên là tên cột bảng và $ _POST ['JbJsJobResume'] ['name']; là dữ liệu biểu mẫu. print_r ($ _ POST) và tìm trong đó bài biến dữ liệu. – Hemc

7

Tôi nghĩ rằng một cách tiếp cận tốt hơn sẽ không sử dụng các kịch bản trong trường hợp này. Mã tiếp theo trong các quy tắc chỉ nói lên kịch bản: các trường tiếp theo là bắt buộc. Nhưng không: bỏ qua người khác.

array('name, username, email', 'required', 'on' => 'update'), 

Ví dụ, nếu chúng ta giới hạn độ dài của mật khẩu lên đến 32 ký tự, nhưng trong một cơ sở dữ liệu được lưu trữ trong một sha1 định dạng (chiều dài 40), sau đó chúng tôi có một vấn đề bởi vì các validator sẽ chặn các cơ sở dữ liệu query.Điều này là bởi vì khi bạn cập nhật, phương thức "validatе" kiểm tra tất cả các thuộc tính lớp (liên quan đến ánh xạ bảng cơ sở dữ liệu), không chỉ các thuộc tính mới được gửi qua bài đăng.

Có thể sử dụng phương thức "saveAttributes", nhưng sau đó tôi nhận thấy một vấn đề khác. Nếu cột "email" là duy nhất trong cơ sở dữ liệu và trong trường hợp email đã chỉnh sửa trùng lặp một trong số hiện có, thì hệ thống thư Yii được xác định trong quy tắc không thể thông báo và ném mã lỗi liên quan đến truy vấn cơ sở dữ liệu.

Cách tiếp cận dễ nhất tôi nghĩ là: không đặt viễn cảnh trong trường hợp này. Chỉ cần gửi như một đối số các thuộc tính mà bạn muốn. Điều này sẽ giữ cho tất cả các tính năng CRUD được tạo bởi GII.

Trong code của bạn nó trông như thế này: (trong mô hình)

public function rules() { 
    return array(
     array('name, username, email, password', 'required'), 
    ); 
} 

(trong điều khiển)

if($id==Yii::app()->user->id){ 
    $model=$this->loadModel($id); 
    if(isset($_POST['JbJsJobResume'])) { 
     $model->attributes=$_POST['JbJsJobResume']; 
     if($model->save(true, array('name', 'username', 'email'))) 
      $this->redirect(array('view','id'=>$model->id)); 
    } 

    $this->render('update',array('model'=>$model,)); 
} 

tôi nhận thấy rằng bạn không sử dụng RBAC. Nó rất tiện lợi và linh hoạt - hãy thử nó.

http://www.yiiframework.com/doc/guide/1.1/en/topics.auth#role-based-access-control

+0

Chỉ cần lưu ý rằng saveAttributes() không thực hiện xác thực trên dữ liệu đang được lưu. – crafter

+0

Làm việc cho tôi như quyến rũ +1 :) – Pupil

1

tùy chọn 1st Chỉ unset trường mật khẩu trước khi đặt nó:

function update(){ 
    $model=$this->loadModel($id); 
    unset($_POST['JbJsJobResume']['password']); 
    $model->attributes=$_POST['JbJsJobResume']; 
    $model->save(); 
} 

2 lựa chọn: Sử dụng tạm thời biến:

function update(){ 
    $model=$this->loadModel($id); 
    $temPassword = $model->passwrod; 
    $model->attributes=$_POST['JbJsJobResume']; 
    $model->passwrod = $temPassword; 
    $model->save(); 
} 

3 tùy chọn: sử dụng scenarios

1

tôi không chắc chắn tại sao đây là một vấn đề, và một số cá tuyết e có thể giúp chúng ta hiểu tại sao. Nếu bạn không muốn nắm bắt/cập nhật mật khẩu, thì tại sao trường mật khẩu trong biểu mẫu?

Nếu bạn xóa trường mật khẩu khỏi chế độ xem, giá trị của trường mật khẩu sẽ không được đăng lại cho bộ điều khiển và sau đó nó sẽ không được cập nhật.

Có một khả năng rằng các phương pháp trên không làm việc và điều này có thể là trong mô hình tài khoản của bạn, bạn đang mã hóa mật khẩu trong phương pháp afterValidate ?:

protected function afterValidate() 
{ 
    parent::afterValidate(); 
    $this->password = $this->encrypt($this->password); 
} 

public function encrypt($value) 
{ 
    return md5($value); 
} 

Trong tình huống này, nếu bạn loại bỏ trường mật khẩu từ dạng xem và chỉ cập nhật tên, tên người dùng hoặc email, khi đó mật khẩu md5 của mật khẩu sẽ được tự động băm lại và bạn sẽ mất mật khẩu thực.

Một phương pháp để giải quyết vấn đề này là md5 mật khẩu trong phương thức afterValidate (tạo hoặc cập nhật) tuy nhiên nếu người dùng muốn thay đổi chi tiết hồ sơ, trong cùng một biểu mẫu, yêu cầu người dùng xác minh lại mật khẩu của họ.

  1. MẪU: dùng thay đổi tên và xác minh mật khẩu
  2. Mẫu posted
  3. điều khiển gọi phương thức xác thực.
  4. Nếu xác thực thành sự thật, ghi đè lên các mục trong bảng người dùng (bao gồm cả xác nhận pw)
-1

Tôi nghĩ rằng câu trả lời @ Gravy là đúng, Cảm ơn Gravy và Nikos Tsirakis. Tôi đã khắc phục vấn đề gần giống như @faizphp. Tôi thêm kịch bản cho mô hình người dùng như Nikos Tsirakis nói, nhưng cũng có vấn đề tương tự. Sau đó, tôi thấy tôi mã hóa mật khẩu trong User.afterValidate, do đó, khi cập nhật mô hình User mọi lúc, chương trình mã hóa mật khẩu trong cơ sở dữ liệu một lần nữa để sai mật khẩu. Vì vậy, tôi đã thay đổi chức năng của tôi từ

protected function afterValidate() 
{ 
     parent::afterValidate(); 
     if (!$this->hasErrors()) 
      $this->password = $this->hashPassword($this->password); 
} 
</code> 


để

protected function afterValidate() 
{ 
     parent::afterValidate(); 
     if (!$this->hasErrors() && $this->scenario==="create") 
      $this->password = $this->hashPassword($this->password); 
} 

. Có vẻ như công việc.

Các vấn đề liên quan