Laravel batch file upload - laravel-5

I have a csv file with the following structure:
id,title,sub_title,filename
1,Title 1, Sub Title 1,filename_1.mp3
2,Title 2, Sub Title 2,filename_2.mp3
3,Title 3, Sub Title 3,filename_3.mp3
(...)
I'm loading the CSV file inside a App\Console\Command (artisan command).
Assuming the files exist on the filesystem and the path is correct, for each csv line how can I upload the related file and validate it using the Validator class?
I'm using this code:
$validator = Validator::make(array('filename' => 'path_to_filename_x.mp3'), [
'filename' => 'required|file|audio:mp3,wav,ogg',
]);
if ($validator->fails()) {
echo '<pre>';
print_r($validator->errors());
echo '</pre>';
die();
}
I'm getting the error:
"The attribute must be a file."
Because I'm sending text instead of a resource (i suppose).
How can I upload these files without using a form using Laravel 5.6?
Thks!

Question: how can I upload the related file and validate it using the Validator class?
Validating the files:
Create a custom rule in laravel and there you can add logic like.
if(file_exists($path)){
//check for file type
}
Upload the files :
use $fcontent = file_get_contents($filepath) and file_put_contents($newfilepath, $fcontent)

Related

DOMPDF: How to customize the name of the single pdf, relating to a single client, with the information present in the object

I am trying to create the pdf, using the domPDF library, for each single client present in the table of my application. So far everything ok!
When I go to save the pdf I want the name of the pdf document to be saved as:
name_client_surname_client.pdf,
so if for example I have a client named Alex Haiold, the document must be saved as Alex_Haiold.pdf
To do this, since I am passing the single client in the controller, as shown below, I tried to write
return $pdf->download('client->surname client->name.pdf');
but it is saved as
client-_surname client-_name.pdf (then printing client-_surname client-_name).
Here my code:
public function generatePDF(Client $client)
{
$data = [
'title' => 'Welcome to LaravelTuts.com',
'date' => date('m/d/Y'),
'client' => $client
];
//dd($data);
$pdf = PDF::loadView('client.clientPDF', $data);
return $pdf->download('client->surname client->name.pdf');
}
Can anyone kindly help me?
$pdf = PDF::loadView('client.clientPDF', $data);
return $pdf->download($client->surname . ' ' . client->name . '.pdf');
On the first line, we are just making a view file. The file is resources/views/client.clientPDF.blade.php and we are feeding data to the view file by passing the variable $data to it.
After making the view, our next step is to download the pdf file. For doing this, we need to call the download method of the instance.
On the first parameter, we are passing the filename with extension(pdf).

Laravel 6 Unit Test file upload unable to find file at path

I'm writing a unit test in laravel 6 to test file uploading. I have a form that is creating a group and there is a file upload for covers.
My unit test is as follows
$this->WithoutExceptionHandling();
//login as admin
$admin = $this->signInAsAdmin();
Storage::persistentFake('public');
$attributes = [
'group_name' => $this->faker->name,
'group_description' => $this->faker->paragraph,
'group_privacy' => '0',
'group_cover' => $file = UploadedFile::fake()->image('random.jpg')
];
//create new group
$response = $this->post('/admin/groups', $attributes);
unset($attributes['group_cover']);
Storage::disk('public')->assertExists($file);
//check the data exists in database
$this->assertDatabaseHas('groups', $attributes);
//how is the uploaded file written to database
//check the data exists in database
$this->assertDatabaseHas('media', ['file_name' => $file]);
//make sure the title appears on the group list
$this->get('/admin/groups')->assertSee($attributes['group_name']);
The error I am getting is:
Unable to find a file at path [php624B.tmp].
Failed asserting that false is true.
I have also set in my php.ini file the upload_tmp_dir
upload_tmp_dir = C:\path_to_laravel_app\storage\tmp\uploads
What seems to be happening is that the faker library is not creating a temporary image. Doesn't matter what folder I set the tmp location to.
Any help would be appreciated
Danny

Laravel : To rename an uploaded file automatically

