Save output data in image format - php

I am saving the data as jpeg file but it is not saving properly.
$file= drupal_http_request('https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=CnRvAAAAwMpdHeWlXl-lH0vp7lez4znKPIWSWvgvZFISdKx45AwJVP1Qp37YOrH7sqHMJ8C-vBDC546decipPHchJhHZL94RcTUfPa1jWzo-rSHaTlbNtjh-N68RkcToUCuY9v2HNpo5mziqkir37WU8FJEqVBIQ4k938TI3e7bf8xq-uwDZcxoUbO_ZJzPxremiQurAYzCTwRhE_V0&sensor=true&key=AIzaSyDGsEo0x-oqsIDVn0EaTx6mN1BMXkAhZDs');
$handle=fopen("/public/image.jpeg",'w');
fwrite($handle,$file->data);
fclose($handle);
The output : $file->data is :" IHDRddpâ•TIDATxÚílUåÇkbæ....."

Save yourself the headache - use system_retrieve_file()
$result = system_retrieve_file($url, 'public://image.jpeg');
I imagine your current code isn't working because you're not using a proper URI to the public folder, but you might may as well use the API where available.

Instead file function you can use copy like this:
try{
copy($source, $destination);
}catch(Exception $e) {
echo "<br/>\n unable to copy '$fileName'. Error:$e";
}

Related

How to zip & download folders and files stored in S3 storage in Laravel [duplicate]

Is there a way to zip and download files and folders which are in Amazon S3 bucket, together in Laravel? I Want to zip the three folders and one file in the picture together and download it
Here's a half baked solution in a route file. Hope it helps.
https://flysystem.thephpleague.com/docs/adapter/zip-archive/
composer require league/flysystem-ziparchive
I put this in routes/web.php just to play with.
<?php
use Illuminate\Support\Facades\Storage;
use League\Flysystem\Filesystem;
use League\Flysystem\ZipArchive\ZipArchiveAdapter;
Route::get('zip', function(){
// see laravel's config/filesystem.php for the source disk
$source_disk = 's3';
$source_path = '';
$file_names = Storage::disk($source_disk)->files($source_path);
$zip = new Filesystem(new ZipArchiveAdapter(public_path('archive.zip')));
foreach($file_names as $file_name){
$file_content = Storage::disk($source_disk)->get($file_name);
$zip->put($file_name, $file_content);
}
$zip->getAdapter()->getArchive()->close();
return redirect('archive.zip');
});
You'll definitely want to do something different than just plopping it in the public dir. Maybe stream it out straight out as a download or save it somewhere better. Feel free to post comment/questions and we can discuss.
I did it the following way after looking at some solutions by streaming the zip directly to the client by using https://github.com/maennchen/ZipStream-PHP :
if ($uploads) {
return response()->streamDownload(function() use ($uploads) {
$opt = new ArchiveOptions();
$opt->setContentType('application/octet-stream');
$zip = new ZipStream("uploads.zip", $opt);
foreach ($uploads as $upload) {
try {
$file = Storage::readStream($upload->path);
$zip->addFileFromStream($upload->filename, $file);
}
catch (Exception $e) {
\Log::error("unable to read the file at storage path: $upload->path and output to zip stream. Exception is " . $e->getMessage());
}
}
$zip->finish();
}, 'uploads.zip');
}

Php use move_uploaded_file() from json data structure

