Password cannot be Username in CodeIgniter form validation - php

On registration, I want my 'password' field to have the following custom rule:
not_matches[username]
I would then set the following language:
$lang['not_matches'] = "The %s field cannot be the same as the %f field";
(Assuming %f is the field name)
Is this possible?
To be clear, I know how to do not_matches[".$val."] but I would like a flexible rule instead.

Im not sure that i understand what u are saying. You want a rule that says not_matches['username'] being the username another input field?
If so, just go to system\libraries\form_validation.php , then find the matches rule and duplicate it changing the == to !== and the name to not_matches. Then go to system\language\english\form_validation_lang.php and create the message.

There is no such support yet in CI. You need to write your own callback validation routine.
There is an example that can be easily adapted to your needs in the CI manual.

Here's how I did it.
application/language/english/form_validation_lang.php
$this_lang = basename(__DIR__);
require_once("./system/language/$this_lang/form_validation_lang.php");
$lang['not_match'] = "The %s field must not match the %s field.";
application/libraries/MY_Form_validation.php
class MY_Form_validation extends CI_Form_validation {
function __construct()
{
parent::__construct();
}
public function not_match($str, $field)
{
if ( ! isset($_POST[$field]))
{
return FALSE;
}
$field = $_POST[$field];
return ($str === $field) ? FALSE : TRUE;
}
}
Then the rule is simply not_match[field_name]

Related

form validation with preg_match in callback not working

