How to download already save image in yii framework - yii

I am using
$this->widget(
'CMultiFileUpload',
array(
'model' => $model,
'attribute' => 'Image',
'accept' => 'jpg|gif|png|doc|docx|pdf',
'denied' => 'Only doc,docx,pdf and txt are allowed',
'max' => 4,
'remove' => '[x]',
'duplicate'=>'Already Selected',
)
);
for upload multiple images , i save all images into database.But i want to download that saved image.
public function uploadMultifile ($model, $attr, $path)
{
/*
* path when uploads folder is on site root.
* $path='/uploads/doc/'
*/
if ($sfile = CUploadedFile::getInstances($model, $attr)) {
foreach ($sfile as $i => $file) {
$fileName = "{$sfile[$i]}";
$formatName=time() . $i . '_' . $fileName;
$file->saveAs(Yii::app()->basePath . '/' . $formatName);
$ffile[$i] = $formatName;
}
return ($ffile);
}
}
I want to provide link to image and download automatically.
echo CHtml::link($data->image);
Any help appreciated.
I tried
public function actionDownloadImage()
{
$model = $this->loadModel($_GET['id']);
$fileDir = Yii::app()->basePath.'/Img/';
Yii::app()
->request
->sendFile(
$model->image,
file_get_contents($fileDir.$model->image),
$model->image
);
}
but give error..

You haven't defined folder path to save image in uploadMultifile() action. So you can't get your desired images from "Img" named folder. You have to make following changes in uploadMultifile() action:
public function uploadMultifile ($model, $attr, $path)
{
/*
* path when uploads folder is on site root.
* $path='/uploads/doc/'
*/
if ($sfile = CUploadedFile::getInstances($model, $attr)) {
foreach ($sfile as $i => $file) {
$fileName = "{$sfile[$i]}";
$formatName=time() . $i . '_' . $fileName;
$file->saveAs(Yii::app()->basePath . '/Img/' . $formatName); // specify folder path where you have to save image
$ffile[$i] = $formatName;
}
return ($ffile);
}
}
Hope this helps.

Related

Correct image path to delete from storage laravel 8

I try to delete the old profilepicture in storage file but it is not working.
below is my screenshot of my files
and this is my code in update profile controller.
public function updateProfile(Request $request, User $user)
{
if ($request->hasFile('profilepicture')) {
Storage::delete('/storage/profilepicture' . $user->profilepicture);
$filenameWithExt = $request->file('profilepicture')->getClientOriginalName();
$filename = pathinfo($filenameWithExt, PATHINFO_FILENAME);
$extension = $request->file('profilepicture')->getClientOriginalExtension();
$fileNameToStore = time() . '.' . $extension;
$path = $request->file('profilepicture')->storeAs('public/profilepicture', $fileNameToStore);
$user->update([
'profilepicture' => $fileNameToStore
]);
}
$user->update([
'name' => $request->name,
'email' => $request->email,
'birth_date' => $request->birth_date,
'section' => $request->section,
'unit' => $request->unit,
'phone' => $request->phone,
]);
return back()->withSuccess('You have successfully update User.');
}
i already tried
Storage::delete('/public/storage/profilepicture/' . $user->profilepicture);
Storage::delete('/storage/profilepicture/' . $user->profilepicture);
Storage::delete('profilepicture/' . $user->profilepicture);
but none of them is working. Or there is any other correct way to do this?
Use class Filesystem instead of Storage, and give it an absolute path like this:
// Declare
use Illuminate\Filesystem\Filesystem;
// Using
$file = 'icon-256x256.png';
$path = public_path('profilepicture/' . $file);
Filesystem::delete($path);
You will delete the file successful!

how to send a file from one web system to another using guzzle client in laravel

