How can I call the CakePHP 3.x built-in 'rule'=>'email' inside of my own validation rule? I would like to make this check among other customized checks not in e.g. validationDefault function.
public function myValidationRule($value,$context){
// HERE -- how can I call standard email rule
}
Except for requirePresence, allowEmpty and notEmpty, all built-in rules map to corresponding static methods on the \Cake\Validation\Validation class, which you can invoke manually yourself if necessary.
The email rule uses Validation::email(), so you can use it like
public function myValidationRule($value, $context) {
// ...
$isValid = \Cake\Validation\Validation::email($value);
// ...
}
See also
Cookbook > Validation > Core Validation Rules
API > \Cake\Validation\Validation::email()
public function myValidationRule($value,$context){
// HERE -- you can get your email in $value and other values in $context
// HERE you can add any of your custome validation rule
// for example
return $value==null;
// it will return true if your email is null.
}
Related
I want to add a custom validation rules with parameter and in the Laravel documentation https://laravel.com/docs/5.8/validation#custom-validation-rules there is no validation parameters option. I want a validation rule like required_if.
You can pass it in the constructor
new CustomRule($parameter);
class CustomRule implements Rule
{
public function __construct($parameter)
{
$this->parameter = $parameter;
}
...
You can use sometimes method on validator instance. Use a required rules and add your condition in the function as below:
$v->sometimes('reason', 'required|max:500', function ($input) {
return $input->games >= 100;
});
The example above will check if games are more than or equal to 100, then user will required to have a reason, otherwise it will trigger an error.
The example is from Laravel documentation that you can find here here
Yii2 has support for XSS(cross-site-scripting ) validation of displayed data using the helper class\yii\helpers\HtmlPurifier, however this only validates and cleans up output code like this
echo HtmlPurifier::process($html);
How to validate input for XSS of input such that this data is not stored in the database itself ?
This can be done using a filterValidator by calling the process as named callable function of validation like this
class MytableModel extends ActiveRecord {
....
public function rules(){
$rules = [
[['field1','field2'],'filter','filter'=>'\yii\helpers\HtmlPurifier::process']
];
return array_merge(parent::rules(),$rules);
}
....
}
Where field1, field2 etc are the inputs fields to be validated, the same applies for Form Model validations as well
in the before validate method add the following:
public function beforeValidate()
{
foreach (array_keys($this->getAttributes()) as $attr){
if(!empty($this->$attr)){
$this->$attr = \yii\helpers\HtmlPurifier::process($this->$attr);
}
}
return parent::beforeValidate();// to keep parent validator available
}
it will help you if you want to run Xss Validator before validate/save all attributes nested of adding the following line
return array_merge(parent::rules(),$rules);
to every class extends the new active record
One of my forms uses AJAX to send data. Since my page never reloads because of AJAX, is there a way I can still make use of form_validation to validate and output which fields are wrong? The url my form sends to using jquery is contact/ajax_send.
The entire AJAX works fine except I haven't inserted any validation yet.
Since you are using ajax to send the data, what you can do is, simply add the form_validation code calls before inserting into the database.
If there are any validation errors, you can either return the error messages as json response to the front end to display the error messages.
The form validation library assigns all errors that occurred to a private array called _error_array, but does not expose it or provide documentation on it (notice the first underscore?). Just return a json encoded object of the errors in the controller:
echo json_encode($this->form_validation->_error_array);
If you wish, you can extend CodeIgniter's form validation library, perhaps returning FALSE instead of an empty array... or whatever you see fit:
/* libraries/MY_Form_validation.php */
<?php
class MY_Form_validation extends CI_Form_validation
{
function __construct($config = array())
{
parent::__construct($config);
}
function error_array()
{
if (count($this->_error_array) === 0) return FALSE;
else return $this->_error_array;
}
}
Now, drop the initial underscore in the controller:
echo json_encode($this->form_validation->error_array);
Then decode and display errors on the client.
I found a method, thanks in part to Jordan's answer. This returns an array containing the names of the fields which have errors.
// library/MY_Form_validation.php
class MY_Form_validation extends CI_Form_validation {
public function get_field_data(){
return count($this->_field_data) ? $this->_field_data : FALSE;
}
}
// Controller file
$field_data = $this->form_validation->get_field_data();
foreach($field_data as $key=>$val){
if($key == '__proto__') break;
foreach($val as $k=>$v){
if($k == 'error' && !empty($v)) $errors[] = $key;
}
}
$return = array('success'=>FALSE, 'errors'=>$errors);
The above code checks the error key whether it's empty or not. Empty values mean that it passed the CI validation while none empty values would contain the string you see when you use validation_errors(). Since I'm after those fields which have errors, I only needed to see which values are not empty disregardig those which are.
I would like to override the standard URL validation rule to make it more tolerant of a whitespace character before or after the URL. Basically use the trim() function on the url before passing it to the standard URL validation handler.
I know I need to override that rule but I'm not exactly where and how I need to do it.
(Plus, the CakePHP API and book documentation are currently offline. Upgrades, I know...)
You can add custom validation rules in your Model classes, your Behavior classes, or in the AppModel class:
http://book.cakephp.org/view/150/Custom-Validation-Rules#Adding-your-own-Validation-Methods-152
Since you want to override an existing method, just give it the same name and signature as the original. Something like this might do the trick:
function url($check, $strict = false) {
return Validation::url(trim($check), $strict);
}
Why would you wanna do that?
Simply make sure all posted data is always trimmed.
Thats cleaner and more secure, anyway.
I have a component doing that in beforeFilter:
/** DATA PREPARATION **/
if (!empty($controller->data) && !Configure::read('DataPreparation.notrim')) {
$controller->data = $this->trimDeep($controller->data);
}
The trimDeep method:
/**
* #static
*/
function trimDeep($value) {
$value = is_array($value) ? array_map(array(&$this, 'trimDeep'), $value) : trim($value);
return $value;
}
I have a SymfonyForm which has 1:n embedForm(s). The main form and the embedForm class got their own PreValidation, which implements a conditional validation.
A part of the EmbedForm class looks like this:
private function configurePreValidators() {
$validator = new sfValidatorCallback( array('callback'=> array($this, 'preValidation')) );
$this->getValidatorSchema()->setPreValidator(new sfValidatorOr( array( $validator ) ));
}
public function preValidation(sfValidatorCallback $validator, array $values){
...
$this->getValidator(self::SOME_FIELD)->setOption('required', false);
...
}
public function configure() {
...
$this->configurePreValidators();
parent::configure();
}
The prevalidation of the main form is similar.
When I submit the form, the main form prevalidation works fine.
In the embed-Form the "SOME_FIELD" gets a required-validation-error although I set it explicit to setOption('required', false) in the preValidation of the embedForm.
Is there something what I have to consider when I use pre-validation in an embedForm? What about mergePreValidator? Any hints about that?
Thanks in advance!
The issue here is not that your pre and post validators aren't firing -- they are (or at least, they should be). The issue is that the validator you are modifying is preValidate is not the one referenced in the top-level validator schema, i.e. the validator schema for the top-level form.
One solution: rather than modify the validator in preValidate, simply perform the validation:
public function preValidation(sfValidatorCallback $validator, array $values)
{
if (!$this->getValidator(self::SOME_FIELD)->isEmpty($values[self::SOME_FIELD])
{
throw new sfValidatorErrorSchema(self::SOME_FIELD => new sfValdiatorError($validator, 'msg'));
}
}
Note, this solution has some danger: if you modify the validator for SOME_FIELD inside of the top-level form, it will not be modified in this pre validator and vice-versa.
Let's look at why. In sfForm::embedForm:
public function embedForm($name, sfForm $form, $decorator = null)
{
...
$this->validatorSchema[$name] = $form->getValidatorSchema();
...
}
Symfony simply nests the validators. This is why pre and post still get called. Why does the reference change? sfValidatorSchema::offsetSet:
public function offsetSet($name, $validator)
{
...
$this->fields[$name] = clone $validator;
}
So when a form is embedded, the validator schema is cloned. Thus, any modifications to the validators inside of an embedded form do not affect the top-level validator schema.