Laravel 5 Image Upload - php

I am trying to upload Images with a form. I have 5 fields in total and don't want to make all fields required. However there is an exception if I leave one of the fields blank. But everything works fine when I upload all 5 images.
I have no rules in my $rules array. Something goes wrong with isValid().
Error:
FatalErrorException in ProfilesController.php line 191:
Call to a member function getClientOriginalExtension() on a non-object.
Can somebody point me into the right direction please.
My Controller:
public function update(ProfileRequest $request, $id)
{
$profile = Profile::findOrFail($id);
$request->merge([ 'wifi' => $request->has('wifi') ? true : false,
'takeaway'=> $request->has('takeaway') ? true : false,
'ec'=> $request->has('ec') ? true : false,
'creditcard'=> $request->has('creditcard') ? true : false,
'cash'=> $request->has('cash') ? true : false,
'wheelchair'=> $request->has('wheelchair') ? true : false,
'outdoor'=> $request->has('outdoor') ? true : false,
'tv'=> $request->has('tv') ? true : false,
'service'=> $request->has('service') ? true : false,
'smoking'=> $request->has('smoking') ? true : false,
'reservation'=> $request->has('reservation') ? true : false,
'brunch'=> $request->has('brunch') ? true : false,
]);
// getting all of the post data
$file = array('image_profilehero' => Input::file('image_profilehero'),
'image_avatar' => Input::file('image_avatar'),
'pdf' => Input::file('pdf'),
'restaurantscene1' => Input::file('restaurantscene1'),
'restaurantscene2' => Input::file('restaurantscene2')
);
// setting up rules
$rules = array(//'image_profilehero' => 'required',
//'image_avatar' => 'required'
); //mimes:jpeg,bmp,png and for max size max:10000
// doing the validation, passing post data, rules and the messages
$validator = Validator::make($file, $rules);
if ($validator->fails()) {
// send back to the page with the input data and errors
return Redirect::to('backend/profile')->withInput()->withErrors($validator);
}
else {
// checking file is valid.
if (Input::file('image_profilehero') or Input::file('image_avatar')->isValid() or Input::file('pdf')->isValid() or Input::file('restaurantscene1')->isValid() or Input::file('restaurantscene2')->isValid()) {
$destinationPathAvatar = 'uploads/avatar'; // upload path Avatar
$destinationPathProfileHero = 'uploads/profilehero'; // upload path ProfileHero
$destinationPathPdf = 'uploads/speisekarten'; // upload path ProfileHero
//Restaurant Scene Bilder
$destinationPathRestaurantScene1 = 'uploads/restaurantscene'; // upload path RestaurantScene
$destinationPathRestaurantScene2 = 'uploads/restaurantscene'; // upload path RestaurantScene
$extensionAvatar = Input::file('image_avatar')->getClientOriginalExtension(); // getting image extension
$extensionProfileHero = Input::file('image_profilehero')->getClientOriginalExtension(); // getting image extension
$extensionPdf = Input::file('pdf')->getClientOriginalExtension(); // getting image extension
$extensionRestaurantScene1 = Input::file('restaurantscene1')->getClientOriginalExtension(); // getting image extension
$extensionRestaurantScene2 = Input::file('restaurantscene2')->getClientOriginalExtension(); // getting image extension
//$fileName = rand(11111,99999).'.'.$extension; // renameing image
$fileNameAvatar = '/avatar/avatar_'.Auth::user()->id.'.'.$extensionAvatar;
$fileNameProfieHero = '/profilehero/profilehero_'.Auth::user()->id.'.'.$extensionProfileHero;
$fileNamePdf = '/speisekarten/pdf_'.Auth::user()->id.'.'.$extensionPdf;
$fileNameRestaurantScene1 = '/restaurantscene/scene1_'.Auth::user()->id.'.'.$extensionRestaurantScene1;
$fileNameRestaurantScene2 = '/restaurantscene/scene2_'.Auth::user()->id.'.'.$extensionRestaurantScene2;
Input::file('image_profilehero')->move($destinationPathProfileHero, $fileNameProfieHero); // uploading file to given path
Input::file('image_avatar')->move($destinationPathAvatar, $fileNameAvatar); // uploading file to given path
Input::file('pdf')->move($destinationPathPdf, $fileNamePdf); // uploading file to given path
Input::file('restaurantscene1')->move($destinationPathRestaurantScene1, $fileNameRestaurantScene1); // uploading file to given path
Input::file('restaurantscene2')->move($destinationPathRestaurantScene2, $fileNameRestaurantScene2); // uploading file to given path
// sending back with message
return redirect('backend/profile')->with([
'flash_message_important' => false,
'flash_message' => 'All done'
]);
}
else {
// sending back with error message.
return redirect('backend/profile')->with([
'flash_message_important' => false,
'flash_message' => 'Upps. Something's wrong.'
]);
}
}
//return redirect('backend/profile');
$profile->update($request->all());
}