i want to send an image from one web system(A) to another web system(B).the image is saved in system(A) and then sent to system(B).am using guzzle http client to achieve this.my api in system (B) works very well as i have tested it in postman.the part i have not understood why its not working is in my system(A) where i have written the guzzle code.i have not seen any error in my system(A) log file but the file isnt sent to system (B).
here is my image save function is system(A).
public function productSavePicture(Request $request)
{
try {
$validation = Validator::make($request->all(), [
'product_id' => 'required',
]);
$product_details = product::where('systemid', $request->product_id)->first();
if ($request->hasfile('file')) {
$file = $request->file('file');
$extension = $file->getClientOriginalExtension(); // getting image extension
$company_id = Auth::user()->staff->company_id;
$filename = ('p' . sprintf("%010d", $product_details->id)) . '-m' . sprintf("%010d", $company_id) . rand(1000, 9999) . '.' . $extension;
$product_id = $product_details->id;
$this->check_location("/images/product/$product_id/");
$file->move(public_path() . ("/images/product/$product_id/"), $filename);
$this->check_location("/images/product/$product_id/thumb/");
$thumb = new thumb();
$dest = public_path() . "/images/product/$product_id/thumb/thumb_" . $filename;
$thumb->createThumbnail(
public_path() . "/images/product/$product_id/" . $filename,
$dest,
200);
$systemid = $request->product_id;
$product_details->photo_1 = $filename;
$product_details->thumbnail_1 = 'thumb_' . $filename;
$product_details->save();
// push image to system(B)
$imageinfo = array(
'file' => $filename,
'product_id' => $product_details->id,
);
$client = new \GuzzleHttp\Client();
$url = "http://systemb/api/push_h2image";
$response = $client->request('POST',$url,[
// 'Content-type' => 'multipart/form-data',
'multipart' => [
[
'name' => 'imagecontents',
'contents' => fopen(public_path() . ("/images/product/$product_id/") . $filename, 'r'),
// file_get_contents(public_path("/images/product/$product_id/thumb/thumb_" . $filename)),
'filename' =>$filename
],
[
'name' => 'imageinfo',
'contents' => json_encode($imageinfo)
],
]
]);
}
}
}
i have followed every step in the documentation but still the process isnt working.where might i be making a wrong move?the laravel version of my project is 5.8 and the version of the guzzle http client is 7.4.1

How do I download document from a web page in Zend Framework