I recive the data by json angular request, but I don´t have ($_FILES['name']['tmp_name']) format, so i can´t use move_uploaded_file()
WEB Json data
avatar {
contentType "application/pdf"
data "data:application/pdf;base64,JVBERi0xLjcNCiW1tbW1DQoxIDAgb2JqDQo8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFIvTGFuZyhlcy1DTykgL1N0cnVjdFRyZWVSb290IDMxIDAgUi9NYXJrSW5mbzw8L01hcmtlZCB0cnVlPj4vTWV0YWRhdGEgMjMyIDAgUi9WaWV3ZXJQcmVmZXJlbmNlcyAyMzMgMCBSPj4NCmVuZG9iag0KMiAwIG9iag0KPDwvVHlwZS9QYWdlcy9Db3VudCA0L0tpZHNbIDMgMCBSIDE3IDAgUiAyMiAwIFIgMjYgMCBSXSA+Pg0KZW5kb2JqDQozIDAgb2JqDQo8PC9UeXBlL1BhZ2UvUGFyZW50IDIgMCBSL1Jlc291cmNlczw8L1hPYmplY3Q8PC9JbWFnZTUgNSAwIFIvSW1hZ2U3IDcgMCBSPj4vRXh0R1N0YXRlPDwvR1M2IDYgMCBSL0dTMTAgMTAgMCB…Dg5NiAwMDAwMCBuDQowMDAwMzU4MDc2IDAwMDAwIG4NCjAwMDAzNTgxMjIgMDAwMDAgbg0KdHJhaWxlcg0KPDwvU2l6ZSAyMzUvUm9vdCAxIDAgUi9JbmZvIDMwIDAgUi9JRFs8MDlEM0VCOEI1NzE4NTg0MEIxMjA3MkEyMUM2RkNEOTg+PDA5RDNFQjhCNTcxODU4NDBCMTIwNzJBMjFDNkZDRDk4Pl0gPj4NCnN0YXJ0eHJlZg0KMzU4ODcyDQolJUVPRg0KeHJlZg0KMCAwDQp0cmFpbGVyDQo8PC9TaXplIDIzNS9Sb290IDEgMCBSL0luZm8gMzAgMCBSL0lEWzwwOUQzRUI4QjU3MTg1ODQwQjEyMDcyQTIxQzZGQ0Q5OD48MDlEM0VCOEI1NzE4NTg0MEIxMjA3MkEyMUM2RkNEOTg+XSAvUHJldiAzNTg4NzIvWFJlZlN0bSAzNTgxMjI+Pg0Kc3RhcnR4cmVmDQozNjM3MzINCiUlRU9G"
filename "manualversion1.pdf"
size 363915
}
descripPretensiones "gsdfgfgdfdgf"
fecFin "2021-06-17T05:00:00.000Z"
PHP
In this part i dont have any response of try catch, no error o problem, but my file never is upload to my folder
$data = json_decode(file_get_contents('php://input'), true);
$fileName= $data["avatar"]["filename"];
try {
if(move_uploaded_file(base64_decode($data['avatar']['data']), $finalRute)){
echo 'file update';
}
} catch (Exception $e) {
echo 'Excepción capturada: ', $e->getMessage(), "\n";
}
You have the data encoded as base64 in memory. You will have to do something to write the data to disk instead of using move_uploaded_file, which is designed for moving a temp file on disk to a different location. The most straightforward would be file_put_contents.
Something like:
file_put_contents($finalRute, base64_decode(explode(',', $data['avatar']['data'])[1]));
code edited per AbraCadaver's comments about omitting data:application/pdf;base64,

How to handle errors exception in laravel snappyPDF?

Using Laravel/Snappy to generate PDFs. However this errors:
already exist file name after trying to save it to storage.
How can I handle these errors?
public function saveSnappyHeaderFooter()
{
//dd( storage_path());
$users = \App\User::all();
$data = ['users' => $users];
$SnappyPDF = SnappyPDF::loadView('pdf.snappyPDF.snappyHeaderFooter', $data);
$SnappyPDF->setOption('margin-top', '25mm');
$SnappyPDF->setOption('margin-bottom', '25mm');
$SnappyPDF->setOption('header-html', public_path() . '\pdf-parts\pdf-header.html');
$SnappyPDF->setOption('footer-html', public_path() . '\pdf-parts\pdf-footer.html');
$SnappyPDF->setOption('print-media-type', true);
$SnappyPDF->save(storage_path('app/files/'.Carbon::now() .'_' . 'myname2.pdf'));
}
In general this is how you can handle errors in PHP:
try {
//your code
} catch (Exception $e) {
//handle errors
}
Or you can ask if file exists by using:
if(!file_exists(storage_path('app/files/'.Carbon::now() .'_' . 'myname2.pdf'))){
//ok, code will run
}else{
// not ok, maybe change the name?
}
you can also do it in the laravel way: File::exists
Or maybe you can give us more details.
Note
Its an anti-patteren to not be 100% sure that the files is not exists. I dont know your usecase, but im saying that based on the fact that you are generating the file name. maybe you should use more uniq patterens. like GUIDs...