Your code is not accounting for an empty or missing file, it's just assuming there's a file there and attempting to move it. So you end up calling methods on a non-object, likely null. You just need to do a bit of extra work to ensure you actually have objects before you call methods on them, like this:
$pdf = Input::file('pdf');
if ($pdf) {
$extension = $pdf->getClientOriginalExtension();
$pdf->move($destinationPathPdf, $fileNamePdf);
}
This way, if there's no PDF file, the if statement will be false and will skip calling methods on it, so you avoid that kind of error. It's generally good practice to do this.

Related

How to open the PDF generated in new tab

I have a Leave application project that generates a PDF file.
this is the code that generates the pdf after I click submit.
$id = DB::table('leave')->where('user_id', auth()->user()->id)->max('id');
$data = leave::where('id', $id)->select('*')->get();
$filename = auth()->user()->name." - S - ". "LEAVE - ".$randomString->randomString(8)."-".$request->filing_date.".pdf";
$path = storage_path('app/leave_file/'.$filename);
PDF::loadView('pdf_views.leave_pdf', $data[0])->setPaper('legal')->save($path);
if(file_exists($path)){
DB::table('leave_files')->insert([
'filename' => $filename,
'leave_id' => DB::table('leave')->where('user_id', auth()->user()->id)->max('id'),
]);
}
return redirect()->route('leave')->with('success', "success");
I wonder if I can make the newly generated pdf open in the new tab after I click submit on my leave application. thank you to anyone who can help
According to the Laravel docs this is what you need: https://laravel.com/docs/9.x/responses#file-responses
File Responses
The file method may be used to display a file, such as an image or PDF, directly in the user's browser instead of initiating a download. This method accepts the path to the file as its first argument and an array of headers as its second argument:
return response()->file($pathToFile);
return response()->file($pathToFile, $headers);
Use the Cache Facade, to store the generated pdf temporary.
$uuid = Str::uuid();
return response()->stream(function () use ($uuid) {
echo Cache::remember($uuid, 300, function() {
return 'genertated pdf content'
});
}, 200, [
'Content-Type' => 'application/pdf',
'Content-Disposition' => sprintf('attachment; filename=%s;', $uuid),
]);
Create a route to access to cached file. Name the route.
Now you can open it in a new tab from you frontend e.g. Generate the route with route('routename', ['param' => 123]) and pass it to your FE with a REST endpoint for example.
window.open(url,'_blank');

Maps image download error, routes are not coming in the image

