YII2 XML file upload wont validate - php

I'm making a file upload controller to upload a bunch of XML files to a server.
However, some XML files don't have the <xml version="1.0" encoding="UTF-8"> tag and Yii validator fails to upload these files.
public $xmlFiles;
public function rules() {
return [
[['xmlFiles'], 'file', 'skipOnEmpty' => false, 'extensions' => 'xml', 'maxFiles' => 20],
];
}
public function upload($path) {
if (empty($path)) {
return false;
}
FileHelper::createDirectory($path);
if ($this->validate()) {
foreach ($this->xmlFiles as $file) {
$file->saveAs($path . $file->baseName . '.' . $file->extension);
}
return true;
}
else {
return false;
}
}
How can I change my validation rule to allow this kind of files?

You can always set checkExtensionByMimeType to false in your validation rule and see if it helps.
This one forces validator to not compare MIME type with file extension and thanks to this some files can pass (like plain text *.csv files or probably your *.xml files). Be aware that with this option user can send you any malicious file only by renaming its extension.
Edit:
You can set mimeTypes property in your rule to specific all the MIME types you want to be valid. In your case it might be something like:
['xmlFiles', 'file', 'skipOnEmpty' => false, 'mimeTypes' => ['application/xml'], 'maxFiles' => 20],
With extensions property removed only MIME type is being checked.
It is possible though that in your case MIME type is just text/plain (you should check this first). You can set this here but it will allow all plain text files which is still better than allowing everything.

Related

Laravel file not saved but recorded in database

I am accepting a file and some other parameters with it. I validate the file and the parameters and then I store the file while making a record in the database. Pretty standard stuff. The issue I have is that a majority of my files and records get saved but sometimes there exists a record in the database but there is no file associated with it saved. I have tried reproducing it but I haven't been able to. I don't know if the error is my code, or my server or if the user prematurely loses connection or some other issue of that nature.
I am running Laravel 7 on AWS Lightsail instance with Bitnami LAMP stack.
Store Method in Controller
public function store(StoreRequest $request)
{
$filePath = $request
->file('file')
->storeAs(
'path',
Str::upper($request->input('param1')) .
"_{$request->input('param2')}_{$request->input(
'param3'
)}_{$request->input('param4')}_{$request->input(
'param5'
)}_" .
now()->format('Ymd_Hi') .
".{$request->file('file')->getClientOriginalExtension()}",
'public'
);
Storage::setVisibility('public/' . $filePath, 'private');
$record = Model::create(
array_merge($request->all(), ['file' => $filePath])
);
return redirect()
->back()
->with('message', 'File submitted successfully');
}
Rules in StoreRequest
public function rules()
{
$rules = [
//rules for other parameters
'filetype' => ['required', 'string'],
];
if (request('filetype') === 'video') {
$rules['file'] = [
'required',
'file',
'mimetypes:video/*',
'max:200000',
];
} elseif (request('filetype') === 'image') {
$rules['file'] = ['required', 'file', 'image', 'max:20000'];
}
return $rules;
}
I have 259 records on the database but I have only received 247 files. Where could the error lie? I have tried on my development environment but I haven't been able to reproduce an error like this. Is it something to do with my php.ini settings? Is it something that the user is causing? How can the file not be saved when I am saving it before the record gets stored in the database?
You are using Ymd_Hi which would not allow for any records saved in the same minute, perhaps use a timestring or include seconds too, but be warned, if you use seconds you may face the same issue!
There are two options in pho.ini file. One is upload_max_filesize and another one post_max_size. While uploading the file I think it crosses the size that defined in ini file.
If your video size 200 MB then upload_max_size should be more than or equal 200 MB. post_max_size is total size of form that going to be submitted. It is safer to set size more than upload_max_size.

Yii2 uploaded image doesn't show up

I use this yii2 module for an image uploading purposes.
My upload folder is:
C:\XAMPP\HTDOCS\MYAPPNAME\WEB\UPLOAD
├───cache
├───global
└───store
└───Products
└───Product15
Where store is the folder for original pictures and the cache is for the resized ones. yii2-images is configured like this:
'yii2images' => [
'class' => 'rico\yii2images\Module',
//be sure, that permissions ok
//if you cant avoid permission errors you have to create "images" folder in web root manually and set 777 permissions
'imagesStorePath' => 'upload/store', //path to origin images
'imagesCachePath' => 'upload/cache', //path to resized copies
'graphicsLibrary' => 'GD', //but really its better to use 'Imagick'
'placeHolderPath' => '#webroot/upload/store/no-image.png', // if you want to get placeholder when image not exists, string will be processed by Yii::getAlias
],
and my Product model upload method is:
public function upload()
{
if ($this->validate()) {
$path = 'upload/store/' . $this->image->baseName . '.' . $this->image->extension;
$this->image->saveAs($path);
$this->attachImage($path);
#unlink($path);
return true;
} else {
return false;
}
}
Uploading images work. I mean, they fisically appear where they should. I load image
<?php $img = $model->getImage(); ?>
and in my DetailView widget instead of 'img':
[
'attribute' => 'image',
'value' => "<img src='{$img->getUrl()}'>",
'format' => 'html',
],
And what I get instead of a rendered image is:
image-by-item-and-alias?item=Product15&dirtyAlias=71273544a6-1.jpg
I have no idea where this "image-by-item-and-aliasitem=Product15&dirtyAlias?" part even comes from when it actually must be something like:
Products\Product15\71273544a6-1.jpg
and given format html parameter it must therefore render an image.
Can you please pinpoint me to the source of this error?

