kohana validation during update - php

In my application developed using Kohana, I have a form where user enters their registration information, My rules are correctly executing and the error message is displaying correctly if user ignores an important field or enters an email address in inappropriate form.
The problem is that i want to do the same validations while an his personal information at a later point of time, but i want to ignore the password fields which is usually empty when the form loads.
Is it really possible to make kohana ignore the blank password values
while updating?
I am using the following code to update user data, I could see no
validation is performed(which is defined in my Model_User) when i use
update_user() of Auth. Can somebody please throw some light on
potential issues that hinders the execution of validation routines
here?
if(Auth::instance()->logged_in()) {
$values = array();
$now = new DateTime();
$userobj = Auth::instance()->get_user();
//$userobj->updatedon = $now->format('Y-m-d H:i:s'); // need research
try {
$userobj->update_user($_POST, array('email',
'password',
'firstname',
'secondname',
'lastname',
'phone',
'city_id'
));
$values = Auth::instance()->get_user()->as_array();
} catch (ORM_Validation_Exception $e) {
$errors = $e->errors('models');
}
//...

This shouldn't be a problem. When registering users, make sure to use create_user() and add password specific rules to get_password_validation().
Now the logic will only apply for registration and not for updating already existing users.
Also if you don't want to update the password, make sure to remove it from the list.
$updateColumns = array('email', 'password', ...);
if ( ! isSet($_POST['password']) || trim($_POST['password']) == "") {
unset($updateColumns[1]);
}
$userobj->update_user($_POST, $updateColumns);

Related

Unable to change value with codeIgniter validation

Here i have a list of contacts where user can add new contacts as well as edit them. Now at the add time i'm using server-side validation by codeIgniter for reduce redundancies. Also here i have a number of users that can add their contacts.
Suppose their are users named "John" and "Sara".
In this case, whenever "john" add new contact that are prevoiusly added by him, then it can't be add as duplicate contact number.
But whenever "john" add new contact that are previously added by "Sara", them it can be add . but its unable to add because CodeIgniter form_validation check unique value with entire table data.
Here is my Controller Code
$this->form_validation->set_rules('customer_email','Email', 'trim|check_email[customer.customer_email.' .$userId. ']', array('check_email' => 'Email must be unique.'));
$this->session->set_flashdata('check_email','Mobile must be unique');
$this->form_validation->set_rules('customer_mobile', 'Mobile', 'required|is_unique[customer.customer_mobile]');
$this->session->set_flashdata('contact_exists','Mobile must be unique');
if ($this->form_validation->run()) {
$userdata = $this->session->userdata();
$userId = $userdata['id'];
if (!$userId):
redirect(site_url());
endif;
I trying to many time but unable to fix this issue. I need your kind efforts. Thanks
Please find below solution.
First you need to remove unique check from customer_mobile.
$this->form_validation->set_rules('customer_mobile', 'Mobile', 'trim|required');
Once form_validation runs true then check customer_mobile with user in database and if it return row then return error else insert Contact.
if ($this->form_validation->run() == TRUE) {
// $check = Check here for customer_mobile with user in database
if($check):
return 'Contact already exist';
else:
// Insert Contact
endif;
}
Let me know if it not works.

Laravel same validator

My case is for change password option. I already have current password in object $pass. I want to validate this $pass against textbox form input current_password to proceed to create a new password for the user. How to validate with same validator. Sorry I'm new to laravel.
$rules = array('password_current' => "required|same:$pass");
doesn't work.
since same: used to ensure that the value of current field is the same as another field defined by the rule parameter (not object). so you can't use this function take a look this example code below.
$data = Input::all();
$rules = array(
'email' => 'required|same:old_email',
);
the above code will check if current email field is same as old_email field.
so i think you can you simple if else
in your handle controller function assume
public function handleCheck(){
$current_password = Input::get('current_password');
$pass = //your object pass;
if($current_password == $pass){
// password correct , show change password form
}else{
// password incorrect , show error
}
}
let me know if it works. see Laravel Validation same
If you have password stored in $pass already just inject $pass in the request and use its field instead for e.g.
$request->request->add(['password_old' => $pass]);
Then, you can validate it like
$rules = array('password_current' => "required|same:password_old");

Upload record md5 cakephp

I have a sit developed in cakephp, and I have a page to edit user.
My user table has many field and one of this is password in md5.
The user can modify all its fields and password but if he leave blank this field I have t take from the database the old password and save it.
But return me error on save on the password field.
This is my action into the controller:
if ($this->request->is ('post')){
$this->User->id = $this->request->data['User']['id'];
if($this->request->data['User']['password'] == ''){
$user = $this->User->find('first',array('conditions'=>array('User.id' => $this->request->data['User']['id'])));
$this->request->data['User']['password'] = md5($user['User']['password']);
$this->request->data['User']['password_confirm'] = md5($user['User']['password']);
}
if ($this->User->save($this->request->data)) {
$this->redirect (array ('action'=>'index'));
}
else{
debug($this->User->validationErrors);
$this->Session->write('flash_element','error');
$this->Session->setFlash ('Errore di salvataggio dello user.');
}
}
And this is the method beforeSave into the UserModel:
public function beforeSave(){
if (isset($this->data['User']['password'])){
$this->data['User']['password'] = AuthComponent::password($this->data['User']['password']);
}
}
The problem is when I try to save return me error on the field password lie is inappropriate type.
If I print the field password before save I see something like: ***** but if I print the variable md5($user['User']['password']) return me the right value of password crypted.
Thanks
IMO, don't have the "password" field where the user edits his profile information.
You can have 2 forms on the page, where the second one is a change password form. This way, if the user changes their "first name" (which is in the first form) for example, your code does not have to check or do anything with their password.
After seeing many different frameworks, and creating systems myself, I can't say I recall anything where I have seen in the "wild" something handled like your doing. You are doing an extra step by getting their old password and "putting it back" just so you don't lose their password in the database when they want to change their profile details.
If its for security, you can make them "confirm" their password so it must match before changing the profile details.
Having the "password" box on the "edit profile" form is just bad code logic.
First comment, there is nothing wrong using md5 but I would use sha1.
Second, you can use only one form, not 2.
Then, in your controller you just need to check if user entered a new password, which you are already doing, if the field is empty then you unset that field, so cake won't update that field.
if ($this->request->is ('post')){
$this->User->id = $this->request->data['User']['id'];
if ($this->request->data['User']['password'] == '') {
unset($this->request->data['User']['password'], $this->request->data['User']['password_confirm']);
}
if ($this->User->save($this->request->data)) {
$this->redirect (array ('action'=>'index'));
}
else{
debug($this->User->validationErrors);
$this->Session->write('flash_element','error');
$this->Session->setFlash ('Errore di salvataggio dello user.');
}
}
By the way, I would change this
$this->User->id = $this->request->data['User']['id'];
For something like
$this->request->data['User']['id'] = $this->Session->read('Auth.id');
in order to prevent data tampering, but due I don't know if you are keeping the user id in a session I didn't write it in the example code

Symfony 1.4 conditional validation

I have a Profile form that inherits from sfGuardRegisterForm
I have these fields:
$this->useFields(
array('first_name',
'last_name',
'email_address',
'country',
'language',
'current_password',
'new_password',
'password_again',
)
);
Required fields are:
email_address, country and language
And the conditions are:
If the email_address is not equal with the current email_address
then check if it's unique then save it
If the current_password is the actual password of the user then verify if new_password and password_again are equals and verify that the new_password is not equal to the actual password of the user
I just can't figure out in how implement this
EDIT
Thanks 1ed your example works but the problem is that I load the user Profile and I fill the fields: 'first_name', 'last_name', 'email_address', 'country', 'language' with the actual logged user so the email_address field will show the email address:
//...
$this->widgetSchema['email_address']->setDefault($this->_user->getEmailAddress());
//...
If the user dont change the email it will always show this message:
An object with the same "email_address" already exist.
I just want to skip that
Also this $this->getObject()->checkPassword() does not works, always show this message:
Incorrect current password.
I use:
$this->_user = sfContext::getInstance()->getUser()->getGuardUser();
To get actual user profile
EDIT2
Thanks again 1ed
This is very weird and I'm getting frustated, this is the situation
I have a "workaround" for this but it does not follow the standard, I can make it works but using sfContext::getInstance()->getUser()->getGuardUser(); and it will be more unnecesary code
If I use new ProfileForm($user) automatically fills all the fields, that's very good but I can't setDefault() I can't set null or empty any field so I can't use doUpdateObject() because this function only works when the current data is updated, also I have tested overriding bind(), save() etc. without results
email_address uniqueness: you should set unique: true in schema, in sfDoctrineGuardPlugin that's the case by default, so in BasesfGuardUserForm you should see a unique validator already: sfValidatorDoctrineUnique(array('model' => 'sfGuardUser', 'column' => array('email_address'))
current_password: you should create a callback type post validator for this
// in sfGuardRegisterForm::configure()
// these fields can be blank
$this->getValidator('current_password')->setOption('required', false);
$this->getValidator('new_password')->setOption('required', false);
$this->getValidator('password_again')->setOption('required', false);
// check the current password (this validator is not `required` by default)
$this->mergePostValidator(new sfValidatorCallback(array(
'callback' => array($this, 'checkPassword'),
), array(
'invalid' => 'Incorrect current password.'
)));
// add this method to the same form class
public function checkPassword(sfValidatorBase $validator, array $values, array $arguments)
{
// if a new password is given check whether the old one is correct or not and rise an error if not correct
if(0 != strlen($values['new_password']) && !$this->getObject()->checkPassword($values['current_password']))
{
throw new sfValidatorErrorSchema($validator, array(
'current_password' => new sfValidatorError($validator, 'invalid')
));
}
return $values;
}
Alternatively you can create a custom post validator, but I think it's not necessary.
EDIT:
If you would like to display empty email address just like the password fields add these to your form class:
// at form load remove the default value
protected function updateDefaultsFromObject()
{
parent::updateDefaultsFromObject();
if (isset($this['email_address']))
{
$this->setDefault('email_address', '');
}
}
// before save remove empty email address
protected function doUpdateObject($values)
{
if (isset($values['email_address']) && 0 == strlen($values['email_address']))
{
unset($values['email_address']);
}
parent::doUpdateObject($values);
}
I'll try and explain this in methodical terms instead of giving you a big block of code....
So first, you want to if (email_addr != current_email) and if that's true, go on to do
if (new_pass != current_pass) then follow on to make sure if (new_pass == new_pass_again)
Inside all of these IFs, you can return a true/false or some kind of flag, or just //do code inside the brackets :p
EDIT: encase these IFs in: if (country != NULL && language != NULL && email_addr != NULL)

Validation Layer in a PHP Class

I need help understanding the logic to deal with validating user inputs.
my current state of validating user data is at worst, i feel pretty awkward using these messy lines of codes, have a look at my typical function which i uses it to get input from the user and process it to database.
public function saveUser($arguments = array()) {
//Check if $arguments have all the required values
if($this->isRequired(array('name','email','password','pPhone','gender','roleId'))) {
//$name should could minimum of 5 and maximum of 25 chars, and is a strict character.
$name = $this->isString(5, 25, $this->data['name'], 'STRICT_CHAR');
$email = $this->isEmail($this->data['email']);
$pPhone = $this->isString(5, 12, $this->data['pPhone'], 'STRICT_NUMBER');
$sPhone = (!empty($this->data['sPhone'])) ? $this->isString(5, 12, $this->data['sPhone'], 'STRICT_NUMBER') : 0;
//Check For Duplicate Email Value
$this->duplicate('user_details','email',$email);
//If Static Variable $error is not empty return false
if(!empty(Validation::$error)) { return false; }
//After Validation Insert the value into the database.
$sth = $this->dbh->prepare('INSERT QUERY');
$sth->execute();
}
}
Now is the time i focus on improving my validation code. i would like all my class methods to validate the user inputs before inserting into the database. basically a class methods which takes user input should be able to perform the following.
If class method accepts user input as an array then check for all required inputs from within the array.
Check the Minimum and Maximum Length of the input.
Check for any illegal character.
etc.
I would like to know how to deal with this, and also if there is any PHP Independent Validation Component which can come to my rescue. it would be of great help. if i am doing it wrong please suggest me on improving my code, i won't mind going to any extent as long as it guarantees that my code follows the coding standard.
I will also appreciate if someone could explain me on dealing with validation logic for validating user input for a class method of an object.
Thank you..
PHP 5.2 has a new core extension called "filter functions". You can use this extension to sanitize and validate user data.
For example, to validate an email address:
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo "This (email) email address is considered valid.";
}
As for dealing with validation in general, you want to decouple the validation process from the incoming data and the objects themselves. I use the Lithium PHP framework, and their data validation class is implemented as a nearly independant utility class. Check it out for ideas on how to roll your own: http://li3.me/docs/lithium/util/Validator
Using their class, you get something like this:
// Input data. This can be an $object->data() or $_POST or whatever
$data = array(
'email' => 'someinvalidemailaddress';
);
// Validation rules
$rules = array(
'email' => array(
array('notEmpty', 'message' => 'email is empty'),
array('email', 'message' => 'email is not valid')
)
);
// Perform validation
Validator::check($data, $rules);
// If this were in your object
public validate($data = array(), $rules = array()) {
$data = !empty($data) ? $data : $this->data; // Use whatever data is available
$rules = $this->rules + $rules; // Merge $this's own rules with any passed rules
return Validator::check($data, $rules));
}
// You can have a save method like
public save() {
if ($this->validates()) {
// insert or update
}
}
// And your object would
$user = new User();
$user->data = array('email' => 'whatever');
$user->save();
And there's always Zend Validate. You can look it up at http://framework.zend.com/manual/en/zend.validate.set.html
Create your validation class first...Then when they submit the code. Just include the class on where every you have action set to on the form. You can create a loop to pass the POST or GET data though the instance which validates the input. Then if the input is good, return it(maybe as an array, that's what I do) and pass it to your database.
Example:
$validate = new validation_Class; //new instance of the validation class
$output = foreach($_POST as $input) // loop each input data into the class
{
$validate->$input;
}
Now if your validation class is setup right, you can have all the clean data stored in $output

Categories