Removing an image from server

I am trying to delete the images from the server using unlink() function. This is deleting the image name from the database, but the image is not deleted from the server, what am i doing wrong?
public function actionDelete()
{
if(Yii::$app->request->isAjax)
{
$id = $_POST['id'];
$product=Product::find()->where(['id'=>$id])->one()->delete();
$delete=CategoryProduct::find()->where(['product_id'=>$id])->all();
foreach($delete as $del)
{
$del->delete();
}
$imgfile="<?php echo Yii::$app->request->baseUrl;?>/web/assets/uploads/<?php echo $product->image;?>";
unlink($imgfile);
echo json_encode(TRUE);die;
}
echo json_encode(FALSE);die;
}
Its is best to set an alias for the upload path (best place will be config/bootstrap.php)so that we can have standard name to all the upload folder. i.e
Yii::setAlias('image_uploads', dirname(dirname(__DIR__)) . '/web/assets/uploads');
You can use the same for saving and deleting the file.
Saving will be like
move_uploaded_file($tmp_file, \Yii::getAlias('#image_uploads/products/') . $product->image);
or
You can use Yii Methods i.e for e.g.
$this->imageFile->saveAs($orignal_file_full_path); // where imageFile in input type file
Deleting will be something like:
unlink (\Yii::getAlias('#image_uploads/products/') . $product->image);
the Core idea is to use real paths for deleting and saving rather then URLs

Deleting files after download in laravel

I'm creating a application that lets a user download a file. After the download i want the file to be deleted. The end of my code is like this:
return Response::download(public_path() . '/uploads/_tmp/' . urldecode($filename));
which means that the function ends on the return an i am not able to delete the file. I have tried to call a 'after' filter on the route but then the file gets deleted to quickly.
Any ideas?
You can use deleteFileAfterSend http://laravel.com/docs/5.0/responses#other-responses
return response()->download($filePath, $fileName, $headers)->deleteFileAfterSend(true);
I personally use the following;
$response = Response::make(file_get_contents($path_to_file), $status_code, $headers);
Status code is obviously the code which you want to return.
Within the $header parameter you can pass an array with the indexes Content-Type and Content-Disposition.
Then you can simply unlink $path_to_file and return $response.
Much easier way of deleting a file would be to use Jon's answer for versions of Laravel > 4.0.
You can use deleteFileAfterSend http://laravel.com/docs/5.0/responses#other-responses
return response()->download($filePath, $fileName, $headers)->deleteFileAfterSend(true);
Simply use this line of code:
return response()->download($file_path)->deleteFileAfterSend(true);
Here, inside download function the file path will be passed as an argument. Let's say for an example you want to backup your database in a file and also want to delete with downloading:
$date = Carbon::now()->format('Y-m-d_h-i');
$pub_path = public_path();
$file_path = $pub_path . '/application/db_backups/' . $date . '.sql';
$output = shell_exec('mysqldump -h58.84.34.65 -uwsit -pwsit97480 websms > ' . $file_path);
return response()->download($file_path)->deleteFileAfterSend(true);
If you want to delete the source file after downloading, simply write it as follows
return response()->download($filePath)->deleteFileAfterSend(true);
$filename = storage_path() . '/testing.txt';
App::finish(function($request, $response) use ($filename)
{
unlink($filename);
});
return Response::download($filename);
For Laravel 5.8 use stream download. In the callback function, delete the file after echo the contents.
Let's take a look at the solution:
return response()->streamDownload(function () use ($pathToTheFile) {
echo Storage::get($pathToTheFile);
Storage::delete($pathToTheFile);
}, 'my-awesome-file-name');
I don't know if it works for the oldest or the latest versions.
unlink('./path/filename.extension');

Categories