Codeigniter form validation callback rule issue - forms

I am using Codeigniter 3.x form validation callback method in combination trim and required to validate a field.
The problem is, when I pipe them: trim|required|callback_some_method, the callback method seems to take precedence over trim and required and shows its error message.
Any ideas on this?
EDIT:
This is the rule:
$this->form_validation->set_rules('new_password', 'New Password', 'trim|required|min_length[8]|callback_password_check');
And this is the password_check method:
function password_check($pwd) {
$containsLetterUC = preg_match('/[A-Z]/', $pwd);
$containsLetterLC = preg_match('/[a-z]/', $pwd);
$containsDigit = preg_match('/\d/', $pwd);
$containsSpecial = preg_match('/[^a-zA-Z\d]/', $pwd);
if ( !($containsLetterUC && $containsLetterLC && $containsDigit && $containsSpecial) ) {
$this->form_validation->set_message('password_check', '{field} must contain UPPERCASE and lowercase letters, digits, and special characters.');
return FALSE;
}
return TRUE;
}
The method should return FALSE, but as long as required is before my custom rule and the field is empty, it should stop there with Required field message, NOT the custom method message.

Okay guys, I've managed to solve it by extending the Form_validation library, putting my callback method there and piping as the other rules (without callback_ prefix).

Unfortunately, as described in the code from CI, callbacks validation rules are always verified first, prior to ‘required’ for instance.
There is an official issue opened at CI : https://github.com/bcit-ci/CodeIgniter/issues/5077

Related

Angular 2 - Removing a Validator error

I wrote a function to update Validator rules on an input if a certain option was selected, using this method (the forms are built using FormGroup):
onValueChanged(data : any) {
let appVIP1 = this.vip1TabForm.get('option1');
let appVIP2 = this.vip2TabForm.get('option2');
let appVIP3 = this.vip3TabForm.get('option3');
//Set required validation if data is 'option3'
if(data != 'option3') {
//Due to initialization errors in UI, need to start with the case
//That there are validations, check to remove them
appVIP1.setValidators([]);
appVIP2.setValidators([]);
appVIP3.setValidators([]);
}
else {
appVIP1.setValidators([Validators.required]);
appVIP2.setValidators([Validators.required]);
appVIP3.setValidators([Validators.required]);
}
}
And I bind that function call to a click event on radio buttons (I initially used the guide from this answer, but the onChange function didn't bind correctly).
This works great, and if the user selects option 1 or 2, the validations are empty, and won't be triggered. If they select option 3, the validations are shown and submission is stopped. However, I run into the problem where the user submits, sees the error, and goes back to change to option 1 or 2. While the validator is cleared, my form still reads as invalid. I have multiple input fields I am validating, so I can't just set the form to valid if the validator is removed this way. How would I go about doing this? Can I remove the has-error for one particular field in the formgroup?
If the correct validators are in place, you can manually call AbstractControl#updateValueAndValidity after they select an option:
this.formBuilder.updateValueAndValidity();
(Where, of course, this.formBuilder is your FormBuilder instance.)
You can also call it on FormElements directly.
This is commonly used to trigger validation after a form element's value has been programmatically changed.
Instead of removing and adding validations. It is more simple to enable and disable fields. You need to add the Validators.required for all required fields. And disable the fields which are not required.
onValueChanged(data : any) {
let appVIP1 = this.vip1TabForm.get('option1');
let appVIP2 = this.vip2TabForm.get('option2');
let appVIP3 = this.vip3TabForm.get('option3');
if(data != 'option3') {
appVIP1.disable();
appVIP2.disable();
appVIP3.disable();
}
else {
appVIP1.enable();
appVIP2.enable();
appVIP3.enable();
}
}

Get Line Items in an Invoice logic hook in SuiteCRM

Via a logic hook I'm trying to update fields of my products, after an invoice has been saved.
What I understand so far is, that I need to get the invoice related AOS_Products_Quotes and from there I could get the products, update the required fields and save the products. Does that sound about right?
The logic hook is being triggered but relationships won't load.
function decrement_stocks ( $bean, $event, $arguments) {
//$bean->product_value_c = $bean->$product_unit_price * $bean->product_qty;
$file = 'custom/modules/AOS_Invoices/decrement.txt';
// Get the Invoice ID:
$sInvoiceID = $bean->id;
$oInvoice = new AOS_Invoices();
$oInvoice->retrieve($sInvoiceID);
$oInvoice->load_relationship('aos_invoices_aos_product_quotes');
$aProductQuotes = $oInvoice->aos_invoices_aos_product_quotes->getBeans();
/*
$aLineItemslist = array();
foreach ($oInvoice->aos_invoices_aos_product_quotes->getBeans() as $lineitem) {
$aLineItemslist[$lineitem->id] = $lineitem;
}
*/
$sBean = var_export($bean, true);
$sInvoice = var_export($oInvoice, true);
$sProductQuotes = var_export($aProductQuotes, true);
$current = $sProductQuotes . "\n\n\n------\n\n\n" . $sInvoice . "\n\n\n------\n\n\n" . $sBean;
file_put_contents($file, $current);
}
The invoice is being retrieved just fine. But either load_relationship isn't doing anything ($sInvoice isn't changing with or without it) and $aProductQuotes is Null.
I'm working on SuiteCRM 7.8.3 and tried it on 7.9.1 as well without success. What am I doing wrong?
I'm not familiar with SuiteCRM specifics, however I'd always suggest to check:
Return value of retrieve(): bean or null?
If null, then no bean with the given ID was found.
In such case $oInvoice would stay empty (Your comment suggests that's not the case here though)
Return value of load_relationship(): true (success) or false (failure, check logs)
And I do wonder, why don't you use $bean?
Instead you seem to receive another copy/reference of $bean (and calling it $oInvoice)? Why?
Or did you mean to receive a different type bean that is somehow connected to $bean?
Then its surely doesn't have the same id as $bean, unless you specifically coded it that way.

Zend_Validate_Date returns true on 2011-02-31

What should i do ?
$edit_end_date = '2011-02-31';
$validator_date = new Zend_Validate_Date(array('format' => 'yyyy-mm-dd'));
$isval = $validator_date->isValid($edit_end_date);
if((!$isval) || empty($edit_end_date))
{
echo "Please Enter Valid End Date. !";
}else{
echo "Entered Is Valid End Date. !";
}
how come it returns true date ?
According to the Zend API Docs, it appears that Zend_Validate_Date will only validate whether the argument passed to it, is a valid date construct (also considers locale), it will not validate if the date actually exists.
Zend_Validate_Date allows you to validate if a given value contains a date. This validator validates also localized input.
-- Edit --
Looks like you can use PHP's built in checkdate() function to determine if a date is valid or not.
There are bugs in data validation (ZF-7583 at issue tracker). Look at Zend_Validate_Date just doesn't work properly
You can use regex validation like in answer to linked question, but it will only check for syntax, not if date exists for real. For this you can use checkdate() - as Mike Purcell suggested - combined with Zend_Validate_Callback:
$validator1 = new Zend_Validate_Regex(
array('pattern' => '/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/')
);
$validator1->setMessage(
"Date does not match the format 'yyyy-mm-dd'",
Zend_Validate_Regex::NOT_MATCH
);
$validator2 = new Zend_Validate_Callback(function($value)) {
// using checkdate() or other function
});

