I have a DocumentsController and it stores files.
When I am uploading multiple files, they are uploaded to store method and after that I call a method that manage the path, filename.
So when I pass the data array as parameter to that method(manageFileName), this array somehow is changed, his values are null.
class DocumentsController
{
public function store(Request $request)
{
$file = $request->file('file');
$data = [
"extension" => $file->getClientOriginalExtension(),
"name" => pathinfo($file->getClientOriginalName())['filename'],
"folder" => $request->folder,
"visible" => "private",
"mime_type" => $file->getClientMimeType()
];
Logger($data);
/*
$data = [
"extension" => 'pdf',
"name" => 'pdf sample',
"folder" => 'folder',
"visible" => "private",
"mime_type" => 'application/pdf'
];
*/
$this->manageFileName($data);
// Upload file to S3...
}
public function manageFileName($data)
{
Logger($data);
/*
$data = [
"extension" => null, // why?
"name" => null, // why?
"folder" => 'folder',
"visible" => "private",
"mime_type" => 'application/pdf'
];
*/
}
}
The problem is that this behavior is not happening to all uploaded files, from 20 only 2 or 3 files are not uploaded properly.
I can't understand what is happening.
P.S. I am using Dropzone.js to upload files in Laravel
I am uploading 20 pdf files at a time(just the same file copied).
Laravel 5.8, Php 7.4
I checked php.ini configuration:
max_file_uploads = 30,
post_max_size = 50M,
post_max_size = 50M,
max_execution_time = 120
Related
I'm building an Restful API using Laravel 5 and MongoDB.
I'm saving avatar image for users.
It's working fine but I'm trying to create a Folder for every User. For example: "app/players/images/USERID"
I've tried to do something like this in different ways but I always get Driver [] is not supported.
\Storage::disk('players'.$user->id)->put($image_name, \File::get($image));
UploadImage:
public function uploadImage(Request $request)
{
$token = $request->header('Authorization');
$jwtAuth = new \JwtAuth();
$user = $jwtAuth->checkToken($token, true);
$image = $request->file('file0');
$validate = \Validator::make($request->all(), [
'file0' => 'required|image|mimes:jpg,jpeg,png'
]);
if ( !$image || $validate->fails() )
{
$data = array(
'code' => 400,
'status' => 'error',
'message' => 'Image uploading error-'
);
}
else
{
$image_name = time().$image->getClientOriginalName();
\Storage::disk('players')->put($image_name, \File::get($image));
$user_update = User::where('_id', $user->id)->update(['imagen' => $image_name]);
$data = array(
'code' => 200,
'status' => 'success',
'user' => $user->id,
'imagen' => $image_name
);
}
return response()->json($data, $data['code']);
}
filesystems.php:
'players' => [
'driver' => 'local',
'root' => storage_path('app/players/images/'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
I expect the user avatar image saves on User ID folder.
The disk call, tells Laravel which filesystem to use, let's assume you have an user with Id one, with your code it will access the filesystem playeers1.
What usually is done is to put these files in folder structures for the different users, so instead you could do. This will put your image file, in the folder 1.
\Storage::disk('players')->put($user->id . '/' . $image_name, \File::get($image));
I had a similar problem, check if the lines can change what you want to achieve.
\Storage::disk('players')->put("{$user->id}/{$image_name}", \File::get($image));
I relied on the laravel guide: File Storage - File Uploads
I hope it helps you. A cordial greeting.
I want to test my file upload action .
I checked file type validation on that action . It is working from browser interaction , but I tried with phpunit it fail on validation .
I validate for accepting jpg or jpeg file only .
Here is my unit code
public function testWIthJpgImage()
{
$_FILES = [
'front_image' => [
'name' => 'uitest',
'type' => 'image/jpeg',
'size'=> filesize(storage_path('data/uitest.jpg')),
'error' => 0,
'tmp_name' => storage_path('data/uitest.jpg')
]
];
$response = $this->call('POST', '/api/test',[],[],$_FILES);
$data = json_decode($response->getContent());
dd($data); // here validation fail always
$this->assertEquals(200, $response->getStatusCode());
}
How can I test with file upload correctly on phpunit ? My laravel version 5.0 (old version) Laravel UploadFile is not available
You can use Illuminate\Http\UploadedFile Facade for this.
Here is an example of one of my projects where I upload & store a file. It also has a files table & model.
/** #test */
function create_new_file ()
{
$payload = [
'file' => UploadedFile::fake()->image('avatar.jpg')
];
// act
$response = $this->post("/api/files", $payload);
// test
$response->assertStatus(201);
Storage::disk('local')->assertExists(File::first()->path);
}
Don't forget
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
In addition you can use
Storage::fake('local');
in order to not persist the uploaded files (if you are using the Storage as I do). This is very handy so your tests don't create a bunch of files in your uploads folder.
I think my problem is sovled but it is so weired to do that :) I set $_FILES and Symfony UploadedFile both :<
$_FILES = [
'front_image' => [
'name' => 'uitest',
'type' => 'image/jpeg',
'size'=> filesize(storage_path('data/uitest.jpg')),
'error' => 0,
'tmp_name' => storage_path('data/uitest.jpg'),
'test' => true
]
];
$uploadedFile = new Symfony\Component\HttpFoundation\File\UploadedFile(
storage_path('data/uitest.jpg'),
'uitest.jpg',
'image/jpeg',
filesize(storage_path('data/uitest.jpg')),
0,
true
);
$response = $this->call('POST', '/api/test',[],[],['front_image' => $uploadedFile]);
The client sends file to server. It look like this:
array:1 [▼
"file" => array:5 [▼
"name" => "MMM1(one row).TXT"
"type" => "application/octet-stream"
"tmp_name" => "/tmp/phpaKnJzE"
"error" => 0
"size" => 1365
]
]
If to make the following operation:
dd($_FILES);
I tried to handle thi file like:
foreach ($_FILES["file"] as $file) {
$file->store('tests');
$file->getClientOriginalName();
}
But it does not work for me.
It involke an error:
Call to a member function getClientOriginalName() on array
$this->file->getClientOriginalName()
You need to set below code in your post action
$photo = $request->file('img');
$path = storage_path('app/public/avatars/');
$photo->move($path, $request->file('img')->getClientOriginalName());
If You're uploading an image then you can also use intervention/image package.
Using this, you'll also be able to do basic image manipulation.
In you controller post action do the following:
use Intervention\Image\Facades\Image;
if($request->hasFile('image')){
$image = \Image::make( $request->file( 'image' ) );
$image->save( storage_path('images/'. $request->file('image')->getClientOriginalName()));
}
Currently, i try to test a file upload with PHPUnit for Laravel. After some searches, i found a first solution :
$file = new \Symfony\Component\HttpFoundation\File\UploadedFile(
app_path() . '/tests/Files/default.png', 'default.png');
$response = $this->call('POST', 'students',
[
'firstname' => 'firstname',
'lastname' => 'lastname',
'promotion' => '2016',
'isCoop' => 1
],
[
'avatar' => [$file]
]
);
It works, but it failed when I push this code on Travis, and i'm not sure it's very clean to do that...
You can see my test failed here.
Thank's you.
You should use virtual file system for your tests. Check mocking file system in the phpunit documentation
You can use this class \Illuminate\Http\UploadedFile to test your upload file as you can see on this answer
mine working using test case like this :
public function testUploadLanscapseValid()
{
$uploadFile= new \Illuminate\Http\UploadedFile(
base_path()."/resources/fakerFile/mobileScreen/bg_land.jpg", //path image
'example.jpg',
'image/jpeg',
filesize(base_path()."/resources/fakerFile/mobileScreen/bg_land.jpg"), // file size
null,
true
);
//checking UI validation response
$this->visit('/mobile-screen')
->attach($uploadFile, 'image-landscape')
->press('upload-image-landscapse')
->seePageIs('/mobile-screen')
->see('Mobile screen successfully uploaded.');
//checking database is inserted
$this->seeInDatabase('mobile_screen',['link_lanscapse'=>'bg_land.jpg']);
//checking file exist
if(file_exists(base_path() . '/public/mobileScreen/bg_land.jpg')){
$this->assertTrue(true);
}else{
$this->assertTrue(false);
}
}
when you are testing upload using file please use \Illuminate\Http\UploadedFile instead of \Symfony\Component\HttpFoundation\File\UploadedFile
UPDATE
when seeing your test I think it is incomplete you can get the response of your test like mine here :
public function testUploadFunctionalTest()
{
$uploadedFile= new \Illuminate\Http\UploadedFile(
base_path()."/resources/fakerFile/mobileScreen/bg_land.jpg", //path image
'example.jpg',
'image/jpeg',
filesize(base_path()."/resources/fakerFile/mobileScreen/bg_land.jpg"), // file size
null,
true
);
// you can use this or
$parameters = [];
$response = $this->action(
'POST',
'AdminWeb\MobileScreenController#store',
[],
$parameters,
[],
['image' => $uploadedFile]
);
// you can use this choose One !
$response =$this->call('POST', 'mobile-screen#store',
[
'firstname' => 'firstname',
'lastname' => 'lastname',
'promotion' => '2016',
'isCoop' => 1
],
[
'image' => [$uploadedFile]
]);
$result = json_decode($response->content()); // you can dump or whatever you want with the test
var_dump($result->your_response);
$this->assertEquals($result->your_response,'expected output');
}
Note : I'm using laravel 5.2, and this test will write the file on your disk
$file = new \Symfony\Component\HttpFoundation\File\UploadedFile(
app_path() . '/tests/Files/default.png', 'default.png', "image/jpeg", null, null, true);
I am using jQuery-File-Upload (basic version) to upload file on server using jQuery. My original image file is uploading successfully but it is not uploading the thumbnail file into thumbnail folder.
I also set the write permission on this folder. But same code on my localhost is working fine, after uploading on server it is not creating thumbnail.
jQuery.each(data.result.files, function (index, file) {
alert(file.thumbnailUrl);
This alert message is showing blank on server. but on localhost showing uploaded path perfectly.
My UploadHandler.php __construct() Code is :-
function __construct($options = null, $initialize = true, $error_messages = null) {
$this->options = array(
'script_url' => $this->get_full_url().'/',
'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')).'../../../../../../temp/',
'upload_url' => $this->get_full_url().'../../../../../../temp/',
'user_dirs' => false,
'mkdir_mode' => 0755,
'param_name' => 'files',
// Set the following option to 'POST', if your server does not support
// DELETE requests. This is a parameter sent to the client:
'delete_type' => 'DELETE',
'access_control_allow_origin' => '*',
'access_control_allow_credentials' => false,
'access_control_allow_methods' => array(
'OPTIONS',
'HEAD',
'GET',
'POST',
'PUT',
'PATCH',
'DELETE'
),
'access_control_allow_headers' => array(
'Content-Type',
'Content-Range',
'Content-Disposition'
),
// Enable to provide file downloads via GET requests to the PHP script:
// 1. Set to 1 to download files via readfile method through PHP
// 2. Set to 2 to send a X-Sendfile header for lighttpd/Apache
// 3. Set to 3 to send a X-Accel-Redirect header for nginx
// If set to 2 or 3, adjust the upload_url option to the base path of
// the redirect parameter, e.g. '/files/'.
'download_via_php' => false,
// Read files in chunks to avoid memory limits when download_via_php
// is enabled, set to 0 to disable chunked reading of files:
'readfile_chunk_size' => 10 * 1024 * 1024, // 10 MiB
// Defines which files can be displayed inline when downloaded:
'inline_file_types' => '/\.(gif|jpe?g|png)$/i',
// Defines which files (based on their names) are accepted for upload:
'accept_file_types' => '/.+$/i',
// The php.ini settings upload_max_filesize and post_max_size
// take precedence over the following max_file_size setting:
'max_file_size' => null,
'min_file_size' => 1,
// The maximum number of files for the upload directory:
'max_number_of_files' => null,
// Image resolution restrictions:
'max_width' => null,
'max_height' => null,
'min_width' => 1,
'min_height' => 1,
// Set the following option to false to enable resumable uploads:
'discard_aborted_uploads' => true,
// Set to false to disable rotating images based on EXIF meta data:
'orient_image' => true,
'image_versions' => array(
// Uncomment the following version to restrict the size of
// uploaded images:
/*
'' => array(
'max_width' => 1920,
'max_height' => 1200,
'jpeg_quality' => 95
),
*/
// Uncomment the following to create medium sized images:
'medium' => array(
'max_width' => 400,
'max_height' => 400,
'jpeg_quality' => 80
),
'thumbnail' => array(
// Uncomment the following to use a defined directory for the thumbnails
// instead of a subdirectory based on the version identifier.
// Make sure that this directory doesn't allow execution of files if you
// don't pose any restrictions on the type of uploaded files, e.g. by
// copying the .htaccess file from the files directory for Apache:
//'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')).'../../../../../../thumbnail/',
//'upload_url' => $this->get_full_url().'../../../../../../thumbnail/',
// Uncomment the following to force the max
// dimensions and e.g. create square thumbnails:
//'crop' => true,
'max_width' => 80,
'max_height' => 80
)
)
);
if ($options) {
$this->options = array_merge($this->options, $options);
}
if ($error_messages) {
$this->error_messages = array_merge($this->error_messages, $error_messages);
}
if ($initialize) {
$this->initialize();
}
}