I have this part of code:
if ($this->request->isPost() && $this->request->hasFiles()) {
$post = $this->request->getPost();
$file = $this->request->getUploadedFiles();
if ($form->isValid($post)) {
$form->bind((array) $this->request->getPost(), $entity);
$entity->save();
// Do some other stuff
}
}
Is there a way to pass $file to a Phalcon\Forms\Form object?
Or another practice to check if validity of a form that contains both files and text?
To validate Files you must use the FileValidator Class as this example:
$file = new FileValidator([
'maxSize' => '10M',
'messageSize' => _('Your file is huge. Max allowed is 10 Mb'),
'allowedTypes' => ["image/jpeg", "image/png"],
'messageType' => _('File type is not permitted. Try with JPG, GIF, etc..'),
'messageEmpty' => _('Cannot be empty. Please upload a file')
]);
$this->validator->add('filesInputName', $file);
$messages = $this->validator->validate($_FILES);
This is a really old question, but as it affects my current project I share my solution.
Normally, I'm using form classes and validation classes, too. For validating a file upload along with other POST data, I simply combine both payloads:
$entity = new MyCustomModel();
$merged = array_merge($_POST, $_FILES);
if ($form->isValid($merged, $entity)) {
// ...
}
Related
i want to validate my file, only .ico files.
Laravel dont include x-icon mime I think, how can i validate it?
$logo = $request->file('logo');
$favicon = $request->file('favicon');
$request->validate([
'logo'=>'image|mimes:png',
'favicon'=>'',
]);
Make a custom validation rule as explained here.
In short:
First do:
php artisan make:rule CheckIfFavicon
Then:
Create the validation code in the created Rules-file.
Try something like:
public function passes($attribute, $value)
{
return $value->getClientOriginalExtension() == 'ico';
}
Then ad it to the validation. Note, that if you make a custom validation class you will have to change the syntax in the $request->validate([...]) from pipe-ing to array.
$request->validate([
'favicon' => [new CheckIfFavicon],
]);
use $file->getClientOriginalExtension() in code if you only want to check file extension
$ext = $file->getClientOriginalExtension();
if($ext == 'ico'){
//uploadfile
}else{
//do something else
}
use this as reference.
How to verify that an image is really an "Image" or a PDF is really a "PDF document" during the upload?
I observed a hack attempt to upload some files with jpg extension which has a picture preview but when I tried to open this file in an editor I saw php codes!
My concern is about:
How can I verify that a file is a real file?
Im using laravel framework, I tested with image mimes validation as shown below:
$inputs = array('image'=>$request->file('file'));
$rules = array(
'image' => 'mimes:jpeg,jpg,png,gif|required|max:10000'
);
$validator = Validator::make($inputs, $rules);
if ($validator->fails()){
die('validation failed');
}else{
die('validation Passed');
}
But this validation always pass if I try to upload the invalid jpeg file with some php injected codes!
Update:
invalid jpeg file attached
If you want to verify that it is an image, add the 'image' rule to your $rules array:
$rules = array(
'image' => 'image|mimes:jpeg,jpg,png,gif|required|max:10000'
);
https://laravel.com/docs/master/validation#rule-image
At last, i decided to check the file manually using the method -
file_get_contents(). I don't know whether this is an optimal solution. awaiting suggestions & recommendations :
public function validateFileContents($file,$needlesArray=null){
if(empty($needlesArray)){
$needlesArray = ['<?php','eval','base','gzuncomp'];
}
foreach($needlesArray as $needle){
if( strpos(file_get_contents($file),$needle) !== false) {
return false;
break;
}
}
return true;
}
I need to send an image to server via an ajax request and it gets through just fine
and in my controller I can just use $_FILES["image"] to do stuff to it.
But I need to validate the image before I save it.
And in the Yii this can be achieved by doing something like this
$file = CUploadedFile::getInstance($model,'image');
if($model->validated(array('image'))){
$model->image->saveAs(Yii::getPathOfAlias('webroot') . '/upload/user_thumb/' . $model->username.'.'.$model->photo->extensionName);
}
But the problem is I don't have a $model, all I have is $_FILES["image"], now what should I put instead of the $model???
is there any other way where I can validate and save files without creating a model and just by Using $_FILES["image"]?
thanks for this awesome community... :)
Exists many ways how you can do upload. I want offer to you one of them.
1.You need to create model for your images.
class Image extends CActiveRecord {
//method where need to specify validation rules
public function rules()
{
return [
['filename', 'length', 'max' => 40],
//other rules
];
}
//this function allow to upload file
public function doUpload($insName)
{
$file = CUploadedFile::getInstanceByName($insName);
if ($file) {
$file->saveAs(Yii::getPathOfAlias('webroot').'/upload/user_thumb/'.$this->filename.$file->getExtensionName());
} else {
$this->addError('Please, select at least one file'); // for example
}
}
}
2.Now, need to create controller, where you will do all actions.
class ImageController extends CController {
public function actionUpload()
{
$model = new Image();
if (Yii::app()->request->getPost('upload')) {
$model->filename = 'set filename';
$insName = 'image'; //if you try to upload from $_FILES['image']
if ($model->validate() && $model->doUpload($insName)) {
//upload is successful
} else {
//do something with errors
$errors = $model->getErrors();
}
}
}
}
Creating a model might be overkill in some instances.
The $_FILE supervariable is part of the HTTP mechanism.
You can handle the copy by using the native PHP function move_uploaded_file()
$fileName = "/uploads/".myimage.jpg";
unlink($fileName);
move_uploaded_file($_FILES['Filedata']['tmp_name'], $fileName);
However, you lose the niceties of using a library that provides additional functionality and checks (eg file type and file size limitations).
So far this is what I know to be the way to pass the data from a post into the form.
$form->setData( $this->getRequest()->getPost() );
I thought that this might work
$form
->setData( $this->getRequest()->getPost() )
->setData( $this->getRequest()->getFiles() );
Which it does not. Looking through the framework source I confirmed that it shouldn't. So I was thinking about merging the file data into post data. Surely this cannot be the desired solution? It's not as if getPost() and getFiles() return easily mergeable arrays, they return Parameter objects.
Please note this is Zend Framework 2 specific.
Have you tried getFileInfo knowing now or paying mind to the fact that your using Zend. Typically on a per file basis $_FILE is an array based on the information of the file being uploaded. Filename, extension, etc.. Zends getFileInfo outputs that information in a similar fashion. Though I haven't played with it in sometime, its worth looking into
Example concept (more for multiple file uploads I know, but works with one, good concept to leave in tact just incase you wanna add a second or more files down the road)
$uploads = new Zend_File_Transfer_Adapter_Http();
$files = $uploads->getFileInfo();
foreach($files as $file => $fileInfo) {
if ($uploads->isUploaded($file)) {
if ($uploads->isValid($file)) {
if ($uploads->receive($file)) {
$info = $uploads->getFileInfo($file);
$tmp = $info[$file]['tmp_name'];
$data = file_get_contents($tmp);
// here $tmp is the location of the uploaded file on the server
// var_dump($info); to see all the fields you can use
}
}
}
}
After attempting to use Zend's file transfer adapter I went with a workaround in the controller. I think that the setData() in the form class should merge the items into the data instead of replacing them. (IMHO)
protected function getPostedData()
{
if ( is_null($this->postedData) )
{
$this->postedData = array_merge(
(array) $this->getRequest()->getPost(),
(array) $this->getRequest()->getFiles()
);
}
return $this->postedData;
}
I am using array_merge:
$form = $this->getForm('my_form');
$request = $this->getRequest();
if($request->isPost())
{
$file = $this->params()->fromFiles('name_of_file');
$form->setData(array_merge(
$request->getPost()->toArray(),
array('arquivo' => $file['name'])
));
if ($form->isValid()) {
// now i can validate the form field
I use variable variables like this article explains to create variables and then echo them as the values for each form entry.
example:
// create array of GET/POST variables then convert each variable to a local variable
$fields = array_keys($_REQUEST);
foreach ($fields as $field) {
$$field = $_REQUEST[$field];
}
I have a file upload form in the frontend.
At the moment, when a new record is created, the file is uploaded to
%sf_data_dir%/files/
but due to some business logic I need the file to be uploaded to
%sf_data_dir%/files/%record_id%/
Therefore the uploaded file should be saved AFTER the record is created.
How can I achieve that?
If you use file upload, your form certainly make use of the sfValidatorFile (if not, that's wrong):
$this->validatorSchema['image'] = new sfValidatorFile(array(
'required' => true,
'mime_types' => 'web_images',
));
This validator return a sfValidatedFile instance that can be saved anywhere you want (it's safer than move_uploaded_file, there is checks on the directory, filename...).
In your action (or in the form, as you want/need), you can now do this:
protected function processForm(sfWebRequest $request, sfForm $form)
{
$form->bind(
$request->getParameter($form->getName()),
$request->getFiles($form->getName())
);
if ($form->isValid())
{
$job = $form->save();
// Saving the file to filesystem
$file = $form->getValue('my_upload_field');
$file->save('/path/to/save/'.$job->getId().'/myimage.'.$file->getExtension());
$this->redirect('job_show', $job);
}
}
Don't hesitate to open sfValidatedFile to see how it work.