Conditional File Count Validator for a Zend_Form_File_Element

In my project we have a Form where the user either needs to upload a file or specify some other information, for example in a text input.
I know that there is the possibility to attach a Count validator to the Form Element, and this works like this:
$upload->addValidator('Count', false, array('min' => 1, 'max' => 3));
This validator gets called, no matter if there are files uploaded or not. But as soon as i replace the validator with a custom version, and do not upload any files, the validator does not get called.
Looking at the isValid() method of Zend_File_Transfer_Adapter_Abstract, I can see the problem:
[...]
foreach($check as $key => $content) {
if (array_key_exists('validators', $content) &&
in_array('Zend_Validate_File_Count', $content['validators'])) {
$validator = $this->_validators['Zend_Validate_File_Count'];
$count = $content;
[...]
Seems like the Count Validator got some special treatment here. But how can I include my customized Validator, without overwriting Zend Files?
Because we do not extend the Zend_Form class, sadly I also cannot overwrite the isValid() method of the involved Form. Any Ideas left? Thanks for your time!
This would probably be easiest with a bit of ajax. That way you could evaluate the selection prior to posting the form.
To do it in PHP, an Element validator is probably not the way to go. It would be better to handle the selection with an if() statment.
pseudocode...
//if file element contains something and text doesn't
if($this->getRequest->getPost('file'=='' && 'text' != ''){
$file = $form->file->receive();
//do some stuff
//if text element contains something and file dosen't
}elseif ($this->getRequst->getPost('file' != '' && 'text' == '') {
if($form->isValid($this->_request->getPost('text')) {
//do some stuff
}
}
This is the idea, hope it helps.

AMFPHP overiding default function arguments?

I've got this odd problem.
If I make a call on that function through amfphp service browser and give it a valid ID and leave the $num_images field blank amfphp will actually pass a blank string as the argument.
// if i call this function width just an ID
function getWorkers($id, $num_images = 100) {
...
// num_images will be set as ''
}
I can easily override using a check:
function getWorkers($id, $num_images = 100) {
if($num_images=='') $num_images = 100;
...
// num_images will now be really set as 100
}
Anyone experiencing the same with amfphp?
That's odd, I never got that from AMFPHP. If you don't have the latest version try updating your installation of AMFPHP. Also make sure Flash doesn't somehow pass an empty variable as the second variable.
(Copied from the comment.)