Laravel 5.4 file upload validation fails for python files

I'm trying to figure out what is wrong with my validation, but I'm not sure.
I have created a file upload that uploads the file to S3. Works fine except when I need to validate python files.
In my FileUploadController.php I have a store(FileStoreRequest $request) method that handles the upload. I added the $validatedData = $request->validate(); in it and it works.
I have also added the mimes.php in config folder with the following:
<?php
return [
'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed'),
'py' => array('text/plain', 'application/x-python' , 'application/octet-stream, application/x-python-code, text/x-python-script', 'text/x-python'),
];
And the rules() method inside my FileStoreRequest class is
public function rules()
{
return [
'preprocessor' => 'mimes:py',
];
}
Any time I try to upload the python file I get the error
The preprocessor must be a file of type: py.
When I remove the mimes check from the rules() it passes.
The rules work, because I tested it on another view for zip file upload.
Any ideas what could be wrong?
You can create custom validation like:
$input = $request->all();
if (isset($input["preprocessor"]) && !empty($input["preprocessor"])) {
$filesource = $input["preprocessor"];
$fileExtension = $filesource->getClientOriginalExtension();
$input["ext"] = $fileExtension;
}
$rules = array(
'ext' => 'nullable|in:py',
);

Validate File Type(Audio/Video) Using Laravel

I am using Laravel 5.2 for my project. I need some help to validate the file upload. Functionality is like below,
fileType - audio/video file
file.mp3, file.mp4, file.3gb
So while submitting(Rest Client through PostMan) the above fields i need to validate the file for "audio extension(.mp3, etc)" if fileType is"audio".
Same way i need to validate the file for video extension if fileType is "video(.mp4,.3gb)"
I tried to do that but there is an option to validate audio/video extension without checking the value of fileType as below,
'file' => 'mimes:mp3,mp4,3gb'
Can anyone guide me on this?
If you are using form requests, try with below code
public function rules()
{
$rules = [
'some_field' => 'required',
];
// if fileType is audio
if ($this->input('fileType') == 'audio') {
$rules['file'] = 'mimes:mp3,mp4';
}
//if fileType is video
if ($this->input('fileType') == 'video') {
$rules['file'] = 'mimes:mp4,3gp';
}
return $rules;
}
Change the field names and validation rules as per your requirement.
You can provide following validation rule for mp3
$validation_args = [
'file' => 'required|mimes:mpeg',
];

jQuery FileUpload syntax error

While implementing jQuery FileUpload in CodeIgniter everything seems to work, no javascript errors and the files get created in the default folders (chmod'ed 0777), but there are two issues.
1. I can't override the default options on the PHP handler provided by the package. Here is the Controller action I'm using to do so, none of the parameters passed are actually applied, if I dump the options within the UploadHandler I get the default options.
public function fileupload()
{
if ($this->input->is_ajax_request())
{
# load library
$this->load->library('UploadHandler');
# upload file
$upload_handler = new UploadHandler(array(
'upload_dir' => FCPATH.'upload/realty/'.$this->_user->id.'/',
'mkdir_mode' => 0777,
'accept_file_types' => '/\.(gif|jpe?g|png)$/i',
));
}
else
{
redirect('error/page_not_found');
}
}
2. The script is throwing a error when a file finishes uploading :
SyntaxError: Unexpected token {
Here is the response of an example request :
{"files":[{"name":"nebula-ngc-281.jpg","size":590295,"type":"image\/jpeg","url":"http:\/\/test.filipematias.info\/mercadoimobiliario\/admin\/files\/nebula-ngc-281.jpg","thumbnailUrl":"http:\/\/test.filipematias.info\/mercadoimobiliario\/admin\/files\/thumbnail\/nebula-ngc-281.jpg","deleteUrl":"http:\/\/test.filipematias.info\/mercadoimobiliario\/admin\/?file=nebula-ngc-281.jpg","deleteType":"DELETE"}]}{"files":[{"name":"nebula-ngc-281 (1).jpg","size":0,"type":"image\/jpeg","error":"File upload aborted","deleteUrl":"http:\/\/test.filipematias.info\/mercadoimobiliario\/admin\/?file=nebula-ngc-281%20%281%29.jpg","deleteType":"DELETE"}]}
According to this document Creating Libraries check how we can pass the param in library
so it would be:-
$options= array(
'upload_dir' => FCPATH.'upload/realty/'.$this->_user->id.'/',
'mkdir_mode' => 0777,
'accept_file_types' => '/\.(gif|jpe?g|png)$/i',
));
$this->load->library('UploadHandler',$options);

Categories