Laravel 5.4 file upload validation fails for python files - php

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

Related

Laravel get path of saved file from upload

I have a laravel upload for file (along with other data that is passed to the database) Everything works. But I just can't figure out how to save the path of the file that is saved.
Here is my controller function:
public function store(Request $request)
{
request()->validate([
'name' => 'required',
'logo' => 'nullable',
'original_filename' => 'nullable',
]);
//This is where the file uploads?
if ($request->hasFile('logo')) {
$request->file('logo')->store('carrier_logo');
$request->merge([
'logo' => '',//TODO: get file location
'original_filename' => $request->file('logo')->getClientOriginalName(),
]);
}
Carrier::create($request->all());
return redirect()->route('carriers.index')->with('toast', 'Carrier created successfully.');
}
The thing I want to achieve:
I want logo to fill with something like carrier_logo/ZbCG0lnDkUiN690KEFpLrNcn2exPTB8mUdFDwAKN.png
The thing that happened every time I tried to fix it was that it placed the temp path in the database. Which ended up being something in the PHP install directory.
Just assign result to variable:
$path = $request->file('logo')->store('carrier_logo');
According to docs
Then you can do with $path variable whatever you want.
just assign the value like this.
$location=base_path('img/'.$filename);
and save it in db.
You could do this:
For FileName
$fileName = $request->file('test')->getClientOriginalName();
OR
$fileName = $request->user()->id.'.'.$request->file('logo')->getClientOriginalExtension();
$imageDirectory = 'logo_images';
$path = $request->file('logo')->storeAs($imageDirectory, $fileName);
dd($path);

YII2 XML file upload wont validate

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.

Laravel 5 form validation on failure keep uploaded data

I am working on a Laravel project and I have routes set up for a form page where it shows the form on GET and it analyzes it on POST:
Route::get('/update-data', [
'as' => 'user.settings.edit-data',
'uses' => 'UserController#editData',
]);
Route::post('/update-data', [
'as' => 'user.settings.update-data',
'uses' => 'UserController#updateData',
]);
In this form I ask the user to fill out two fields with text and I also ask them to upload two files. Both files must be jpeg, png or pdf. In the controller I have:
$this->validate($request,
[
'phone' => 'required',
'email' => 'required|email',
'file1' => 'required|mimes:jpeg,png,pdf',
'file2' => 'required|mimes:jpeg,png,pdf',
]);
If that succeeds, then the code will continue executing and save everything, but if not it will redirect the user back to the form. Is there a way to still have the file chosen so that the user doesn't need to look for it again?
I would suggest validating using server side code (not javascript, although both can be nice from the user perspective (but obviously don't rely on the js validation).
I usually validate like this in Laravel (I'm not the biggest fan of their built in validator). Then after the validation you can use Laravel's File class to get the file name and re-post the data to the view:
$file = Request::file('file1');
$accepts = ['jpeg', 'png', 'pdf'];
$ext = $file->getClientOriginalExtension();
$filename = $file->getClientOriginalName();
if( !in_array($ext, $accepts) )
{
return view('your-view')->withErrors('Invalid File Format');
}
else
{
//File has one of the correct extensions,
//return the filename to the view so it can be
//re-displayed in the input
return view('your-view', ['filename' => $filename]);
}
Or if you prefer the non-facade way:
$file = $request->file('file1');
$accepts = ['jpeg', 'png', 'pdf'];
$ext = $file->getClientOriginalExtension();
$filename = $file->getClientOriginalName();
if( !in_array($ext, $accepts) )
{
return view('your-view')->withErrors('Invalid File Format');
}
else
{
//File has one of the correct extensions,
//return the filename to the view so it can be
//re-displayed in the input
return view('your-view', ['filename' => $filename]);
}
This takes advantage of Laravels File class.

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',
];

Yii: How to make Dropzone Extension work?

I'm trying to add Dropzone Extension to my application in Yii, which allows asynchronous file uploading. http://www.yiiframework.com/extension/yii-dropzone/
The first thing i did was putting the downloaded folder called "dropzone" into my extensions folder "C:\xampp\htdocs\site\protected\extensions".
And here is my code for the action in the controller (MainController.php)
public function actionUpload()
{
$test = rand(100000, 999999); //TEST
var_dump($test);
$model = new UploadFile;
if(isset($_FILES['images'])){
$model->images = CUploadedFile::getInstancesByName('images');
$path = Yii::getPathOfAlias('webroot').'/uploads/';
//Save the images
foreach($model->images as $image)
{
$image->saveAs($path);
}
}
$this->render('upload', array('model' => $model));
}
the view (upload.php)
<?php
$this->widget('ext.dropzone.EDropzone', array(
'model' => $model,
'attribute' => 'images',
'url' => $this->createUrl('file/upload'),
'mimeTypes' => array('image/jpeg', 'image/png'),
'options' => array(),
));
?>
and the model (UploadFile.php)
<?php
class UploadFile extends CFormModel
{
public $images;
public function rules(){
return array
(
array(
"images",
'file',
'types' => 'jpg,gif,png',
),
);
}
}
When I run it I can see the Dropzone interface and I can add images dragging them or selection them from the file explorer.
It appears their respective progress bar and a success mark, but nothing appear in the directory of uploads, and any error is shown neither in the IDE (Netbeans) nor in the Chrome console.
I did some print tests and I realize that the code inside the 'actionUpload' is being executed only the first time (when it draws the view), but when its called from the dropzone widget it do nothing.
I'd really appreciate if you have a solution for this. I'd love if someone could give me a simple working example of this extension. Thanks.
As I understand, dropzone uploads files one by one, not all together. So $model->images holds only one image object. And foreach cycle fails.

Categories