Yii2 file download using custom components - download

In yii2 project I am using components in order to download a file whose path is saved in my database.
I have setup the download button in my action column
['class' => 'yii\grid\ActionColumn',
'template'=>'{update}{pdf}{delete}',
'buttons'=>[
// to display pdf icon.
'pdf' => function ($url, $model) {
$id = [];
foreach ($model->sdsrefs as $mod)
$id[] = $mod->file_id;
return Html::a('<span class="glyphicon glyphicon-download-alt"></span>', Url::to(['product/download', 'id' => implode($id)]), [
]);
}
],
'options'=>[
'style'=>'width:70px;'
]
],
I have setup the link to the controller action in the above code.
My controller action
public function actionDownload($id)
{
Yii::$app->files->downloadFile($id);
$searchModel = new ProductSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
In the controller action I am calling the component in order to download. What happens here is instead of downloading when i click the PDF button it echoes out the content in the page. When I press the Pdf button I want it perform dowload of the file.
my download function in the component.
public static function downloadFile($id) {
$file = File::findOne($id);
$filepath = Files::getFilePath($id);
if (file_exists($filepath)) {
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.$file->file_name);
header('Content-Length: ' . filesize($filepath));
readfile("$filepath");
}else{
echo "file not exist: ".$filepath;
}
exit;
}
How can I achieve my result .i.e download when I click on the pdf action button?
Thank you

Why don't you use sendFile() method of Response object?
return Yii::$app->response->sendFile($pathFile, $filename);
Check documentation at: http://www.yiiframework.com/doc-2.0/yii-web-response.html#sendFile()-detail

Related

How can i change the image upload directory and view image url in laravel

In my script all images uploaded goes into directory "ib" but i want to change that directory to a different name eg. "imgib"
here is what i did so far. i changed the code vlues from "ib" to "imgib"
} else {
// upload path
$path = 'imgib/';
// if path not exists create it
if (!File::exists($path)) {
File::isDirectory($path) or File::makeDirectory($path, 0777, true, true);
}
// move image to path
$upload = $request->file('uploads')->move($path, $imageName);
// file name
$filename = url($path) . '/' . $imageName;
// method server host
$method = 1;
}
// if image uploded
if ($upload) {
// if user auth get user id
if (Auth::user()) {$userID = Auth::user()->id;} else { $userID = null;}
// create new image data
$data = Image::create([
'user_id' => $userID,
'image_id' => $string,
'image_path' => $filename,
'image_size' => $fileSize,
'method' => $method,
]);
// if image data created
if ($data) {
// success array
$response = array(
'type' => 'success',
'msg' => 'success',
'data' => array('id' => $string),
);
// success response
return response()->json($response);
} else {
if (file_exists('imgib/' . $filename)) {$delete = File::delete('imgib/' . $filename);}
// error response
return response()->json(array(
'type' => 'error',
'errors' => 'Opps !! Error please refresh page and try again.',
));
}
so far everything looks ok and it creates "imgib" directory automatically and all uploads go into "imgib" directory.
But the issue is, image url still uses the same old directory name.
eg. site.org/ib/78huOP09vv
How to make it get the correct url eg. site.org/imgib/78huOP09vv
Thanks for the help everyone. I managed to fix the issue by editing viewimage.blade.php
Yes of course need to clear the browser cache after editing the files.

How to image upload into databae using laravel?

I am trying to upload an image into the database but unfortunately not inserting an image into the database how to fix it, please help me thanks.
database table
https://ibb.co/3sT7C2N
controller
public function Add_slider(Request $request)
{
$this->validate($request, [
'select_image' => 'required'
]);
$content = new Sliders;
if($request->file('select_image')) {
$content->slider_image = Storage::disk('')->putFile('slider', $request->select_image);
}
$check = Sliders::create(
$request->only(['slider_image' => $content])
);
return back()
->with('success', 'Image Uploaded Successfully')
->with('path', $check);
}
You should do with the following way:
public function Add_slider(Request $request)
{
$this->validate($request, [
'select_image' => 'required'
]);
$image = $request->file('select_image');
$extension = $image->getClientOriginalExtension();
Storage::disk('public')->put($image->getFilename().'.'.$extension, File::get($image));
$content = new Sliders;
if($request->file('select_image'))
{
$content->slider_image = $image->getFilename().'.'.$extension;;
$content->save();
$check = Sliders::where('id', $content->id)->select('slider_image')->get();
return back()->with('success', 'Image Uploaded Successfully')->with('path',$check);
}
}
And in view blade file:
<img src="{{url($path[0]->slider_image)}}" alt="{{$path[0]->slider_image}}">
This returns only the filename:
Storage::disk('')->putFile('slider', $request->select_image);
Use this instead:
Sliders::create([
'slider_image' => $request->file('select_image')->get(),
]);
Make sure the column type from database is binary/blob.

Yii2 Kartik editable input value will only change after refresh

I use Kartik Editable input widget. I have a home model and tema model attribute here. Whenever I input and submit value in the field, the value won't change on-the spot but will only change after I refresh the page instead. What should I do? Thanks!
My controller :
public function actionIndex()
{
$searchModel = new HomeSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
// table only has one row
$model= Home::find()->one();
// Check if there is an Editable ajax request
if (isset($_POST['hasEditable'])) {
// use Yii's response format to encode output as JSON
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
// read your posted model attributes
if ($model->load($_POST)) {
// read or convert your posted information. Based on the 'name' property set in the view. So this 'tema' of $model-> tema comes from 'name' property set in the view.
$value = $model->tema;
$model->save();
// return JSON encoded output in the below format
return ['output'=>$value, 'message'=>'output berhasil'];
// alternatively you can return a validation error
// return ['output'=>'', 'message'=>'Validation error'];
}
// else if nothing to do always return an empty JSON encoded output
else {
return ['output'=>'', 'message'=>'output gagal'];
}
};
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'model'=>$model,
]);
}
The view
<?php
echo Editable::widget([
'model' => $model,
'attribute' => 'tema',
'value'=>$model->tema,
/*'asPopover'=>'false',*/
'type' => 'post',
'header'=>'tema',
'valueIfNull'=>'value-nya NULL',
'format'=>'link',
'size'=> 'lg',
'inputType' => Editable::INPUT_TEXT,
'editableValueOptions' => ['class' => 'text-success h3']
]); ?>
Another issue, whenever I used 'asPopover'=>'false', it shows no error but nothing happen when I click the supposedly editable-input field. The editable-inline field just won't show up. When I use the popOver option,the pop-up just automatically triggered without clicking and also it pop-up on the top left corner of the page. Only after I clicked on the editable widget that triggered the pop-up will it recorrect itself to the proper position. Is it a bug? I used the latest Yii2 with bootstrap 4, and I had set the global parameter in params.php config with 'bsVersion' => '4.x', as in the documentation
In the Controller, try this:
public function actionIndex()
{
$searchModel = new HomeSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
if (isset($_POST['hasEditable']))
{
$tema = Yii::$app->request->post('editableKey');
$modelHome = Home::findOne($tema);
$posted = current($_POST['Home']);
$post = ['Home' => $posted];
if ($modelHome->load($post)) {
$modelHome->save();
$out = Json::encode(['output'=>$modelHome->tema, 'message'=>'']);
return $out;
}
return;
};
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'model'=>$model,
]);
}