I created a function in PHP that downloads a map created in google maps, I am able to download, however, the route is not coming when I am saving.
How the picture is coming:
How it should come:
Code:
function download_remote_file_with_curl($file_url, $save_to) {
$arrContextOptions = array(
"ssl" => array(
"verify_peer" => false,
"verify_peer_name" => false,
),
);
$response = file_get_contents($file_url, false, stream_context_create($arrContextOptions));
//echo $response;
//file_put_contents($save_to, $response);
$downloaded_file = fopen($save_to, 'wb');
fwrite($downloaded_file, $response);
fclose($downloaded_file);
}
$urlDownload = "https://maps.googleapis.com/maps/api/staticmap?size=1000x1000&maptype=roadmap&path=enc:zklaAbqcyJzCmF~#b#fBdAzCiEnKyQlFpCnMdH~_#nU~JlFlCNrw#oL~IcApEZxd#nQpgBhq#tRtStgA``Aty#`o#ll#pa#tNhFzMvJfG~D|Y~Hxd#rMll#`Rtb#jLjNzExWtFz`#bJvM|ItG`LdF|V`GvD|CL|JiBv]aGld#cHrk#cLdU_Fpb#wGdMg#vaAqAti#g#z_#Cj~A{#raAfDlp#xAfYa#tyAuDtVEbTdApO`#rGk#dP`#vgEo#baCuA`|AaArHGIzAwCtHqDlNf#rl#lA~bAnAphAMj`#hBlj#\hd#s#tL\pHnCff#~A`|#lMnmEnBbKrFbDn`#jP~RtQ~k#hVhNtGb#xFgPheAsAnOuIlaBpj#|qCtDzGb`A~`AzDvGd#vI{Af_#x#~GxItHzLvGp\fLxc#t\pe#d`#h|AnmA`WvQnEDnF}Bd\uUjGeB~Gb#nEvB~KnMri#ni#fjCbfCpmArkAv|#pz#bjAjhApcEt}Ddx#pv#r_#lZzyB|hBtoHneGzZvVh|#xq#fb#jZh^fZjD~E`FlOzMbc#|L|`#hQrS~H`MhQ~w#hEdzB~B~hAbAbk#Ux^kNx~BeGriAaCbe#|#zSt#`ChDnBnZlAlFtCl`#`AzMpBpRvJlKvFbKlLxd#pcAdk#~oAjbAbiAnPxLfq#b^ndDpkBbdDfjBbqAdt#hFjAtNhCfMbD|g#tYhxDfxBrqFx~C|CpCzA|EE~E}i#raDsOb}#uO~{#{f#zvCr#hG~CdDf`Bly#hL|Lt#bClD|Brx#naAvAnAzb#lg#zj#veDjMbI|rBhdAlJzFdAjCbBpgBpMlsQdIhhO]p^?hb#z#dsAp#jo#l#pWffDp`FzyB~eDxdEhlGpNrSvv#hn#duEvuDnsJp~HtpLvvJ~bBtvAjw#hp#hDnFnHvpBlSh}FrFd_BvAno#tu#buTtPxwEnXvhJbRddGbQ~nGlNjqFlJv~BvC~rAdFppBvNhvEhShsGw#nQ}i#htBsq#lgCcJd]}BjPkG|y#gPptBu]byE_H~gArB`EfG|FxXnYfv#nv#nWhX`RjRjHj`#bfBdgKlCrKzGhQp`#lbAtdBnjEr_#z`A`~#n}Bth#fuAdpDzdJ|W`o#`ClAxIj#beA~A~p#bAx|F~I`lEzGvwAbCdMx#neDjlAbp#hUrE}#prB_qCzBaAjJAxOKhWfAfP?tm#}Q~{Bkr#r{EeyAxPoApfB~WzK|AHTdBDrO}A~RmBrXsCzZuA~NJx#bD|#dAfX`#{#nG&markers=color:green|label:A|-10.8819552,-61.95483539999998&markers=color:red|label:B|-12.457280801085,-64.2310285267651&key=yourkey";
download_remote_file_with_curl($urlDownload, realpath('C:/test') . '/' . 'test' . '.jpg');
?>
Thank you!
I don't know if what I'm about to write makes sense, but the route that you want to download is an item that appears once it's selected.
For example when the "SKIP" buttom in Youtube appears to quit an advertisement, it creates an instance of that box in HTML, and then it dissappears when Add is over.
I think that the route is this kind of instance and you must add a line of code to also take that piece of html

Unable to upload video file with yii2

I tried to upload video file using kartik FileInput widget.
When I use the same to field to upload image it works very fine but problem arise once I turn to video.
This is activeForm field in my view file
<?= $form->field($model, 'myFile')->widget(FileInput::classname(),
[
'pluginOptions' => [
'showUpload' => false,
'browseLabel' => 'Insert File',
'removeLabel' => '',
'mainClass' => 'input-group-md'
],
'options' => ['accept' => 'image/*, video/*']
])
?>
And I use below code to save file in the disk
if(isset($model->myFile)){
$file = UploadedFile::getInstance($model,'myFile');
if(!empty($file)){
$path=Yii::$app->basePath . '/web/uploads/';
$filetmp = explode(".", $file->name);
$extension = end($filetmp);
$encryptName = Yii::$app->security->generateRandomString().".{$extension}";
$file->saveAs($path.$encryptName);
}
} else
{
throw new \yii\web\HttpException(500, 'File not saved try again');
}
When I upload form to the controller it return
Unable to verify your data submission (400 bad request error)**
I have already tried to modify php.ini as
max_input_time = -1,
upload_max_filesize = 100M,
post_max_size = 100M
And also when I when I tried to set enableCsrfValidation = false; in that controller action request post contain no data.
I don't know what exactly is the problem.

