How to create client side self defined rule in yii - php

I want to use reset password functionality in Yii. For that I have 4 fields i.e email, currentPassword, newPassword, newPasswordRepeat.
I have used following rules in my model
array('email, currentPassword, newPassword, newPasswordRepeat', 'required'),
array('newPasswordRepeat', 'compare', 'compareAttribute'=>'newPassword'),
array('currentPassword', 'equalPasswords'),
where equalPasswords is my user defined rule which checks whether currentPassword password match with my original password or not.
public function equalPasswords($currentPassword)
{
$oDbConnection = Yii::app()->db;
$oCommand = $oDbConnection->createCommand('SELECT * FROM Superadmin_details where email=:email');
$oCommand->bindParam(':email', Yii::app()->session['email'],PDO::PARAM_STR);
$user=$oCDbDataReader = $oCommand->queryRow();
if ($user['password'] != $currentPassword)
$this->addError($currentPassword, 'Old password is incorrect.');
}
This rule gives error on server side, i.e when I click on Submit button, page gets reloaded and then error gets displayed.
I want to display error on client side like other errors.
And I have enabled client side validation in form.
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'contact-form',
'enableClientValidation'=>true,
'clientOptions'=>array(
'validateOnSubmit'=>true,
),
)); ?>

Try to change
$this->addError($currentPassword, 'Old password is incorrect.');
to
$this->addError('currentPassword', 'Old password is incorrect.');
EDIT:
Also, you need AJAX validation:
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'contact-form',
'enableClientValidation'=>true, 'enableAjaxValidation' => true,
'clientOptions'=>array(
'validateOnSubmit'=>true,
),
)); ?>
and in top of your controller action:
if (array_key_exists('ajax', $_POST) && $_POST['ajax'] === 'contact-form') {
echo CActiveForm::validate($model);
Yii::app()->end();
}

Best way is to extend the CValidator class. Inside there you can override two methods validateAttribute and clientValidateAttribute. What you need is the second one. clientValidateAttribute. Make sure you have enable client side validation.
'enableClientValidation'=>true,
Sample:
class MyValidation extends CValidator
{
protected function validateAttribute($object,$attribute)
{
//TODO: server side validation
}
public function clientValidateAttribute($object,$attribute)
{
//TODO: client side javascript
}
}

Related

Yii - Textfield validation not working