I am allowing users to upload any kind of file on my page, but there might be a clash in names of files. So, I want to rename the file automatically, so that anytime any file gets uploaded, in the database and in the folder after upload, the name of the file gets changed also when other user downloads the same file, renamed file will get downloaded.
I tried:
if (Input::hasFile('file')){
echo "Uploaded</br>";
$file = Input::file('file');
$file ->move('uploads');
$fileName = Input::get('rename_to');
}
But, the name gets changed to something like:
php5DEB.php
phpCFEC.php
What can I do to maintain the file in the same type and format and just change its name?
I also want to know how can I show the recently uploaded file on the page and make other users download it??
For unique file Name saving
In 5.3 (best for me because use md5_file hashname in Illuminate\Http\UploadedFile):
public function saveFile(Request $request) {
$file = $request->file('your_input_name')->store('your_path','your_disk');
}
In 5.4 (use not unique Str::random(40) hashname in Illuminate\Http\UploadedFile). I Use this code to ensure unique name:
public function saveFile(Request $request) {
$md5Name = md5_file($request->file('your_input_name')->getRealPath());
$guessExtension = $request->file('your_input_name')->guessExtension();
$file = $request->file('your_input_name')->storeAs('your_path', $md5Name.'.'.$guessExtension ,'your_disk');
}
Use this one
$file->move($destinationPath, $fileName);
You can use php core function rename(oldname,newName) http://php.net/manual/en/function.rename.php
Find this tutorial helpful.
file uploads 101
Everything you need to know about file upload is there.
-- Edit --
I modified my answer as below after valuable input from #cpburnz and #Moinuddin Quadri. Thanks guys.
First your storage driver should look like this in /your-app/config/filesystems.php
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'), // hence /your-app/storage/app/public
'visibility' => 'public',
],
You can use other file drivers like s3 but for my example I'm working on local driver.
In your Controller you do the following.
$file = request()->file('file'); // Get the file from request
$yourModel->create([
'file' => $file->store('my_files', 'public'),
]);
Your file get uploaded to /your-app/storage/app/public/my_files/ and you can access the uploaded file like
asset('storage/'.$yourModel->image)
Make sure you do
php artisan storage:link
to generate a simlink in your /your-app/public/ that points to /your-app/storage/app/public so you could access your files publicly. More info on filesystem - the public disk.
By this approach you could persists the same file name as that is uploaded. And the great thing is Laravel generates an unique name for the file so there could be no duplicates.
To answer the second part of your question that is to show recently uploaded files, as you persist a reference for the file in the database, you could access them by your database record and make it ->orderBy('id', 'DESC');. You could use whatever your logic is and order by descending order.
You can rename your uploaded file as you want . you can use either move or storeAs method with appropiate param.
$destinationPath = 'uploads';
$file = $request->file('product_image');
foreach($file as $singleFile){
$original_name = strtolower(trim($singleFile->getClientOriginalName()));
$file_name = time().rand(100,999).$original_name;
// use one of following
// $singleFile->move($destinationPath,$file_name); public folder
// $singleFile->storeAs('product',$file_name); storage folder
$fileArray[] = $file_name;
}
print_r($fileArray);
correct usage.
$fileName = Input::get('rename_to');
Input::file('photo')->move($destinationPath, $fileName);
at the top after namespace
use Storage;
Just do something like this ....
// read files
$excel = $request->file('file');
// rename file
$excelName = time().$excel->getClientOriginalName();
// rename to anything
$excelName = substr($excelName, strpos($excelName, '.c'));
$excelName = 'Catss_NSE_'.date("M_D_Y_h:i_a_").$excelName;
$excel->move(public_path('equities'),$excelName);
This guy collect the extension only:
$excelName = substr($excelName, strpos($excelName, '.c'));
This guy rename its:
$excelName = 'Catss_NSE_'.date("M_D_Y_h:i_a_").$excelName;

Laravel 5.3 : txt or csv file throws an exception (getimagesize(): Read error!)

I have used following code to validate the image file. I want to upload image file only.
However when user upload the txt or csv file it throws an exception (getimagesize(): Read error!).
Below is the validation code.
$rules = [ 'mobile_image'=>'mimes:jpg,jpeg,gif,png|dimensions:width=710,height=400', 'web_image'=>'mimes:jpg,jpeg,gif,png|dimensions:width=1182,height=300', ];
$validator = Validator::make($validateData, $rules);
if($validator->fails()){
}
I have checked in Laravel validation file.
They have used getimagesize for all file uploads.
Is there any other validation rule for txt or csv file ?
Is there any way to overwrite the validator class with custom rules ?
You're using dimensions rule, so Laravel executes getimagesize() to get image dimensions. If you want to upload text files, change mimes and remove dimensions rule.
https://laravel.com/docs/5.3/validation
Try below example code:
$validator = Validator::make($validateData,[
'mobile_image'=>'mimes:jpg,jpeg,gif,png|dimensions:width=710,height=400',
'web_image'=>'mimes:jpg,jpeg,gif,png|dimensions:width=1182,height=300',
])->validate();
UPDATE
You can try below snippet at own your risk:
$image_size = #getimagesize( $image_url );
if($image_size === false){
//Handle error message
}
else {
$validator = Validator::make($validateData,[
'mobile_image'=>'mimes:jpg,jpeg,gif,png|dimensions:width=710,height=400',
'web_image'=>'mimes:jpg,jpeg,gif,png|dimensions:width=1182,height=300',
])->validate();
}
Hope this will solved your issue.

Laravel validation pdf mime

I have tried below mime types for validating PDF files.but none of them doesnt pass the validation .
$rules = [
....
"file" => "required|mimes:application/pdf, application/x-pdf,application/acrobat, applications/vnd.pdf, text/pdf, text/x-pdf|max:10000"
....
]
Just add file extension
$rules = [
"file" => "required|mimes:pdf|max:10000"
]
From laravel Docs:
Even though you only need to specify the extensions, this rule
actually validates against the MIME type of the file by reading the
file's contents and guessing its MIME type.
Update:
Starting from Laravel 5.2, you could validate file upload against full MIME type, new validation rule called: mimetypes.
$rules = [
"file" => "required|mimetypes:application/pdf|max:10000"
]

Resources