Yii2 Kartik editable widget

I have a problem with my Kartik input text editable widget. It affected on the tema column in my table. The problem is, on my chrome developer tool it returns an "Internal server error" on the AJAX processing. The response header's content is : Content-Type: application/json; charset=UTF-8 but the connection remains close. Is there anything wrong with my code? Note : the initial value of the editable's label is NOT SET (which should be the value of "tema" column retrieved from my $model->tema). The model name is Home.
My HomeController :
public function actionIndex()
{
$searchModel = new HomeSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
$model = new Home;
// Check if there is an Editable ajax request
if (isset($_POST['hasEditable'])) {
// use Yii's response format to encode output as JSON
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
$temaId=Yii::$app->request->post('editableKey');
$query= Home::find()->where(['id'=> $temaId])->one();
// read your posted model attributes
if ($model->load($_POST)) {
// read or convert your posted information
$value = $query->tema;
$value->save();
// return JSON encoded output in the below format
return ['output'=>$value, 'message'=>''];
// alternatively you can return a validation error
// return ['output'=>'', 'message'=>'Validation error'];
} else {
// else if nothing to do always return an empty JSON encoded output
return ['output'=>'', 'message'=>''];
}
};
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'model'=>$model,
]);
}
The view file
use kartik\editable\Editable;
<?php
echo Editable::widget([
'model' => $model,
'attribute' => 'tema',
'type' => 'post',
'value'=>$model->tema,
'header'=>'tema',
'size'=> 'lg',
'inputType' => Editable::INPUT_TEXT,
'editableValueOptions' => ['class' => 'text-success h3']
]);
?>
Please help. Have spent two days on this. Thanks!

I need correct example for ajax send and received data in zend framework 3

Example for send and received data between ajax function and action of controller in Zend framework 3
Here is a simple example of an ajax request using ZF3. You may give a try with this one. In this example we would use ZF3's default Application module.
Lets assume we would retrieve data via a ajax call from the following url.
http://yoursite.com/title
Lets create an action method for the title route in the IndexController.
public function titleAction()
{
// Initialize view
$view = new ViewModel();
// Checks if this is a Javascript request
$xmlHttpRequst = $this->getRequest()->isXmlHttpRequest();
if (! $xmlHttpRequst) {
die('Bad request');
}
/**
* Here we may pull data from database but for tests
* here we make an array of titles for the view
*/
$titles = [];
for ($i = 0; $i < 10; $i++) {
$titles[] = "Lorem ipsum dolor {$i}";
}
// Set data to be used in the view
$view->setVariable('titles', $titles);
/**
* Tell the renderer not to show the layout
* by setting setTerminal to true
*/
$view->setTerminal(true);
return $view;
}
We created a method, we need creating a view template for it.
view/application/index/title.phtml
<?php
foreach ($titles as $title) {
echo '<h2>' . $title . '</h2>';
}
Now we would create another action method in the IndexController from where we would make the ajax call.
http://yoursite.com/text
So lets make that action method too...
public function textAction()
{
return new ViewModel();
}
and view template would be like so
view/application/index/text.phtml
<h1>Handling ajax request</h1>
<button onclick="showTitle()">Show Title</button>
<div id="box"></div>
<?php
// Set url
$url = $this->serverUrl('/title'); // http://yoursite.com/title
// This is for the "url" catch
echo "<script>" . PHP_EOL;
echo "\tvar url = '{$url}';" . PHP_EOL;
echo "</script>" . PHP_EOL;
?>
<script>
function showTitle() {
$.get(url, function(data){
$('#box').html(data);
})
.done(function(){
console.log('Done!');
})
.fail(function(){
console.log('Failed!');
});
}
</script>
This script needs jQuery Javascript library to make the ajax call. So make sure that script is added in your view/layout/layout.phtml.
The last thing we need is to set up routes for the /title and /text. Lets add those two routes to the route section of module/Application/config/module.config.php
'title' => [
'type' => Literal::class,
'options' => [
'route' => '/title',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'title',
],
],
],
'text' => [
'type' => Literal::class,
'options' => [
'route' => '/text',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'text',
],
],
],
Let us know if it makes you happy!

Resources