I'm new to Yii framework. Now I'm using two textfields for min size and max size. Now this textfields are supposed to take only integers. But they are taking alphabets also. I used the following rule in model file.
public function rules() {
return array(
array('min_size, max_size', 'numerical', 'integerOnly'=>true));
}
But this seems to be not working, no error is displayed . How can i validate successfully, by displaying error when text is entered. Should I make some changes in main.php
Look for this kind of form in your code
<?php
$form = $this->beginWidget('CActiveForm', array(
'id' => 'trip-form',
'enableAjaxValidation' => true,
'enableClientValidation' => true,
?>
if you want ajax validation to take place then this line must be uncommented in controller
$this->performAjaxValidation($model);
Client validation will automatically take place
Just try Adding this instead of that
if (isset($_POST['ajax']) && $_POST['ajax'] === "your_form_id") {
echo CActiveForm::validate($model);
Yii::app()->end();
}
This will check with the model when the ajax request is received

Lithium and validating login form (without model) - how?

Is there any way to use Validator on login form from Simple Authentication in Lithium tutorial. I know that it is better to use validation in model, but with login form there's no model, so, as I understand, I need to use Validator in the SessionsController, but I don't know how to do it (
What I am trying to do is in SessionsController:
<?php
namespace app\controllers;
use lithium\security\Auth;
use lithium\storage\Session;
use lithium\util\Validator;
class SessionsController extends \lithium\action\Controller {
private $rules = array(
'password' => array(
array('notEmpty', 'message' => 'password is empty'),
),
'email' => array(
array('notEmpty', 'message' => 'email is empty'),
array('email', 'message' => 'email is not valid')
)
);
public function add() {
if ($this->request->data && Auth::check('default', $this->request)) {
return $this->redirect('/');
}
// Handle failed authentication attempts
$errors = Validator::check($this->request->data, $this->rules);
return compact('errors');
}
public function delete() {
Auth::clear('default');
return $this->redirect('/');
}
/* ... */
}
and I'm expect that after empty form was sent, it will be rendered with errors, like in user creation from tutorial. But there are no errors showed, just login form again. Can I ever validate forms without models and how to do it in Lithium?
Thanks beforehand.
The errors rendered in the form are bound to an entity, which is bound to the form when you create it with $this->form->create($user). In this case only, the errors are displayed thanks to the form helper automatically.
If your need is to check, in the controller, the incoming data, you can check $this->request->data['password'] and return errors that you need to handle by yourself in the form view (with if (!empty($errors)) for example)

Cake PHP Validation not happening

Im new to cakePHP.I just learning the way to validate the data before storing into the database.I just did the following validation to check the birth date given by the user.
class User extends AppModel {
public $name = "Users";
public $validate = array (
'birth_dt' => array ( 'rule' => 'date',
'required' => true,
'allowEmpty' => false,
'message' => 'Please Give valid date' ));
}
I expected a error message when I give wrong data in the birth_dt field.But there is no errors in case of wrong data ,bug the data is not getting store in the database.If I give the valid data also the data is not getting stored.If I remove the validation part then data getting stored in the database.
It not only happen for date ,it happen for other fields like alphaNumeric ,email which I used in my form.Any one please tell what I did wrong.
This is my controller code,
<?php
class UsersController extends AppController{
var $name = 'Users';
var $uses = array('User','Dob');
var $helpers = array('Form');
function index() {
if ($this->request->is('post')) {
if ($this->request->data) {
$this->User->save ( $this->request->data );
$this->Session->setFlash("User Added!");
$this->redirect('/users');
}
}
}
There can be multiple possible issue.Try following.
Before saving user Create new record like this->User->create();
You don't have else part. Write like following in else & check,
else {
$this->Session->setFlash(__('User could not be saved',true));
}
You can check why save() failed by examining the validationErrors array in the User model. From the UsersController it can be access via $this->User->validationErrors.
Furthermore, your controller logic isn't quite right. A was mentioned in some of the comments, you don't check if save() was successful and you always state that a user was added, even when it's not true.
Try something like this:
if($this->request->is('post') && !empty($this->data)) {
if($this->User->save($this->data)) {
$this->Session->setFlash('User added!', 'flash_good');
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash('Could not add player.', 'flash_bad');
}
}
This way, when save() fails for some reason, the user will remain in that action and the form will still be populated with the data the user entered. Furthermore, if you use $this->Form->input(...) to create you form elements the validation errors will be added to the form automagically.
I think your public $validate is wrongly written
Try this
class User extends AppModel {
public $name = "Users";
//For more strict validation you should have more than one parameter
//submitted to the rule array for date which requires the user to enter
// exactly what you need. for example 01/01/12 instead of 01/01/2012
//Please check the following address
//http://book.cakephp.org/2.0/en/models/data-validation.html#Validation::date
//However, this should work fine.
public $validate = array (
'birth_dt' => array (
'rule' => array('date'),
'required' => true,
'allowEmpty' => false,
'message' => 'Please Give valid date'
)
);
}
I think best way for validation is to integrate server side and client side validation.
form fields should be validated on focus out/blur with ajax call to server side validation rules via your controllers. This will ensure consistency in server side and client side validation.
bla..bla :)
I think validate error message not show
because you use $this->redirect('/users');
when redirect cakephp will be render view that clear message error :)
You can comment line //$this->redirect('/users'); and then try again :)

CakePHP: allowing login with user name or email

I'm implementing a logic where you can use either your username or email address to log in in CakePHP. I'm following an example in a book called CakePHP 1.3: Application Development Cookbook (Chapter 1: Allowing logins with username or email). The book explains that when the Auth component cannot log the user in with the provided info, it goes back to the login() action and can look for additional info that might log the user in with the logic within the login() action.
The code/logic is working. However, when I login with my email address, it still displays the loginError message, which says "Invalid account specified." Below that it says "Welcome," which is a message I display when a login is successfull.
These are what I'd like to know:
The book doesn't indicate whether or not this is normal, but I'd like to learn how to omit this error message, since it doesn't make sense. Where is THIS LINE (in comment) taking the user? The error message displays after that line.
.. and possibly display with "you logged logged in with email." This is of secondary importance.
Below are what I think relevant code. Please let me know if you need more.
class AppController extends Controller {
public $components = array(
'Auth' => array(
'authorize' => 'controller',
'loginRedirect' => array(
'admin' => false,
'controller' => 'users',
'action' => 'dashboard'
),
'loginError' => 'Invalid account specified',
'authError' => 'You don\'t have the right permission'
),
'Session'
);
}
class UsersController extends AppController {
public function login() {
if (
!empty($this->data) &&
!empty($this->Auth->data['User']['username']) &&
!empty($this->Auth->data['User']['password'])
) {
$user = $this->User->find('first', array(
'conditions' => array(
'User.email' => $this->Auth->data['User']['username'],
'User.password' => $this->Auth->data['User']['password']
),
'recursive' => -1
));
if (!empty($user) && $this->Auth->login($user)) { // $this->Auth->login() true if logs in
if ($this->Auth->autoRedirect) { // I think autoRedirect is TRUE by default
$this->redirect($this->Auth->redirect()); // <<THIS LINE>>
}
} else {
$this->Session->setFlash($this->Auth->loginError, $this->Auth->flashElement, array(), 'auth');
}
}
}
if (!empty($user) && $this->Auth->login($user)) {
$this->Session->delete('Message.auth');
}
You don't need to setFlash for authError if you flash('auth') in login view (as in the cookbook) and you don't need to call redirect.
Its the same code explained in http://www.packtpub.com/cakephp-1-3-application-development-cookbook/book CakePHP 1.3 Application Development Cookbook
,
I think it would be more effective like this
if(!empty($user) && $this->Auth->login($user)){
if($this->Auth->autoRedirect){
$this->Session->delete('Message.auth'); // kills login failed message after successful login
$this->redirect($this->Auth->redirect());
} else {
$this->Session->setFlash($this->Auth->loginError, $this->Auth->flashElement, array(), 'auth');
}
}
this way login failed error message after successful login will be omitted and redirection will remain intact.

ZF: Login Form Validation

WHat's the best way/code in Login Form (Zend_Form) to display error message 'Login/password incorrect'?
I slowly begin to understand, that setting $this->setErrorMessage('Login/password incorrect') in form/init() is not enough and I somehow have to involve Validators to be able to see the message I set.
To which object should I bind this message and do I have to use validator or not?
Thanks!
Update:
LoginAction() code:
$auth = Zend_Auth::getInstance();
$authAdapter =
$this->_getAuthAdapter($formData['userName'],$formData['password']);
$result = $auth->authenticate($authAdapter);
if (!$result->isValid()) {
//Problem: the line below doesn't display error message
$form->addError('Username or password do not exist');
$form->populate($formData);
$this->view->form = $form;
I think you're looking for the Zend_Form_Decorator_FormErrors decorator. As this decorator is not registered by default on the Zend_Form you have to register the decorator manually.
You have to do something like this in your form's init() method:
$this->setDisableLoadDefaultDecorators(true);
$this->setDecorators(array(
'FormElements',
array('HtmlTag', array('tag' => 'dl', 'class' => 'zend_form')),
'FormErrors',
'Form'
));
I usually have just two checks to cover my authentication forms.
Check username and password, and if either is not set, display a message like "Please enter both username and password"
Validate credentials using Zend_Auth and display an error if they are invalid: "Invalid username or password".
I normally just pass the message to the view in a variable, but you might find a FlashMessenger useful.

Categories