I have questions about my codeigniter form validation. I try to validate the input form for name so it will generate error if user using symbol like ">?<*&%^$". Here is my code:
My rules:
$this->load->library('form_validation');
$this->form_validation->set_rules('full_name', 'Name', 'trim|required|callback_name_check',
array(
'name_check' => '%s should not using symbols'
)
);
This is my callback function (I tried to modify this from the last example I saw, so I thought the problem was here)
public function password_check($str)
{
if (preg_match('#[<>?&%$##]#', $str)) {
return TRUE;
}
return FALSE;
}
I have tried another example from another StackOverflow answer to use / as delimiter (like this --> [/<>?&%$##/]), but still, doesn't work. I'll appreciate your help sensei :)
Validation should be
$this->load->library('form_validation');
$this->form_validation->set_rules('full_name', 'Name', 'trim|required|callback_name_check');
Inside call back function
public function name_check($str)
{
if (preg_match('#[<>?&%$##]#', $str)) {
{
return TRUE;
}
else
{
#adding new validation error should be
$this->form_validation->set_message('full_name', '%s should not using symbols'); # input field name should come to first
return FALSE;
}
}
Note: Didn't validate REGEX which you have posted

Using a validation rule in Yii with no parameters

I'm just wondering if there is way to run a validation function from your rules method where you don't need to pass in any parameters to it?
So normally you would pass in the attribute name for the property, but say you know what properties you want to use such as $this->foo and $this->bar.
So a normal custom inline validator would be done like this:
['country', 'validateCountry']
public function validateCountry($attribute, $params)
{
if (!in_array($this->$attribute, ['USA', 'Web'])) {
$this->addError($attribute, 'The country must be either "USA" or "Web".');
}
}
Like I'm currently doing this:
['username', 'regAvailable', 'params' => ['email' => 'email']],
public function regAvailable($attribute, $params) {
$username = $this->{$attribute};
$email = $this->{$params['email']};
}
Sure, it does the job. But seems a bit overkill when I can just do:
public function regAvailable($attribute, $params) {
$username = $this->username;
$email = $this->email;
}
Sure, I can still do it this way, but then I kinda feel like the code wouldn't be very "clean" by having those unused parameters there; I would prefer to have it like this:
public function regAvailable() {
$username = $this->username;
$email = $this->email;
}
Is there anyway do do something like that? If so, how?
Of course you can do that. You can avoid passing any argument to custom validation method. For example:
public function regAvailable() {
if(!$this->hasErrors()){
if(strlen($this->email) < 10 && $this->email!='info#site.com' && $this->username!='admin'){
$this->addError('email','Invalid email!');
$this->addError('username','username must not be admin');
}
}
}
But, please note that, using those argument would be useful if you need to perform some validation for multiple fields. Assume that we have 9 fields that we need to validate theme like above function. So, it is better to use $attribute argument as it refers to the field which is under validation progress.

codeigniter form callback value

Im carrying out some form validation with codeigniter using a custom validation callback.
$this->form_validation->set_rules('testPost', 'test', 'callback_myTest');
The callback runs in a model and works as expected if the return value is TRUE or FALSE. However the docs also say you can return a string of your choice.
For example if I have a date which is validated, but then in the same function the format of the date is changed how would I return and retrieve this new formatted value back in my controller?
Thanks for reading and appreiate the help.
I'm not entirely sure I got what you were asking, but here's an attempt.
You could define a function within the constructor that serves as the callback, and from within that function use your model. Something like this:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Controllername extends CI_Controller {
private $processedValue;
public function index()
{
$this->form_validation->set_rules('testpost','test','callback');
if ($this->form_validation->run()) {
//validation successful
echo $this->processedValue; //outputs the value returned by the model
} else {
//validation failed
}
}
private function callback($input)
{
$this->load->model('yourmodel');
$return = $this->yourmodel->doStuff($input);
//now you have the user's input in $input
// and the returned value in $return
//do some checks and return true/false
$this->processedValue = $return;
}
}
public function myTest($data){ // as the callback made by "callback_myTest"
// Do your stuff here
if(condition failed)
{
$this->form_validation->set_message('myTest', "Your string message");
return false;
}
else
{
return true;
}
}
Please try this one.
I looked at function _execute in file Form_validation of codeigniter. It sets var $_field_data to the result of callback gets(If the result is not boolean). There is another function "set_value". Use it with the parameter which is name of your field e.g. set_value('testPost') and see if you can get the result.
The way Tank_Auth does this in a controller is like so
$this->form_validation->set_rules('login', 'Login', 'trim|required|xss_clean');
if ($this->form_validation->run()) {
// validation ok
$this->form_validation->set_value('login')
}
Using the set_value method of form_validation is undocumented however I believe this is how they get the processed value of login after it has been trimmed and cleaned.
I don't really like the idea of having to setup a new variable to store this value directly from the custom validation function.
edit: sorry, misunderstood the question. Use a custom callback, perhaps. Or use the php $_POST collection (skipping codeigniter)...apologies haven't tested, but I hope someone can build on this...
eg:
function _is_startdate_first($str)
{
$str= do something to $str;
or
$_POST['myinput'} = do something to $str;
}
================
This is how I rename my custom callbacks:
$this->form_validation->set_message('_is_startdate_first', 'The start date must be first');
.....
Separately, here's the callback function:
function _is_startdate_first($str)
{
$startdate = new DateTime($this->input->post('startdate'), new DateTimeZone($this->tank_auth->timezone()));
$enddate = new DateTime($this->input->post('enddate'), new DateTimeZone($this->tank_auth->timezone()));
if ($startdate>$enddate) {
return false;
} else {
return true;
}
}

How to set custom error message with form_validation And CodeIgniter

i am newbie in CodeIgniter...and i am trying to do form validation for array input...
the array name is pages[].
and i wrote:
$this->form_validation->set_rules('pages[]','','required');
if i use that:
$this->form_validation->set_message('required', 'you not selected pages.');
it will not change the other "required" validation input params?
So how can i set error message only for one validation?
This is my custom Form_Validation class. you can use it if you want to. put this file under your libraries directory. then you can use the set message like this:
$this->form_validation->setError(YOUR_INPUT_NAME, THE_MESSAGE);
ex: $this->form_validation->setError('email', 'Invalid email');
--
class MY_Form_validation extends CI_Form_validation {
public function set_error($field, $pesan_error){
$this->_field_data[$field]['error'] = $pesan_error;
}
public function get_error($field){
return $this->_field_data[$field]["error"];
}
public function get_all_error(){
// return $this->_field_data[$field]["error"];
$fields = $this->_field_data;
$pesan = "";
foreach($fields as $field ) {
if($field["error"]) {
$pesan .= "<p>$field[error]</p>";
}
}
return $pesan;
}
}
It doesn't work like you stated, you should read this section of the user guide more carefully.
I'm not sure I can explain better, but the first field of the set_message method doesn't refer to the type of validation but to the callback function's name, that's the function which is doing the custom validation work.
What you need to do is define your callback function (the guide has a good example), in which you iterate through your array's elements and count what's checked. If at the end of the iteration the counter is 0 you set your error message.
Hope this helps.

Zend_Form: Element should only be required if a checkbox is checked

I've got a Form where the user can check a checkbox "create new address" and can then fill out the fields for this new address in the same form.
Now I want to validate the fields of this new address ONLY if the checkbox has been checked. Otherwise, they should be ignored.
How can I do that using Zend_Form with Zend_Validate?
Thanks!
I think that the best, and more correct way to do this is creating a custom validator.
You can do this validator in two different ways, one is using the second parameter passed to the method isValid, $context, that is the current form being validated, or, inject the Checkbox element, that need to be checked for validation to occur, in the constructor. I prefer the last:
<?php
class RequiredIfCheckboxIsChecked extends Zend_Validate_Abstract {
const REQUIRED = 'required';
protected $element;
protected $_messageTemplates = array(
self::REQUIRED => 'Element required'
);
public function __construct( Zend_Form_Element_Checkbox $element )
{
$this->element = $element;
}
public function isValid( $value )
{
$this->_setValue( $value );
if( $this->element->isChecked() && $value === '' ) {
$this->_error( self::REQUIRED );
return false;
}
return true;
}
}
Usage:
class MyForm extends Zend_Form {
public function init()
{
//...
$checkElement = new Zend_Form_Element_Checkbox( 'checkbox' );
$checkElement->setRequired();
$dependentElement = new Zend_Form_Element_Text( 'text' );
$dependentElement->setAllowEmpty( false )
->addValidator( new RequiredIfCheckboxIsChecked( $checkElement ) );
//...
}
}
I have not tested the code, but I think it should work.
I didn't actually run this, but it should work within reason. I've done something similar before that worked, but couldn't remember where the code was.
<?php
class My_Form extends Zend_Form
{
public function init()
{
$checkbox = new Zend_Form_Element_Checkbox("checkbox");
$checkbox->setValue("checked");
$textField = new Zend_Form_Element_Text("text");
$this->addElements(array("checkbox", "text"));
$checkbox = $this->getElement("checkbox");
if ($checkbox->isChecked() )
{
//get textfield
$textField = $this->getElement("text");
//make fields required and add validations to it.
$textField->setRequired(true);
}
}
}
Here's what I do if I need to validate multiple elements against each other
$f = new Zend_Form();
if($_POST && $f->isValid($_POST)) {
if($f->checkbox->isChecked() && strlen($f->getValue('element')) === 0) {
$f->element->addError('Checkbox checked, but element empty');
$f->markAsError();
}
if(!$f->isErrors()) {
// process
...
...
}
}
I've been wondering how to do that in ZF as well, though never had to implement such form feature.
One idea that comes to mind is to create a custom validator that accepts the checkbox field as a parameter, and run it in a validator chain, as documented. If the checkbox is checked, validator could return failure. Then you can check whether all validations failed and only then treat form as having failed validation.
That level of customization of form validation could be inconvenient, so maybe using form's isValidPartial method would be better.
I created a custom validator that will make your element required based on the value of another zend form element.
Here's the full code. I hope this helps someone.
The idea is to create a custom validator and pass in the name of the conditional element and the value of that conditional element into the constructor. Zend_Validor's isValid method already has access to the value of the element you are attaching the validtor to along with all the form element names and values.
So, inside the isValid method you have all the information you need to determine if your form element should be a required element.
On Zend 1 extend the isValid method, where you set required depending on posted data for example:
public function isValid($data)
{
if (!empty($data['companyCar'])) {
$this->getElement('carValue')->setRequired(true);
}
return parent::isValid($data);
}
Thank you JCM for your good solution.
However 2 things I've noticed:
The isValid method of your validator has to return true in case of success.
The validator will not be executed during form validation without pass the allowEmpty option to false to the text field.

Categories