I'm working on the signup process and want to check if the two passwords (password + re-entered password) are equal. These are my validation rules in the User Model:
var $validate = array(
'username' => array(
'notEmpty' => array(
'rule' => array('minLength', 5),
'required' => true,
'allowEmpty' => false,
'message' => 'User name has to be at least 5 characters long'
),
array(
'rule' => 'isUnique',
'message' => 'User name taken. Use another'
)
),
'password' => array(
'notEmpty' => array(
'rule' => array('minLength', 6),
'required' => true,
'allowEmpty' => false,
'message' => 'Password has to be at least 6 characters long'
),
'password_similar' => array(
'rule' => 'checkPasswords',
'message' => 'Entered passwords does not match'
)
),
'email' => array(
'rule' => 'email',
'required' => true,
'allowEmpty' => false,
'message' => 'Please enter a valid email'
)
);
In the users_controller.php I have the checkPasswords function:
function checkPasswords($data) {
if($data['password'] == $this->data['User']['password2hashed'])
return true;
else
return false;
}
An my singup function looks like this:
function signup(){
if (!empty($this->data)) {
if(isset($this->data['User']['password2']))
$this->data['User']['password2hashed'] = $this->Auth->password($this->data['User']['password2']);
$this->User->create();
if ($this->User->save($this->data)) {
.
.
.
}
No matter what I do, the passwords do not match. Even if I change the checkPasswords function to this:
function checkPasswords($data) {
return true;
}
What could cause this behavior?
OMG I just realised that the checkPasswords Function is not supposed to be in the controller but in the model. Problem solved, I'm ashamed...
Related
I am trying to add validation on change password function but it doesn't work.
I have added
->add('repeat_password', [
'equalToPassword' => [
'rule' => function ($value, $context) {
return $value === $context['data']['new_password'];
},
'message' => __("Your password confirm must match with your password.")
]
]);
to Users model
and in my controller
$user = $this->Users->get($this->_User['user_id']);
if ($this->request->is(['patch', 'post', 'put'])) {
$user = $this->Users->createEntity($user, ['password' => $this->request->data['repeat_password']]);
// $verify = (new DefaultPasswordHasher)->check($this->request->data['old_password'], $user->password);
// debug($verify);
//if ($verify) {
if ($this->Users->save($user)) {
$this->Flash->success('The password has been changed');
$this->redirect(['action' => 'index']);
} else {
$this->Flash->error('Password could not be issued');
}
}
// else {
// $this->Flash->error('Password Do not match');
// }
// }
}
It saves data without validating. What is the solution ?
Without having checked your code thoroughly, my first thought is that CakePHP 3 already provides the built-in validator compareWith for this purpose.
Try setting the validation rules as follows:
$validator->add('repeat_password', [
'compareWith' => [
'rule' => ['compareWith', 'new_password'],
'message' => __("Your password confirm must match with your password.")
]
]);
Also, check that both new_password and repeat_password are set to true in the $_accessible array.
public $validate = array(
'password' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A password is required'
),
'min_length' => array(
'rule' => array('minLength', '6'),
'message' => 'Password must have a mimimum of 6 characters'
)
),
'password_confirm' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'Please confirm your password'
),
'equaltofield' => array(
'rule' => array('equaltofield','password'),
'message' => 'Both passwords must match.'
)
),
)
please write code in your model more detail please check below link
http://miftyisbored.com/a-complete-login-and-authentication-application-tutorial-for-cakephp-2-3/
Sorry before, i have a function add answer for answering question in my article, so when user add answer for a question, system will sending an email to user who wrote this question. This is my function in controller :
public function add($question_id = null) {
if ($this->request->is('post')) {
$this->loadModel('Question');
$this->Answer->set(array('question_id'=>$question_id));
$this->Answer->create();
$user = $this->Question->find('all',array('fields' => 'Useri.email',
'joins' => array(array('conditions' => array('Useri.id = Question.user_id'),
'table' => 'users',
'alias' => 'Useri',
'type' => 'INNER'))));
$email = new CakeEmail();
$email->config('server');
$email->template('answer');
$email->viewVars(array(
'to'=>$user['User']['email']
));
$email->to($user);
$email->from(array('gais#wahanaartha.com' => 'IT Sharing Knowledge Team'));
$email->subject('Sharing Knowledge Notification');
$result=$email->send();
if ($this->Answer->save($this->request->data)) {
$this->Question->updateAll(array('Question.status' => '1'),
array('Question.id' => $question_id));
$this->Session->setFlash(__('The answer has been saved.'));
return $this->redirect(array('controller' => 'questions', 'action' => 'view', $question_id));
} else {
$this->Session->setFlash(__('The answer could not be saved. Please, try again.'));
return $this->redirect(array('controller' => 'questions', 'action' => 'view', $question_id));
}
}
$questions = $this->Answer->Question->find('list');
$users = $this->Answer->User->find('list');
$this->set(compact('questions', 'users', 'tests'));
}
<?php
App::uses('AppModel', 'Model');
class Question extends AppModel {
public $validate = array(
'topic_id' => array(
'rule' => 'numeric',
'required' => true,
'message' => 'Topic must be choosen !'
),
'user_id' => array(
'rule' => 'numeric',
'required' => true,
'message' => 'User must be choosen !'
),
'question' => array(
'minLength' => array(
'rule' => array('minLength', 12),
'required' => true,
'message' => 'Question min. 12 characters !'
),
'unique' => array(
'rule' => array('checkUnique', 'question'),
'message' => 'Question don\'t be same !'
)
),
'description' => array(
'minLength' => array(
'rule' => array('minLength', 12),
'required' => true,
'message' => 'Description min. 12 characters !'
),
'unique' => array(
'rule' => array('checkUnique', 'description'),
'message' => 'Description don\'t be same !'
)
)
);
public $belongsTo = array(
'Topic' => array(
'className' => 'Topic',
'foreignKey' => 'topic_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
public $hasMany = array(
'Answer' => array(
'className' => 'Answer',
'foreignKey' => 'question_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
function checkUnique($data, $fieldName) {
$valid = false;
if(isset($fieldName) && $this->hasField($fieldName)) {
$valid = $this->isUnique(array($fieldName => $data));
}
return $valid;
}
}
But when run this code, there is error "Invalid Email 'Array'", i have been check my query, when i run my query in navicat is fine, any help will be greatly appreciated
thanks
Concording with CakeEmail :
**to( ) public
To
Parameters
mixed $email optional null
Null to get, String with email, Array with email as key, name as value or email as value (without name)
string $name optional null
Returns
mixed
mixed**
So your $user array must like : ["email1#mail.com"=>"Name User", "email2#mail.com"=>"Name User2"]
or a string : "email#mail.com" .
Try this ! and tell me more about.
(try to set $email->to(array('mail#mail.com'=>'Name User') );
If isnt work , please tell us more about your bug
some users can resgister with null values in my cakephp website !!
when i try to register with null value im getting the error messages of my model, but someone do that, i found 8 users with no data (no usernam, no email, no names... !!!!! )
this is my signup (add) action:
if($this->request->is('Post')){
$this->User->create();
$this->request->data['User']['user_id'] = $this->Auth->User('id');
if($this->User->save($this->request->data)){
$iduser=$id=$this->User->getLastInsertId();
$this->Session->setFlash(_('your accoutn has been created, check you inbox.'));
$this->redirect(array('action'=>'login',$iduser));
}
else
$this->Session->setFlash(_('Erreur !'));
}
$this->set('title_for_layout','users sign up');
and this is a part of my users model :
public $validate =array(
'username' => array(
'length' => array(
'rule' => array('minLength', 5),
'message' => 'error !',
'required' => true,
),
'alphanum' => array(
'rule' => 'alphanumeric',
'message' => 'error !',
),
'unique' => array(
'rule' => 'isUnique',
'message' => 'error !)',
),
),
'password' => array(
'length' => array(
'rule' => array('minLength', 6),
'message' => 'error !',
'required' => true,
'on' => 'create'
),
'alphanum' => array(
'rule' => 'alphanumeric',
'message' => 'error !',
'on' => 'create'
),
),
'email' => array(
'email' => array(
'rule' => 'email',
'message' => 'error !',
),
'unique' => array(
'rule' => 'isUnique',
'message' => 'error !',
),
),
(other fields are checked too)
so, how someone can signup with no data ??????!
please help !
Are the creating the accounts and then removing the data thereafter?
Is there the facility for the user to edit these details out later on?
You need to specify which fields are empty and post the full validation from the controller.
This seemed to be working perfectly, I added a checkbox to my form so the user can decide whether to change the password or not. In the add user action the validation works fine and won't save the user if there are any errors, but with my edit user action it will still save them when both password fields are blank, but still validate them properly if there's any data in either password input. Here's my model:
class User extends AppModel {
var $name = 'User';
var $displayField = 'name';
var $validate = array(
'username' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'User must have a username to login with',
),
),
'password' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'User must have a password',
),
'alphanumeric' => array(
'rule' => array('alphanumeric'),
'required' => true,
'message' => 'User must have a password'
),
'minlength' => array(
'rule' => array('minlength', 6),
'message' => 'Password must be at least 6 characters',
),
'confirmPassword' => array(
'rule' => array('confirmPassword', 'password'),
'message' => 'Passwords do not match'
),
),
'password_confirm' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'User must have a password',
),
'alphanumeric' => array(
'rule' => array('alphanumeric'),
'required' => true,
'message' => 'User must have a password'
),
'minlength' => array(
'rule' => array('minlength', 6),
'message' => 'Password must be at least 6 characters',
),
),
);
function confirmPassword($data) {
return ($data['password'] === Security::hash(Configure::read('Security.salt').$this->data['User']['password_confirm']));
}
And here's my edit user action:
function admin_edit($id = null) {
$this->set('title_for_layout', 'Users / Editing User');
if (!$id && empty($this->data)) {
$this->Session->setFlash(__('Invalid user specified', true), 'flash_error');
$this->redirect(array('action' => 'index'));
}
if (!empty($this->data)) {
$redirect = array('action' => 'index');
if ($this->data['User']['edit_password'] == 1) {
$fields = array('username', 'confirm_password', 'password', 'name');
if ($this->data['User']['id'] == $this->Auth->user('id')) {
$redirect['action'] = 'logout';
}
} else {
$fields = array('username', 'name');
}
if ($this->User->save($this->data, true, $fields)) {
$this->Session->setFlash(__(sprintf('The user <i>%s</i> was saved successfully.', $this->data['User']['username']), true), 'flash_success');
$this->redirect($redirect);
} else {
$this->Session->setFlash(__('There were errors when trying to save the user', true), 'flash_error');
}
}
if (empty($this->data)) {
$this->data = $this->User->read(null, $id);
$this->data['User']['password'] = '';
$this->data['User']['edit_password'] = 0;
}
}
Sorry in advance as this is only a half-answer, but should get you moving in the right direction.
The Auth component will automatically hash the password field if the username field is also present in the submitted data
So you have set up your data to either anticipate this.. or avoid it.
This method will come in handy too.
http://book.cakephp.org/view/1259/hashPasswords
I have a custom validation rule to check if two passwords entered are the same, and if they arent I wish to have a message that says "Passwords do not match".
The rule works, however, when the passwords don't match it simply displays the normal error message, what's going on?
var $validate=array(
'passwd2' => array('rule' => 'alphanumeric',
'rule' => 'confirmPassword',
'required' => true,
'allowEmpty'=>false));
function confirmPassword($data)
{
$valid = false;
if ( Security::hash(Configure::read('Security.salt') .$data['passwd2']) == $this->data['User']['passwd'])
{
$valid = true;
$this->invalidate('passwd2', 'Passwords do not match');
}
return $valid;
}
It says "This field cannot be left blank"
EDIT:
The strange thing is, if I leave one of the password fields blank, both error messages say "This field cannot be left blank"
However, if I put something in both, then it correctly says "Passwords do not match"
I think you made it too complex. Here is how I do it:
// In the model
public $validate = array(
'password' => array(
'minLength' => array(
'rule' => array('minLength', '8')
),
'notEmpty' => array(
'rule' => 'notEmpty',
'required' => true
)
),
'confirm_password' => array(
'minLength' => array(
'rule' => array('minLength', '8'),
'required' => true
),
'notEmpty' => array(
'rule' => 'notEmpty'
),
'comparePasswords' => array(
'rule' => 'comparePasswords' // Protected function below
),
)
);
protected function comparePasswords($field = null){
return (Security::hash($field['confirm_password'], null, true) === $this->data['User']['password']);
}
// In the view
echo $form->input('confirm_password', array(
'label' => __('Password', true),
'type' => 'password',
'error' => array(
'comparePasswords' => __('Typed passwords did not match.', true),
'minLength' => __('The password should be at least 8 characters long.', true),
'notEmpty' => __('The password must not be empty.', true)
)
));
echo $form->input('password', array(
'label' => __('Repeat Password', true)
));
You should use the 'message' key in your $validate array to specify the message:
'message' => 'Your passwords do not match'
Further reading: http://book.cakephp.org/view/1143/Data-Validation
And then you can access the fields and the messages by $this->modelName->invalidFields(), which will return you the fields that didn't pass the validation and the message that you have setted for them...
In the controller I mean...
http://book.cakephp.org/view/1182/Validating-Data-from-the-Controller