CakePHP validation not detecting form field - php

I have a form where users can upload images, and I'm printing it to the page like so:
<?php echo $this->Form->label('file', 'Image file', array('class' => 'col-lg-1 control-label')); ?>
Then, in the model I'm setting up validation like so:
public $validate = array(
'file' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'You must select an image to upload'
),
'extension' => array(
'rule' => array('extension', array('png')),
'message' => 'Images must be in PNG format'
),
'size' => array(
'rule' => array('fileSize', '<', '1MB'),
'message' => 'Images must be no larger than 1MB'
),
'goodUpload' => array(
'rule' => 'uploadError',
'message' => 'Something went wrong with the upload, please try again'
)
)
);
However, Cake doesn't seem to be associating the form field with the validation rule, as if I select an image to upload I always get "You must select an image to upload" as a form error. I've made sure the form has enctype="multipart/form-data".
Is this happening because file isn't a database field? How can I make cake run some validation on file?
Edit: Here's my entire form, as requested: http://pastebin.com/SbSbtDP9

You can validate fields that are not in the database, long as you have the correct field name in the correct model.
From what I can see in your code it seems your outputting a label instead of an actual input, for the image upload I would try
echo $this->Form->create('Model', array('type'=>'file'));
echo $this->Form->input('file', array('type'=>'file'));
echo $this->Form->submit('Upload Image'):
echo $this->Form->end();
For the validation I would try something like with the rest of your validate options (size, etc...) CakePHP usually throws an error on notEmpty on File Uploads. So just checking for the extension type is usually good enough.
public $validate = array(
'file' => array(
'rule' => array(
'extension', array('jpeg', 'jpg')
'message' => 'You must supply a file.'
)
)
);
Majority of time in CakePHP for Image Uploading I resort to a plugin such as https://github.com/josegonzalez/cakephp-upload it does validation and upload handling all in one.

Managed to figure it out. Turns out having the notEmpty validation on a file fieldnever works, it always thinks there's nothing there and so always throws that validation message.
Worked around it by writing my own validation method.

Related

cakephp 3 image upload

I am trying to upload image by cakephp 3. I have tried the code below which was working in cakephp 2. Now in cakephp 3 I have tried the code below
database field
ALTER TABLE `users` ADD `avatar` VARCHAR(255) NOT NULL ;
Then in users add.ctp I have created below form
<?= $this->Form->create($user,['type' => 'file']) ?>
<?= $this->Form->input('avatar',['type' => 'file']);?>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
In user model I have added this validation
$validator
->add('avatar', [
'uploadError' => [
'rule' => 'uploadError',
'message' => 'The cover image upload failed.',
'allowEmpty' => TRUE,
],
'mimeType' => [
'rule' => array('mimeType', array('image/gif', 'image/png', 'image/jpg', 'image/jpeg')),
'message' => 'Please only upload images (gif, png, jpg).',
'allowEmpty' => TRUE,
],
'fileSize' => [
'rule' => array('fileSize', '<=', '1MB'),
'message' => 'Cover image must be less than 1MB.',
'allowEmpty' => TRUE,
],
'processCoverUpload' => [
'rule' => 'processCoverUpload',
'message' => 'Unable to process cover image upload.',
'allowEmpty' => TRUE,
],
]);
After that I found this error
ext/fileinfo is required for validating file mime types
After ndm's comment, I have changed
;extension=php_fileinfo.dll
to
extension=php_fileinfo.dll
in the php.ini file
Then this error has been gone. But the new error that I found
error : Method processCoverUpload does not exist
But in the method below I have added
public function processCoverUpload($check = array()) {
if (!is_uploaded_file($check['avatar']['tmp_name'])) {
return FALSE;
}
if (!move_uploaded_file($check['avatar']['tmp_name'], WWW_ROOT . 'img' . DS . 'uploads' . DS . $check['avatar']['name'])) {
return FALSE;
}
$this->data[$this->alias]['avatar'] = 'uploads/'. $check['avatar']['name'];
return TRUE;
}
I don't know why Method processCoverUpload does not exist. Can you explain?
As already mentioned in the comments, CakePHP 3.x now requires the fileinfo extension for validating mime types.
http://php.net/manual/en/fileinfo.installation.php
The other error happens because you haven't defined a provider where your custom method can be found. You've most likely added the method to your table class, so in that case you should use the table provider
'processCoverUpload' => [
'provider' => 'table', // <<<< there you go
'rule' => 'processCoverUpload',
'message' => 'Unable to process cover image upload.',
'allowEmpty' => TRUE,
],
The default provider is defined to use the \Cake\Validation\Validation class.
On a side note, $check wont contain the field name as a key, validation methods will receive the plain value that the key in the data holds.
Also $this->data doesn't exist anymore, things are working different now in 3.x. If you want to modify the data, then you should use the beforeMarshal or beforeSave events. However, with the latter you'll run into problems in case the upload field is using the same name as the column in the database which stores the file path, as this will cause the array to be marshalled to the type of the column, which is most probably a string type: https://github.com/cakephp/cakephp/issues/5998
See also
Cookbook > Database Access & ORM > Validation > Validation Providers
Cookbook > Validation > Adding Validation Providers
Cookbook > ... ORM > Saving Data > Modifying Request Data Before Building Entities

Laravel 4 CSS file validation failing

I have an upload form that has validation checks whether an item is a valid CSS file or not. I do try to upload a .css file but the validation fails.
Here's the bit where I try to validate the code on my controller:
private function _queueArticle($ref = NULL)
{
$input = Input::all();
$vrules = Config::get('validation.queue_article');
//validate inputs
$validation = Validator::make($input, $vrules);
if ( $validation->fails() ) {
return ( $ref === NULL ) ?
Redirect::to($redir_path)->withErrors($validation)->withInput() :
Redirect::to($redir_path)->withErrors($validation);
}
}
Here's what's $vrules:
'queue_article' => array(
'title' => 'required|max:255',
'body' => 'required',
'slug' => 'unique:articles,slug',
'hero' => 'required|image',
'custom_css' => 'mimes:css'
)
I believe it's failing because it's using PHP's finfo, which is known to fail detecting css not as text/css, but rather text/plain. Doesn't Symfony, Laravel's 'companion code' here (don't know the term), has its own validation class that successfully clears CSS for what it is?
More importantly, what can I do about this?
UPDATE: Error message shows my custom error 'Please upload a valid CSS file.' From app/lang/en/validation.php:
'custom' => array(
'password_old' => array( 'required' => 'Please enter your current password.' ),
'password' => array( 'confirmed' => 'The new passwords don\'t match.' ),
'hero' => array(
'required' => 'A header image is required.',
'image' => 'The header file you included is not valid. Please upload a valid image.'
),
'custom_css' => array('mimes' => 'Please upload a valid CSS file.')
)
UPDATE 2: I checked var_dump($validation) and showed zero contents on array messages and failedRules. It also shows the CSS file having mime type as text/css. All is well, eh, except when I var_dump($validation->fails()) it returns a bool of true.
Additional info will be provided upon request.
Thanks!

CakePHP empty field versus not empty field validations

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.

AllowEmpty vs NotEmpty

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',
),
),

CakePHP validation alpha problem w/ validation is checked - what am I doing wrong?

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.'
)
)
);

Categories