I am using multiple scenarios in my application but facing a problem that every time the last scenario overrides the first one.
Model:
public function rules()
{
return array(
[...]
array('cost_spares', 'cost_spare_func', 'match',
'pattern' => '/^[a-zA-Z]+$/',
'message' => 'Do not enter zero or/and characters for Spare parts!',
'on' => 'cost_spare_func'),
array('cost_labour', 'cost_labour_func', 'match',
'pattern' => '/^[a-zA-Z]+$/',
'message' => 'Do not enter zero or/and characters for Labour Charges!',
'on' => 'cost_labour_func'),
);
}
Controller :
public function actionUpdate ($id)
{
if (isset($_POST['TblEnquiry']))
{
[...]
$model->setScenario('cost_spare_func');
$model->setScenario('cost_labour_func');
}
}
Regarding to the documents:
Firstly it is important to note that any rules not assigned a scenario will be applied to all scenarios.
So I think you maybe do not need a scenario and just use common rules/validation.
OR
You have ONE scenario for your rules like this:
public function rules()
{
return array(
[...]
array('cost_spares','numerical',
'integerOnly' => true,
'min' => 1,
'max' => 250,
'tooSmall' => 'You must order at least 1 piece',
'tooBig' => 'You cannot order more than 250 pieces at once',
'message' => 'Do not enter zero or/and characters for Spare parts!',
'on' => 'myScenario'),
array('cost_labour','numerical',
'integerOnly' => true,
'min' => 1,
'max' => 250,
'tooSmall' => 'You must order at least 1 piece',
'tooBig' => 'You cannot order more than 250 pieces at once',
'message' => 'Do not enter zero or/and characters for Labour Charges!',
'on' => 'myScenario'),
);
}
And in your controller you just write:
public function actionUpdate ($id)
{
if (isset($_POST['TblEnquiry']))
{
[...]
$model->setScenario('myScenario');
}
}
Edit: Regarding to this document, I just see that you only want numerical input. So this might fit better to your needs. And since both got same check, you could just do one check and pass the message later into it. But for now, this should work.
Extra:
There is another bug in your rules like you wrote.
array('cost_spares', 'cost_spare_func', 'match',
'pattern' => '/^[a-zA-Z]+$/',
'message' => 'Do not enter zero or/and characters for Spare parts!',
'on' => 'cost_spare_func'),
That is not possible. You can not mix a rule validate function and a default validation like match.
That means you can only define a validation function like this:
array('cost_spares', 'cost_spare_func',
'message' => 'Do not enter zero or/and characters for Spare parts!',
'on' => 'cost_spare_func'),
OR use a default validation like this:
array('cost_spares', 'match',
'pattern' => '/^[a-zA-Z]+$/',
'message' => 'Do not enter zero or/and characters for Spare parts!',
'on' => 'cost_spare_func'),
Related
inList states that your array should contain a certain string value.
I'm looking for a rule that will exclude certain values for names in my model.
The following code states that the name should be Bob, Bobbie or Bobzilla:
'name' => array(
'rule' => array('inList', array('Bob', 'Bobbie', 'Bobzilla')),
'message' => 'Stop it Bob!'
),
I need the user to be unable to enter any of these names. To me it seems as if inList should be notInList.
I've tried many ways but none of them lead me to Rome.
If you could help me that would be very much appreciated!
Take a look at PHP in_array function
something like
if (!in_array(ENTERED_NAME,YOUR ARRAY)) {
}
This is the best solution I was able to come up with:
public function itsBob($check) {
$bobArr = ['Bob', 'Bobbie', 'Bobzilla'];
if (!in_array($check['name'], bobArr) {
return false;
}
return true;
}
With the following lines in the $validation:
'name' => array(
'rule' => array('itsBob'),
'message' => 'Stop it bob!'
),
itsBob literally does the opposite of inList.
I'm trying to do alphanumeric with spaces validation in CakePHP 3.5.13.
So I've added the following to one of my Table classes:
// src/Model/Table/SavedSearchesTable.php
public function validationDefault(Validator $validator)
{
$validator->add('search_name', [
'alphanumeric' => [
'rule' => ['custom', '/^[a-z0-9 ]*$/i'],
'message' => 'Alphanumeric characters with spaces only'
]
]);
return $validator;
}
This does exactly what I want - I get a validation error message if I enter a string that contains characters other than A-Z, 0-9 or a space.
However...reading about Using Custom Validation Rules in the documentation all of the ->add() calls use 3 parameters.
I've looked into the source (vendor/cakephp/cakephp/src/Validation/Validator.php) and the method looks like this:
public function add($field, $name, $rule = [])
{
// ...
}
How can my rule work if I've passed an array for the second parameter, which it's treating as $name?
Edit : Someone has mentioned in the comments that there is a fallback for older code. Well, if I try and use 3 parameters (instead of 2) in the Model (note addition of 'custom' as second param):
$validator->add('search_name', 'custom', [
'alphanumeric' => [
'rule' => ['custom', '/^[a-z0-9\' ]*$/i'],
'message' => 'Alphanumeric characters with spaces only'
]
]);
It now produces an error:
Unable to call method "" in "default" provider for field "search_name"
The correct answer to this was provided by #ndm in the comments.
I'm writing out a full example in case anyone else has this problem.
It can either be written as:
$validator->add(
'search_name',
'alphanumeric',
[
'rule' => ['custom', '/^[a-z0-9 ]*$/i'],
'message' => 'Alphanumeric characters with spaces only'
]
);
or:
$validator->add('search_name',
[ // second argument is an array. This was how it was in the original question.
'alphanumeric' =>
[
'rule' => ['custom', '/^[a-z0-9 ]*$/i'],
'message' => 'Alphanumeric characters with spaces only'
]
]
);
The following is given as a comment in Cake's source code regarding how the add() method works:
Adds a new rule to a field's rule set. If second argument is an array then rules list for the field will be replaced with second argument and third argument will be ignored.
Both of these have been tested and give the same result in CakePHP 3.5.13
I have the follow validation rule for a file:
modelFile.php
public $validate = array(
'image' => array(
'maxWidth' => array(
'rule' => array('maxWidth', 2000),
),
'maxHeight' => array(
'rule' => array('maxHeight', 2000),
),
'extension' => array(
'rule' => array('extension', array('gif', 'jpg', 'png', 'jpeg')),
),
'filesize' => array(
'rule' => array('filesize', 5120000),
)
)
);
Have a way to skip validations, if image are empty?
You may have to adjust how you check if the image is empty/not uploaded - I'm not sure if what I have is correct. But the idea is to check and unset the validation rule.
public function beforeValidate($options = array()) {
if (empty($this->data[$this->alias]['image']['name'])) {
unset($this->validate['image']);
}
return true;
}
See below URL
cakePHP optional validation for file upload
Or try it
"I assign $this->data['Catalog']['image'] = $this->data['Catalog']['imageupload']['name'];"
So by the time you save your data array, it looks something like this I assume:
array(
'image' => 'foobar',
'imageupload' => array(
'name' => 'foobar',
'size' => 1234567,
'error' => 0,
...
)
)
Which means, the imageupload validation rule is trying to work on this data:
array(
'name' => 'foobar',
'size' => 1234567,
'error' => 0,
...
)
I.e. the value it's trying to validate is an array of stuff, not just a string. And that is unlikely to pass the specified validation rule. It's also probably never "empty".
Either you create a custom validation rule that can handle this array, or you need to do some more processing in the controller before you try to validate it
Ok, as far as I know there is no such code to set this in your $validate variable. So what you are going to have to do is:
In the beforeValidate of the corresponding model add the following piece of code:
<?php
# Check if the image is set. If not, unbind the validation rule
# Please note the answer of Abid Hussain below. He says the ['image'] will probably
# never be empty. So perhaps you should make use of a different way to check the variable
if (empty($this->data[$this->alias]['image'])){
unset($this->validate['image']);
}
I used http://bakery.cakephp.org/articles/kiger/2008/12/29/simple-way-to-unbind-validation-set-remaining-rules-to-required as my main article. But this function doesn't seem to be a default cake variable. The code above should work.
New to CakePHP here - I'm going through the documentation on the site, trying to muster up some basic data validation for a model I'm creating. This will likely be the first of many questions I have about CakePHP.
In the CakePHP Book, the validation rules seem to specify two different methods for making sure that a field isn't empty - AllowEmpty, and NotEmpty.
Question - is there a tangible difference between these two? CakePHP states that validation rules should occur in your model or controller - is one better suited for a model, and the other for a controller? The Book doesn't say anything about this. I'm guessing that one is an older method that's simply still around?
What gives? Should I use a specific one, or both, or does it not matter?
Edit: I decided to check the CakePHP 1.3 class documentation for it (to check the default value of the allowEmpty attribute), but it doesn't even show up. It's not in the source code either...is there something I'm missing?
Welcome to Cake. I hope you enjoy it.
This is definitely one of the stranger aspects of Cake.
notEmpty is a rule in and of itself. You can define it in your $validation attribute. You can assign a message for when this validation fails. You can treat this as if it is any other validation rule.
allowEmpty is an option of another validation rule, normally not notEmpty. It is not a validation rule in-and-of-itself. This would allow, for example, you to define that a varchar field allows an empty string, '', or a string with no more than 20 characters.
Edit:
Here's some code
// model validation using 'notEmpty'
$validation = array(
'fieldName' => array(
'notEmpty' => array(
'rule' => 'notEmpty',
'message' => 'This value may not be left empty!'
),
... // other rules can go here
),
... // other fieldName can go here
);
// model validation using 'allowEmpty' to create an optional field
$validation = array(
'fieldName' => array(
'maxLength' => array(
'rule' => array('maxLength', 20),
'message' => 'This field may only contain 20 characters!',
'allowEmpty' => true // we'll also accept an empty string
),
... // other rules can go here
)
... // other fieldName can go here
);
I found a case where I had to use 'allowEmpty' => false instead of rule => 'notEmpty'. I had a form with an upload input (type='file') that had a validation rule of notEmpty, and it kept failing validation, even though the debugger showed the file[] array loaded. When I removed the 'notEmpty' rule and set allowEmpty => false, it worked, throwing an error when no file was chosen and accepting it when one was selected.
It must have something to do with the value being an array rather than a text value.
Its very simply to make server side validation in cakephp
Here is code for both validation (noEmpty, maxlength) for the same field.
'fieldName' => array(
'rule' => array('maxLength', 20),
'message' => 'fieldName should be less than 20 characters',
'allowEmpty' => true
),
'fieldName' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'Please enter field name',
),
),
Excuse my ignorance on this question, but what seems to be an obvious fix is not coming together for me..
My validation is working perfectly fine with the exception of when I enter any alpha characters in my form field, I get a sql error:
SQL Error: 1054: Unknown column 'abcde' in 'where clause'...
As you can see I entered 'abcd' as a test..
But if I enter a numeric character and per my validation its all fine.. It appears the alpha value is being read as a column name??
Here is my validation rule:
...'Age' => array(
array(
'rule' => array('maxLength', 3),
array(
'rule' => 'numeric',
'allowEmpty' => true,
'message' => 'Age must be numeric.'
),
),
Here is my controller validation code:
if ($this->RequestHandler->isAjax()) {
if ($this->Plan->validates()) {
$this->Plan->set($this->data);
$errors = $this->Plan->invalidFields();
$this->set('errors', $errors);
} else {
$this->Plan->set($this->data);
}
}
As you can see I am returning my errors to my view, and the correct error "Age must be numeric." does in fact display as expected, but just with the SQL error stuff.
Thanks for any insight as to why this is happening.
Do you even read the manual? It's clearly stated in the CookBook that you need to give your rules names if you want to use multiple rules.
Also, your array is nested completely wrong. I don't know how this could be working, but anyway, this is how your validate should look like:
var $validate = array(
'Age' => array(
'length' => array(
'rule' => array('maxLength', 3)
),
'numbers' => array(
'rule' => 'numeric',
'allowEmpty' => true,
'message' => 'Age must be numeric.'
)
)
);