I am using Laminas (Zend) Framework. I have created a folder for storing documents for each of the customers. Since a user can have access to public folder only, how do I make the user have access to documents stored in his/her folder? One way I could think off is creating symbolic links but I do not have
the know-how of creating dynamic symbolic links? Please advise about any other options.
You can serve file from controler action
class FilesControler extends Laminas\Mvc\Controller\AbstractActionController;
public function fileAction()
{
//TODO get userDir from identity
$filename= $userDir.$this->param()->fromQuery('file');
if (file_exists($filename))
{
$ext = substr($filename, - 3, 3);
if ($ext == 'pdf')
{
header('Content-Type: application/pdf');
}
else
{
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($filename) . '"');
header('Content-Length: ' . filesize($filename));
}
header('Content-Description: File Transfer');
header('Pragma: public');
readfile($filename);
}
else
{
header("HTTP/1.0 404 Not Found");
echo "404 Not Found. $filename";
}
return $this->response;
}
You can also define route like that
[
'assets' => [
'type' => Segment::class,
'options' => [
'route' => '/file[/:d1][/:d2][/:d3][/:d4][/:d5][/:d6][/:d7][/:d8][/:d9]/:basename',
'defaults' => [
'controller' => Controller\FilesController::class,
'action' => 'file'
]
]
]
and then concat filepath from route params
$directories = [];
for ($i = 1; $i < 9; ++ $i)
{
$dir = $this->params('d' . $i);
if ($dir)
$dirs[] = $dir;
else
break;
}
$basename = $this->param('basename');
$filename = implode('/', $dirs) . '/' . $basename;
URI will be more natural, but you have to limit depth of directories.

Decode base64 into jpeg and save the image to server

currently i have base 64 value in
$model->test
and i want to decode the base 64 value in controller and save it to database through API here some of my code in controller
i try to decode and cant figure out how to upload it to server and create path
however i try to to pass the $data to getinstance which is not working
public function doSaveStudent(StudentLoanForm $model)
{
$url = API_URL . 'web/apply/student';
$data1 = $model->test;
$decode = base64_decode($data);
$img = file_put_contents('webcam.jpg', $data);
$model->doUploads();
$ktpdetail = UploadedFile::getInstance($model, 'image_ktp');
$data = null;
$data = [
[
'name' => 'univ_name',
'contents' => $model->univ_name
],
[
'name' => 'test',
'contents' =>$model->test
],
];
// dd($model->test);
if ($ktpdetail != null) {
$data[] = [
'name' => 'image_ktp',
'contents' => fopen(Yii::getAlias('#frontend/web/') . $model->image_ktp, 'r'),
'filename' => $ktpdetail->getBaseName() . '.' . $ktpdetail->getExtension()
];
}
if($ktpayahdetail != null){
$data[] = [
'name' => 'foto_ktp_ayah',
'contents' => fopen(Yii::getAlias('#frontend/web/') . $model->foto_ktp_ayah, 'r'),
'filename' => $ktpayahdetail->getBaseName() . '.' . $ktpayahdetail->getExtension()
];
}
if ($kkdetail != null) {
$data[] = [
'name' => 'image_kk',
'contents' => fopen(Yii::getAlias('#frontend/web/') . $model->image_kk, 'r'),
'filename' => $kkdetail->getBaseName() . '.' . $kkdetail->getExtension()
];
i expect to decode the base 64 and upload all the value using yii2 best practice
The yii\web\UploadedFile is used only for files uploaded using file input in forms.
In your case base64_decode($model->test) should give you binary data of image.
Then you have two options what to do with them.
1) You can store them directly into BLOB attribute in database.
$imageModel = new MyImageModel();
$imageModel->data = base64_decode($model->test);
if(!$imageModel->save()) {
throw new \yii\base\Exception("Couldn't save file to db");
}
2) You can save the file with file_put_contents and then store the path to file in your model.
$imageData = base64_decode($model->test);
//the used alias in path is only example.
//The datetime and random string are used to avoid conflicts
$filename = Yii::getAlias(
'#frontend/web/' . date('Y-m-d-H-i-s') .
Yii::$app->security->generateRandomString(5) . '.jpg'
);
if (file_put_contents($filename, $imageDate === false) {
throw new \yii\base\Exception("Couldn't save image to $filename");
}
$imageModel = new MyImageModel();
$imageModel->path = $filename;
if(!$imageModel->save()) {
//delete file if we couldn't save path into db to prevent creating an orphan
unlink($filename);
throw new \yii\base\Exception("Couldn't add $filename to database");
}

How to upload multiple file at a time using TbActiveForm?

I am using TbActiveForm. I want upload multiple file at a time, Please help me.Thanks
In your TbActiveForm you have to use a widget for multiple file upload. You could write it yourself or use widget like CMultiFileUpload.
Here is reference for CMultiFileUpload.
Example for view:
<?php
$this->widget('CMultiFileUpload', array(
'model'=>$model,
'attribute'=>'photos',
'accept'=>'jpg|gif|png',
'options'=>array(),
'denied'=>'File is not allowed',
'max'=>10, // max 10 files
));
?>
Example for controller:
public function actionCreate()
{
$model = new Photo;
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
$type = isset($_GET['type']) ? $_GET['type'] : 'post';
if (isset($_POST['Photo'])) {
$model->attributes = $_POST['Photo'];
$photos = CUploadedFile::getInstancesByName('photos');
// proceed if the images have been set
if (isset($photos) && count($photos) > 0) {
// go through each uploaded image
foreach ($photos as $image => $pic) {
echo $pic->name.'<br />';
if ($pic->saveAs(Yii::getPathOfAlias('webroot').'/photos/path/'.$pic->name)) {
// add it to the main model now
$img_add = new Photo();
$img_add->filename = $pic->name; //it might be $img_add->name for you, filename is just what I chose to call it in my model
$img_add->topic_id = $model->id; // this links your picture model to the main model (like your user, or profile model)
$img_add->save(); // DONE
}
else{
echo 'Cannot upload!'
}
}
}
if ($model->save())
$this->redirect(array('update', 'id' => $model->id));
}
$this->render('create', array(
'model' => $model,
));
}
Source reference.