While using change password in Zend Form,I want to check old password and new password.Both should not be same.Is there any option in Zend Form to check the both.
Thanks in advance.
Create a Library under My and use the following:
class My_Validate_PasswordConfirmation extends Zend_Validate_Abstract
{
const NOT_MATCH = 'notMatch';
protected $_messageTemplates = array(
self::NOT_MATCH => 'Password confirmation does not match'
);
public function isValid($value, $context = null)
{
$value = (string) $value;
$this->_setValue($value);
if (is_array($context)) {
if (isset($context['password_confirm'])
&& ($value == $context['password_confirm']))
{
return true;
}
} elseif (is_string($context) && ($value == $context)) {
return true;
}
$this->_error(self::NOT_MATCH);
return false;
}
}
More Information at the : Zend Manual
Scroll down to or find :
Note: Validation Context
On the source page. Code is given right below it and so is the explanation.
Hope it helps! :)
Related
I am developing a Register/Login system with validation. Registering system is working well. For example, when I register the same email twice, the following message appears:
Email already registered!
However, when I log-in with the same e-mail and password, an error occurs. The following message appears as a validation error:
Email not registered!
Even if the email is registered in DB.
Code for e-mail validation:
<?php
public function validateEmail($par)
{
if (filter_var($par, FILTER_VALIDATE_EMAIL)) {
return true;
} else {
$this->setErro("Invalid Email!");
return false;
}
}
public function validateIssetEmail($email, $action = null)
{
$b = $this->cadastro->getIssetEmail($email);
if ($action == null) {
if ($b > 0) {
$this->setErro("Email already registered!");
return false;
} else {
return true;
}
} else {
if ($b > 0) {
return true;
} else {
$this->setErro("Email not registered!");
return false;
}
}
}
Code for login controller:
<?php
$validate = new Classes\ClassValidate();
$validate->validateFields($_POST);
$validate->validateEmail($email);
$validate->validateIssetEmail($email,"login");
$validate->validateStrongSenha($senha);
$validate->validateSenha($email,$senha);
var_dump($validate->getErro());
Code for class login:
<?php
namespace Models;
class ClassLogin extends ClassCrud
{
# Returns user data
public function getDataUser($email)
{
$b = $this->selectDB(
"*",
"users",
"where email=?",
array(
$email
)
);
$f = $b->fetch(\PDO::FETCH_ASSOC);
$r = $b->rowCount();
return $arrData = [
"data" => $f,
"rows" => $r
];
}
}
My getIssetEmail method exists on Register code only.
# Check directly at the bank if the email is registered
public function getIssetEmail($email)
{
$b = $this->selectDB(
"*",
"users",
"where email=?",
[
$email
]
);
return $r = $b->rowCount(); // returns the amount of rows in the search
}
And ClassPassword
<?php
namespace Classes;
use Models\ClassLogin;
class ClassPassword
{
private $db;
public function __construct()
{
$this->db = new ClassLogin();
}
# Create password's hash to save in DB
public function passwordHash($senha)
{
return password_hash($senha, PASSWORD_DEFAULT);
}
# Verify if password's hash is correct
public function verifyHash($email, $senha)
{
$hashDb = $this->db->getDataUser($email);
return password_verify($senha, $hashDb["data"]["senha"]);
}
}
This is not an answer but hopefully it will help in debugging.
First, I'm going to change your code. This is 100% a style choice but I personally think it is easier to follow. If you have an if statement that always returns, you don't technically need an else. Once again, this is a style choice and you don't have to follow it.
Second, if you can, try adding logging into your workflow, it will save you so much time debugging. It isn't always an option, especially for legacy code bases, but it is awesome when you can inspect complex code. In this example, I"m just making a couple of helper methods that dump stuff but normally I'd use something like Monolog to write to a stream that I can tail, and I can easily turn it off in production. When logging, sometimes it helps to avoid identical messages so that you can easily find the exact line number you are on, too.
So with those changes, try running this code inside of your class:
private function logMessage($message)
{
echo $message . PHP_EOL;
}
private function logVariable($variable)
{
var_dump($variable);
}
public function validateIssetEmail($email, $action = null)
{
$this->logVariable($email);
$this->logVariable($action);
$b = $this->cadastro->getIssetEmail($email);
$this->logVariable($b);
if ($action === null) {
$this->logMessage('Action was null');
if ($b > 0) {
$this->logMessage('B is greater than zero');
$this->setErro("Email already registered!");
return false;
}
$this->logMessage('B was not greater than zero');
return true;
}
$this->logMessage('Action was not null');
if ($b > 0) {
$this->logMessage('B is greater than zero');
return true;
}
$this->logMessage('B was not greater than zero');
$this->setErro("Email not registered!");
return false;
}
This should log in human-readable form every step. You should be able to walk through this and identify where your bug is. For instance, in the comments above you said that a variable was 0 in a block that was guarded by a check that guarantees that that shouldn't happen.
This is the wrong part i guess you assigned login as action so you can call cadastro class inside of the function
$cadastro = new Cadastro();
$b = $cadastro->getIssetEmail($email);
if ($action == null) {
if ($b > 0) {
$this->setErro("Email already registered!");
return false;
} else {
return true;
}
} else {
if ($b > 0) {
return true;
} else {
$this->setErro("Email not registered!");
return false;
}
}
I know this topic is existing, but no one could solve my problem.
I am using the library mewebstudio/captcha, everything is fine, but when I submit, it tells me always that the captcha is wrong.
My validation rules:
'captcha' => 'required|captcha'
In my html form:
<?= captcha_img(); ?>
<input type="text" name="captcha">
I am using php5.6, Laravel 5.1 and mews/captcha 2.2
My solution:
'captcha' => ['required' , new CheckCaptcha]
Rule class :
public function passes($attribute, $value)
{
return Hash::check($value, session('captcha.key'));
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'Invalid captcha';
}
I found a solution, I hope that will help someone in the future.
Well it is a bug in the library itself, where they delete the session key without checking the result:
public function check($value)
{
if ( ! $this->session->has('captcha'))
{
return false;
}
$key = $this->session->get('captcha.key');
$sensitive = $this->session->get('captcha.sensitive');
if ( ! $sensitive)
{
$value = $this->str->lower($value);
}
$this->session->remove('captcha');
return $this->hasher->check($value, $key);
}
So my solution is like that (you need to extend the class, override the method and bind the class to the new implementation):
public function check($value)
{
if ( ! $this->session->has('captcha'))
{
return false;
}
$key = $this->session->get('captcha.key');
$sensitive = $this->session->get('captcha.sensitive');
if ( ! $sensitive)
{
$value = $this->str->lower($value);
}
$isNotARobot = $this->hasher->check($value, $key);dd($isNotARobot);
if ($isNotARobot) {
$this->session->remove('captcha');
}
return $isNotARobot;
}
This is my callback function, I want to check the database for duplicate value, I have tried a lot, but I can't get validation to work. I'm new to Codeigniter so any help would be appreciated!
public function alias_exist_check()
{
$scol_code = $this->input->post('school_code');
$user_id=$this->input->post('user_id');
$query=$this->db->get_where('user_application',array('school_code'=>$scol_code, 'user_id'=>$user_id));
$row= $query->row_array();
if(!$row['user_id']==$user_id && !$row['school_code']==$scol_code)
{
return TRUE;
} else {
$this->form_validation->set_message('alias_exist_check', 'Already exists.');
return FALSE;
}
}
UPDATE1 ::
i tried this but its not working me help me if i wrote any mistakes.
$this->form_validation->set_rules('school_code', 'School Name','required','callback_alias_exist_check', 'trim|xss_clean'); $where = array(
'school_code' => $this->input->post('school_code'),
'user_id' => $this->input->post('post'));
if( ! $this->lawschool_model->alias_exist_check($where))
{
$this->form_validation->set_message('alias_exist_check', 'Already exists.');
}
if ($this->form_validation->run() == FALSE)
{
$data['row']= $this->lawschool_model->Getuser($data1);
$data['row1']= $this->lawschool_model->GetData1();
$this->ag_auth->view('Home',$data);
}
else
{
$insert = $this->db->insert('user_application',$data);
if($insert==TRUE)
{
/*$idNum = $this->input->post('school_code');
$data1 = $this->lawschool_model->upddata_school();*/
$data['row'] = $this->lawschool_model->Getuser($data1);
$data['row1'] = $this->lawschool_model->GetData1();
$this->ag_auth->view('Home',$data);
}
}
UPDATE2::finaly its works fine,here is my working code
$this->form_validation->set_rules('school_code', 'School Name','required','callback_alias_exist_check1', 'trim|xss_clean');
function alias_exist_check1($scol_code,$user_id)
{
$sql = "SELECT * FROM user_application WHERE school_code = ? AND user_id = ?";
$val = $this->db->query($sql,array($scol_code ,$user_id ));
if ($val->num_rows)
{
$this->form_validation->set_message('alias_exist_check', 'Already exists.');
return TRUE;
}
else
{
return FALSE;
}
}
Model
public function alias_exist($where)
{
return $this->db->where($where)->count_all_results('user_application') > 0;
}
Controller
public function alias_exist_check()
{
$where = array(
'school_code' => $this->input->post('school_code'),
'user_id' => $this->input->post('user_id')
);
return ! $this->name_model->alias_exist($where);
}
The first function was not working because you tried to access post data from within the callback itself. This does not appear to work well with callbacks. This is because codeigniter will remove all post data from the request as soon as your run the form validator run method. It repopulates post data only when form processing is complete. Pass any extra parameters you need for you callback functions to work like this
callback_foo[bar]
I wonder how Zend_Form validates inputs, I mean how does it know which input fields to validate. I looked to php globals($_POST, $_GET) and I didn't see anything set as an identifier(for example ) in order to know how validate. Can anyone suggest me any guide for this stuff?
Well, the best option to find out is to look at the code of Zend_Form:
/**
* Validate the form
*
* #param array $data
* #return boolean
*/
public function isValid($data)
{
if (!is_array($data)) {
require_once 'Zend/Form/Exception.php';
throw new Zend_Form_Exception(__METHOD__ . ' expects an array');
}
$translator = $this->getTranslator();
$valid = true;
$eBelongTo = null;
if ($this->isArray()) {
$eBelongTo = $this->getElementsBelongTo();
$data = $this->_dissolveArrayValue($data, $eBelongTo);
}
$context = $data;
foreach ($this->getElements() as $key => $element) {
if (null !== $translator && $this->hasTranslator()
&& !$element->hasTranslator()) {
$element->setTranslator($translator);
}
$check = $data;
if (($belongsTo = $element->getBelongsTo()) !== $eBelongTo) {
$check = $this->_dissolveArrayValue($data, $belongsTo);
}
if (!isset($check[$key])) {
$valid = $element->isValid(null, $context) && $valid;
} else {
$valid = $element->isValid($check[$key], $context) && $valid;
$data = $this->_dissolveArrayUnsetKey($data, $belongsTo, $key);
}
}
foreach ($this->getSubForms() as $key => $form) {
if (null !== $translator && !$form->hasTranslator()) {
$form->setTranslator($translator);
}
if (isset($data[$key]) && !$form->isArray()) {
$valid = $form->isValid($data[$key]) && $valid;
} else {
$valid = $form->isValid($data) && $valid;
}
}
$this->_errorsExist = !$valid;
// If manually flagged as an error, return invalid status
if ($this->_errorsForced) {
return false;
}
return $valid;
}
which means in a nutshell, Zend_Form will iterate over all the configured elements in the form and compare them against the values in the array you passed to it. If there is a match, it will validate that individual value against the configured validators.
So, you create form in action and then check is there post|get data. You can check is_valid form right here. You need pass $_POST or $_GET data to isValid() function. Example:
if ($request->isPost() && $form->isValid($request->getPost())) {
isValid() is function Zend_Form class. Form runs all validations for each element (just if you dont set to stop in first validation fail) and then for subforms too.
Look at Zend_Form quickstart, it's a very bright example on how to start dealing with forms in Zend.
Validating a text input looks like this:
$username = new Zend_Form_Element_Text('username');
// Passing a Zend_Validate_* object:
$username->addValidator(new Zend_Validate_Alnum());
// Passing a validator name:
$username->addValidator('alnum');
Or you can use:
$username_stringlength_validate = new Zend_Validate_StringLength(6, 20);
$username = new Zend_Form_Element_Text('username');
$username->setLabel('Username: ')
->addFilters(array('StringTrim', 'HtmlEntities'))
->setAttrib('minlength', '6')
->setAttrib('class', 'required')
->removeDecorator('label')
->removeDecorator('HtmlTag')
->removeDecorator('DtDdWrapper')
->setDecorators(array(array('ViewHelper'), array('Errors')))
->addValidator($username_stringlength_validate);
I did register form in with zend form
$password = new Zend_Form_Element_Password('password');
$password->setLabel($this->_translate->_("Password:"))
->setRequired(true)
->addValidator('stringLength', true, array(4, 32));
$confirmPassword = new Zend_Form_Element_Password('confirmpassword');
$confirmPassword->setLabel($this->_translate->_("Confirm Password:"))
->setRequired(true);
I control password and confirmpassword in controller. if password and confirmpassword don't match then add error message under confirmpassword textbox. how i do?
Override isValid in your form
/**
* Validate the form, check passwords.
*
* #param array $data
* #return boolean
*/
public function isValid($data) {
$valid = parent::isValid($data);
if ($this->getValue('password') !== $this->getValue('password2')) {
$valid = false;
$this->password2->addError('Passwords don\'t match.');
}
return $valid;
}
The concept basically boils down to adding a Zend_Validate_Identical validator to the 'confirmpassword' field, using the data from the $this->_request->getParam('password') to test against. I use a custom method on an extended Zend_Form to process the post data from all my forms, it isn't an exact solution for you, but perhaps my code from my "EditUser" form can point you in the right direction.
From the controller:
// $form is a MW_Form_EditUser.
if ($this->_request->isPost() && $form->process($this->_request->getPost()))
{
// successful form - redirect or whatever here
}
From the MW_Form_EditUser class:
public function process(array $data)
{
// gets a copy of the user we are editing
$user = $this->getEditable();
// checks to see if the user we are editing is ourself
$isSelf = ($user->id == MW_Auth::getInstance()->getUser()->id);
// if the new_pass field is non-empty, add validators for confirmation of password
if (!empty($data['new_pass']))
{
$this->new_pass2->setAllowEmpty(false)->addValidator(
new Zend_Validate_Identical($data['new_pass'])
);
if ($curpass = $this->current_password) $curpass->setAllowEmpty(false);
}
if ($this->delete && !empty($data["delete"])) {
$this->delete->setValue(true);
$user->delete();
return true;
}
if ($this->isValid($data))
{
/// saves the data to the user
$user->email = $this->email->getValue();
$user->name = $this->name->getValue();
if ($password = $this->new_pass->getValue()) $user->password = $password;
if (!$isSelf)
{
if ($this->super->getValue()) {
$user->setGroups(array(MW_Auth_Group_Super::getInstance()));
} else {
$user->setGroups(array(MW_Auth_Group_User::getInstance()));
}
}
$user->save();
return true;
}
return false;
}
//inside form
public function isValidPSW($data) {
$valid = parent::isValid($data);
if ($data['pswd'] !== $data['pswd2']) {
$valid = false;
$this->pswd->addError('Passwords don\'t match.');
}
return $valid;
}
Using Zend_Validate_Identical is a good solution for you by Zend. I will give you another choice. jQuery. When you are using Zend_Validate_Identical form will go to the server and server will validate it. If passwords are not same it will return an error message. If you use jQuery form will not go to the server unless passwords are same.