below code return "File '' is not readable or does not exist" always:
$filters = array(
'*' => 'stringTrim'
);
$validators = array(
'image'=> array(
'allowEmpty' => TRUE,
new Zend_Validate_File_ImageSize(array('minheight'=>0,'minwidth'=>0,'maxheight'=>1024,'maxwidth'=>1024)),
)
);
$input = new Zend_Filter_Input($filters, $validators);
$input->setData(array_merge($data, $_FILES));
if (!$input->isValid()) {
$this->_errors = $input->getMessages();
}
The input name of your file input has to be image. Also, be sure your form has enctype="multipart/form-data". The format of $_FILES is explained here.
Aside from that I don't detect any code in Zend_Validate_File_ImageSize that can operate on $_FILES. I think you've got to pass the actual path to the file, e.g. 'image' => $_FILES['image']['tmp_name'] (in your $input->setData() call).
Related
I'm trying to perform validation with cake 2.3.8 on a file upload to make sure that only PDF's can be uploaded. I'm loosly basing this off of this tutorial.
My form is displaying the asterisk next to the input, and when I remove the validation from my model the asterisk goes away. I'm assuming this means it "sees" the input for validation, but I just can't figure out why even the custom validation isn't being triggered.
Here's the form
echo $this->Form->create('Upload', array('type' => 'file'));
echo $this->Form->input('file_upload', array('type' => 'file'));
echo $this->Form->input('file_title');
echo $this->Form->end(__('Upload File!', true));
Here's the code in my Upload model
public function checkUpload(){
echo "test"; //check to see if it reaches this...not displaying
return false; //the error message should be set just for testing, it's not displaying though
}
public $validate = array(
'file_upload' => array(
'extension' => array(
'rule' => array('extension', array('pdf')),
'message' => 'Only pdf files',
),
'upload-file' => array(
'rule' => array('checkUpload'),
'message' => 'Error uploading file'
)
)
);
Here is my answer (albeit for cakephp 1.3):
In your model add the following validation to your $validate variable.
$this->validate = array(...
// PDF File
'pdf_file' => array(
'extension' => array(
'rule' => array('extension', array('pdf')),
'message' => 'Only pdf files',
),
'upload-file' => array(
'rule' => array('uploadFile'), // Is a function below
'message' => 'Error uploading file'
)
)
); // End $validate
/**
* Used when validating a file upload in CakePHP
*
* #param Array $check Passed from $validate to this function containing our filename
* #return boolean True or False is passed or failed validation
*/
public function uploadFile($check)
{
// Shift the array to easily acces $_POST
$uploadData = array_shift($check);
// Basic checks
if ($uploadData['size'] == 0 || $uploadData['error'] !== 0)
{
return false;
}
// Upload folder and path
$uploadFolder = 'files'. DS .'charitylogos';
$fileName = time() . '.pdf';
$uploadPath = $uploadFolder . DS . $fileName;
// Make the dir if does not exist
if(!file_exists($uploadFolder)){ mkdir($uploadFolder); }
// Finally move from tmp to final location
if (move_uploaded_file($uploadData['tmp_name'], $uploadPath))
{
$this->set('logo', $fileName);
return true;
}
// Return false by default, should return true on success
return false;
}
You may have to display the error validation messages yourself, you can do this using:
<!-- The classes are for twitter bootstrap 3 - replace with your own -->
<?= $form->error('pdf_file', null, array('class' => 'text-danger help-block'));?>
if you try to debug sth in Cake, always use debug(sth) // sth could be variable could be string could be anything, cuz in Cake debug means
echo "<pre>";
print_r(sth);
echo "</pre>";`
it's already formatted very well.
then after that you have to put die() otherwise after echo sth it will load the view that's why you can't see it even there was an output.
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!
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.
I've noticed in Kohana 3 these error messages provided by default.
return array(
'not_empty' => ':field must not be empty.',
);
Obviously, :field is replaced with the field name.
Now I am validating an image upload. Obviously, I'm allowing only JPG, JPEG, GIF & PNG.
I have an error message set up like so.
return array(
'photo' => array(
'Upload::type' => 'You must upload an image file (JPG, JPEG, GIF, PNG)'
)
);
I also use Kohana's validation helper like so.
$input->rules('photo', array(
'Upload::type' => array('Upload::type' => array('jpg', 'jpeg', 'png', 'gif'))
));
Is there a way I can use those accepted extensions in my error string, perhaps like...
return array(
'photo' => array(
'Upload::type' => 'You can only upload files of :types'
)
);
you can access the parameters with :param1 :param2 etc
'error' => 'You can only upload files of :param1, :param2, :param3'
I guess this doesn't work so well with variable amounts of parameters =(
A possible solution would be to use a callback as an alias to the rule, then take the list of allowed formats and send them to the message manually using implode().
ex:
public function valid_type(Validate $array, $field, $formats)
{
$params = $formats;
array_unshift($params, $array[$field]);
if ( ! call_user_func_array(array('Upload', 'type'), $params))
{
$array->error($field, 'Upload::type', array('types' => $formats));
}
}
Kohana has this feature "out of the box" :)
So, you should add something like this:
// messages/validate.php
return array(
'upload::type' => ':field should be one of the following types: [:param1]',
);
I'm using Zend_Validate to validate some form input (Zend Framework version is 1.8.2). For some reason, using the Zend_Filter_Input interface as described here does not work:
$data = $_POST;
$filters = array('*' => array('StringTrim'));
$validators = array('driverName' => array('NotEmpty','messages' => 'This should override the default message but does not!'));
$inputFilter = new Zend_Filter_Input($filters,$validators,$data);
$messages = $inputFilter->getMessages();
debug($messages); //show me the variable contents
Output from debug($messages):
Array
(
[driverName] => Array
(
[isEmpty] => You must give a non-empty value for field 'driverName'
)
)
No matter what I do, I cannot override that message. If I use the validator directly, i.e.:
$notEmpty = new Zend_Validate_NotEmpty();
$notEmpty->setMessage('This WILL override the default validation error message');
if (!$notEmpty->isValid($_POST['driverName'])) {
$messages = $notEmpty->getMessages();
debug($messages);
}
Output from debug($messages):
Array
(
[isEmpty] => Please enter your name
)
Bottom line. I can get validators to work, but without the benefits of the Zend_Filter_Input interface method of validation I might as well write my own validation class!
Does anyone have a clue as to why this is happening, and how to fix it?
Could it be a bug?
The messages key in the validator array must be passed an array of key/value pairs, where the key is the validation message constant, and the value is your custom error message. Here's an example:
$validators = array(
'excerpt' => array(
'allowEmpty' => true,
array('StringLength', 0, Ctrl::getOption('blog/excerpt/length')),
'messages' => array(Zend_Validate_StringLength::TOO_LONG => 'The post excerpt must not exceed '.Ctrl::getOption('blog/excerpt/length').' characters.')
),
);
However, in your case, the error message you are receiving is coming from the the allowEmpty meta command of Zend_Filter_Input. This isn't really a standard validator. You can set it like so:
$options = array(
'notEmptyMessage' => "A non-empty value is required for field '%field%'"
);
$input = new Zend_Filter_Input($filters, $validators, $data, $options);
// alternative method:
$input = new Zend_Filter_Input($filters, $validators, $data);
$input->setOptions($options);
If you need a different not empty message per field, I'd recommend setting allowEmpty => true and adding a NotEmpty validator with a custom message.
For your reference, the correct message key for the NotEmpty validator is Zend_Validate_NotEmpty::IS_EMPTY
The MESSAGES argument takes an array, not a string. Try this:
$validators = array('driverName' =>
array('NotEmpty',
'messages' => array(
0 => 'This should override the default message but does not!'
)
)
);
It's a bug, it's in the JIRA of Zend Framework...