Add watermarks to multiple images using Dropzone.js and Laravel 5.5

I have a form where a user can upload multiple images with Dropzone.js and then I store those images in the database and in the public/images folder.
But what I need is to add a watermark to all of these images before I save them in the public/images directory, because these images will show in the front-end as "preview" images.
I found documentation on how to add watermarks using Intervention Image here.
But I just cant figure out how I would proceed in adding that in my current setup.
Here is my form with the script:
<div id="file-preview_images" class="dropzone"></div>
<script>
let dropPreview = new Dropzone('#file-preview_images', {
url: '{{ route('upload.preview.store', $file) }}',
headers: {
'X-CSRF-TOKEN': document.head.querySelector('meta[name="csrf-token"]').content
}
});
dropPreview.on('success', function(file, response) {
file.id = response.id;
});
</script>
$file variable is when a user clicks on create a new File, it creates a new File with a unique identifier before its even saved. A file can have many uploads.
Here is my store method:
public function store(File $file, Request $request) {
// Make sure the user owns the file before we store it in database.
$this->authorize('touch', $file);
// Get the file(s)
$uploadedFile = $request->file('file');
$upload = $this->storeUpload($file, $uploadedFile);
$request->file( 'file' )->move(
base_path() . '/public/images/previews/', $upload->filename
);
return response()->json([
'id' => $upload->id
]);
}
protected function storeUpload(File $file, UploadedFile $uploadedFile) {
// Make a new Upload model
$upload = new Upload;
// Fill the fields in the uploads table
$upload->fill([
'filename' => $uploadedFile->getClientOriginalName(),
'size' => $uploadedFile->getSize(),
'preview' => 1
]);
// Associate this upload with a file.
$upload->file()->associate($file);
// Associate this upload with a user
$upload->user()->associate(auth()->user());
// Save the file
$upload->save();
return $upload;
}
All of that works as intended, I just need to add watermarks to each of these images, which I'm having trouble with.
I already saved a watermark image in public/images/shutterstock.png
I figured it out. This is what I had to do:
public function store(File $file, Request $request) {
// Make sure the user owns the file before we store it in database.
$this->authorize('touch', $file);
// Get the file(s)
$uploadedFile = $request->file('file');
$upload = $this->storeUpload($file, $uploadedFile);
// Get the image, and make it using Image Intervention
$img = Image::make($request->file('file'));
// Insert the image above with the watermarked image, and center the watermark
$img->insert('images/home/shutterstock.png', 'center');
// Save the image in the 'public/images/previews' directory
$img->save(base_path() . '/public/images/gallery/pre/'.$upload->filename);
return response()->json([
'id' => $upload->id
]);
}
And on the "storeUpload" method, changed the 'filename' too:
$upload->fill([
'filename' => $file->identifier.'-'.uniqid(10).$uploadedFile->getClientOriginalName(),
'size' => $uploadedFile->getSize(),
'preview' => 1
]);

Zend File Transfer: Problem when uploading a single image

I cannot understand how ->isuploaded() works. I am suppose to upload six images to display on my index page. Now the problem is, in my update function, if I upload only one or two image $upload->isUploaded() returns a false value, but if I decide to update all six of them it returns a true value. How do I deal with this problem? Am i missing out something here?
Here is my zend file transfer upload
$upload = new Zend_File_Transfer();
$upload->addValidator('Count', false, array('min' =>1, 'max' => 6))
->addValidator('Size', false, array('max' => '1Mb'))
->addValidator('ImageSize', false, array('minwidth' => 50,
'maxwidth' => 1000,
'minheight' => 50,
'maxheight' => 1000));
if ($upload->isUploaded()) $hasImage = true;
By default Zend guess all uploaded files are invalid even if just one of submitted form file fields was empty.
Zend docs are suggest to override this behavior by calling isValid() method before receive().
So I'm not sure if suggest best solution, but it works for me:
$upload = new Zend_File_Transfer();
$upload->setDestination( 'some your destination' );
if( $adapter->isValid( 'your form file field name' ) ){
$adapter->receive( 'your form file field name' );
}
And so on with every file field name. Wrap in foreach if needed.
Use isValid() instead.
if ($upload->isValid()) {
// success!
} else {
// failure!
}
Once you know your upload passed the validators, then start processing the images.

Categories