DomPDF is displaying output as HTML not as PDF document - laravel

I'm facing an issue with domPDF. pdf result getting displayed as html page not as pdf document. I'm trying to get the data from database and get the result in pdf document using 'dompdf' for laravel.
pdf-output-image
here is my HTML code.
`<!DOCTYPE html>
<html>
<head>
<title>MHT Order PDF</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
</head>
<body>
<div class="d-block text-center" style="text-align: center; margin-top: -15px;">
<h1 style="text-align: center" class="navbar-brand text-underline text-center"><u> MAJESTIC HOUSE </u></h1>
<p style="margin-top:-20px">General Trading LLC</p>
</div>
<div class="order_heading">
#foreach($orderDtls as $order)
<p class="date">Date: {{$date}}</p>
<h3 class="orderDtls">Order Details </h3>
<h5 class="details">Order UID: <strong style="color: red;">{{$order->order_unq_id}}</strong></h5>
<h5 class="details">Customer Name: <strong style="color: red;">{{$order->customer_name}}</strong></h5>
<p id="date"> </p>
</div>
<table class="table caption-top" id="orderTable">
<caption>Order Details</caption>
<thead>
<tr>
<th scope="col">Customer Name</th>
<th scope="col">Product Name</th>
</tr>
</thead>
<tbody>
#foreach($orderDtls as $order)
<tr>
<td scope="row">{{$order->customer_name}}</td>
<td>{{$order->item_name}}</td>
</tr>
#endforeach
</tbody>
</table>
#endforeach
</body>
</html>
this is the code from Controller
public function mht_order_pdf(){
$customers = Customer::all();
$linkeds = Linked::all();
$orders = Order::all();
$date = date('y-m-d');
$orderDtls = DB::select("SELECT
customers.customer_name,
orders.id,
orders.order_unq_id,
items.item_name,
orders.item_quantity,
orders.total
FROM customers
JOIN linkeds
ON customers.id = linkeds.customer_id
JOIN items
ON linkeds.item_id = items.id
JOIN orders
ON linkeds.id = orders.linked_id
WHERE orders.order_unq_id = 'MH-Ord/29722/xyz supermarket';"
);
// // return $orderDtls;
return view('mht_order_pdf', compact('customers', 'linkeds', 'orders', 'orderDtls',
'date'));
$pdf = PDF::loadView('mht_order_pdf', $orderDtls);
return $pdf->stream('mht_order_pdf.pdf');
}
this is the code from web.php
<?php
use App\Http\Controllers\Backend\CustomerController;
use App\Http\Controllers\Backend\ItemController;
use App\Http\Controllers\Backend\LinkedController;
use App\Http\Controllers\Backend\OrderController;
use App\Http\Controllers\Backend\ProductController;
use App\Http\Controllers\Backend\UserController;
use App\Http\Controllers\PDFController;
use App\Models\Customer;
use App\Models\Linked;
use App\Models\Order;
use App\Models\Product;
use Illuminate\Support\Facades\Route;
use Dompdf\Dompdf;
use Illuminate\Support\Facades\DB;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])-
>name('home');
Route::resource('users', UserController::class);
Route::resource('products', ProductController::class);
Route::resource('items', ItemController::class);
Route::resource('customers', CustomerController::class);
Route::resource('linked', LinkedController::class);
Route::resource('orders', OrderController::class);
Route::get('mht_order_pdf', [OrderController::class, 'mht_order_pdf'])-
>name('mht_order_pdf');
PLEASE LET ME KNOW WHAT I'M DOING WRONG?
Thank you!

Your controller stops at this line:
return view('mht_order_pdf', compact('customers', 'linkeds', 'orders', 'orderDtls', 'date'));
thus the 2 lines below it, which related to the DomPDF, gets ignored. Try to delete the return view() above so that the DomPDF lines of code below it can be executed.

Related

Trying to get property of non-object in json from API

I'm using the Discord API to get the members on a Discord guild to display 10 randoms users and display it in the view with blade using the foreach method.
I'm getting the JSON from the API, getting the members array of it and sclicing it to return only 10 members to send it from the controller to the view.
The problem is that, when I want to parse it and use an element of the array (avatar_url), it's not working and I'm getting this error message: Trying to get property 'avatar_url' of non-object
Here is my controller
class IndexController extends Controller {
...
/**
* Function to get 10 random players on fivem
* #return array
*/
private function getServerPlayers() {
$request = file_get_contents('https://discordapp.com/api/guilds/683766194884575355/widget.json');
$decoded = json_decode($request, true)['members'];
return array_slice($decoded, 0, 10);
}
/**
* Return index view
* #return Factory|View
*/
public function index() {
return view('index')->with('players', $this->getServerPlayers())->with('clients', $this->getServerClients())->with('members', $this->getDiscordMembers());
}
}
Here is my view
<div class="row">
<div class="col-lg-12">
<div class="tab-content" id="pills-tabContent">
<div class="tab-pane fade show active" id="pills-all-bets" role="tabpanel"
aria-labelledby="pills-all-bets-tab">
<div class="responsive-table">
<table class="table">
<thead>
<tr>
<th scope="col">Nom du joueur</th>
<th scope="col">Statut</th>
</tr>
</thead>
<tbody>
#foreach($players as $player)
<tr>
<td><img src="{{ $player->avatar_url }}">{{ $player->username }}</td>
<td>En ligne</td>
</tr>
#endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
I think that the problem is kind of dumb but I'm blocked on it, I need some help !
Thanks.
You should use avatar_url like this:
<td><img src="{{ $player['avatar_url'] }}">{{ $player['username'] }}</td>
because what you pass to view is an array, not an object.
The problem is that json_decode returns an array and not an object.
You can pass the arguments to the view using:
return view('index',[
'players' => $this->getServerPlayers(),
'clients' => $this->getServerClients(),
'members' => $this->getDiscordMembers(),
]);
And then display them in the view using:
<img src="{{ $player['avatar_url'] }}">{{ $player['username'] }}

Displaying Calculations from Controller In View blade Laravel

i am building an asset management system.I would like to have the following calculations done in the controller to be displayed in the view.
public function depreciation()
{
$assets = Asset::all();
$price = DB::table('assets')
->where('category_id', 1)
->sum('purchase_price');
$dep = $price * 0.3333;
$netprice = $price - $dep;
return $netprice;
return view('admin.assets.index')->with(['price','dep', 'netprice' => $netprice]);
}
My Route
Route::post('assets_depreciation', ['uses' => 'Admin\AssetsController#depreciation', 'as' => 'assets.depreciation']);
My View
<tbody>
#if (count($assets) > 0)
#foreach ($assets as $asset)
<tr data-entry-id="{{ $asset->id }}">
#can('asset_delete')
<td></td>
#endcan
<td field-key='title'>{{ $asset->title }}</td>
<td field-key='serial_number'>{{ $asset->serial_number }}</td>
<td field-key='barcode'>{{ $asset->barcode }}</td>
<td field-key='photo1'>#if($asset->photo1)<img src="{{ asset(env('UPLOAD_PATH').'/thumb/' . $asset->photo1) }}"/>#endif</td>
<td field-key='category'>{{ $asset->category->title ?? '' }}</td>
<td field-key='status'>{{ $asset->status->title ?? '' }}</td>
<td field-key='location'>{{ $asset->location->title ?? '' }}</td>
<td field-key='assigned_user'>{{ $asset->assigned_user->name ?? '' }}</td>
<td field-key='vendor'>{{ $asset->vendor->name ?? '' }}</td>
<td field-key='purchase_price'>{{ $asset->purchase_price }}</td>
<td field-key='warranty'>{{ $asset->warranty }}</td>
<td field-key='depreciation'>{{ $netprice }}</td>
<td>
How can This be achieved?
You should be using a GET request instead of a POST for your route. It should look like this:
Route::get('assets_depreciation', ['uses' => 'Admin\AssetsController#depreciation',
'as' => 'assets.depreciation']);
Laravel's documentation gives you correct usage examples of their framework components, you can check it out here: Laravel/Routing. Hope this helps!
If you are looking to send the price, dep and netprice to the admin.assets.index view then you can use this:
public function depreciation()
{
$assets = Asset::all();
$price = DB::table('assets')
->where('category_id', 1)
->sum('purchase_price');
$dep = $price * 0.3333;
$netprice = $price - $dep;
return view('admin.assets.index')->with(['price' => $price,'dep' => $dep, 'netprice' => $netprice]);
}
Then you can use these variables in you view file {{ $price }}, {{ $dep }}, {{ $netprice }}
You need to create file index.blade.php in your_project/resources/views/admin/assets/ with html-blade content e.g:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>my page</title>
</head>
<body>
<div>Price: {{ $price }}</div>
<div>Dep: {{ $dep }}</div>
<div>Net price: {{ $netprice }}</div>
</body>
</html>
more info here. And remove first return statement and change last return to
return view('admin.assets.index', compact('price','dep','netprice'));

Route [/createhotel] not defined. laravel 5.4

This is my index view page.
#extends('layouts.app')
<!DOCTYPE html>
<html lang="en">
<head>
<link href="css/hotel.css" rel="stylesheet" type="text/css"/>
</head>
<body>
#section('content')
<h2>Hotels</h2>
<div class="container-fluid sug-1">
<div class="ui_column is-12 h1 ui_header sug-1head">{{ $data[0]->city}}
</div>
<div style="display:flex; flex-direction: row; justify-content: center; align-items: center">
#for ($i = 0; $i < 4; $i++)
<div class= "img__wrap">
<form method="get" action="/hotel/viewpost.blade.php">
<img class = "img__img" src={{asset($data[$i]->image)}} alt="Logo" style="width:90%;height:90%" >
<p class = "img__description"> {{$data[$i]->name}} <br> {{$data[$i]->rating}}<br> {{$data[$i]->price}}</p>
</form>
</div>
#endfor
<input class="sug1btn" type=Button id="allsugbtn" onclick="findHotels();" value="See all"/>
</div>
#endsection
</body>
</html>
This is controller for my index:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class HotelController extends Controller
{
public function index()
{
$hotelData['data'] = \DB::table('hotels')->get();
if(count($hotelData) > 0)
{
return view("hotel.index",$hotelData);
}
else
{
return view("hotel.index");
}
}
}
I created a route from my index to viewpost i.e. following code:
#extends('layouts.app')
<!DOCTYPE html>
<html lang="en">
<head>
<link href="css/hotel.css" rel="stylesheet" type="text/css"/>
</head>
<body>
#section('content')
<div class="container-fluid sug-1">
<div class="ui_column is-12 h1 ui_header sug-1head">
</div>
<div style="display:flex; flex-direction: row; justify-content: left; align-items: left">
<div class="card">
<img src={{asset($data->image)}} alt="Image" style="width:100%">
<div class="container">
<h4><b>{{$data->name}}</b></h4>
<p>Rating: {{$data->rating}}<br>Price: {{$data->price}}</p>
</div>
</div>
<button href="{{ route('/createhotel') }}" type="button" class="btn btn-default">Left</button>
</div>
<h2>Reviews</h2>
#foreach ($reviews as $review)
<p>{{ $review->user_name }}<br>{{ $review->description }}</p>
<br><br><br>
#endforeach
#endsection
</body>
</html>
This is HotelPostController for my viewpost and createhotel:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class HotelPostsController extends Controller
{
public function show($hotelviewid)
{
$imagedata['data'] = \DB::table('hotels')->select('id','image','name','city','rating','price' )->where('id', $hotelviewid)->first();
$reviewdata['reviews'] = \DB::table('hotel_reviews')->where('hotel_id', $hotelviewid)->get();
return view("hotel.viewpost",$imagedata,$reviewdata);
}
public function createhotel()
{
return view("hotel.createhotel");
}
}
This is web.php routes file:
Route::get('/', 'HotelController#index');
Route::get('/hotel', 'HotelController#index');
Route::get('/hotel/viewpost/{hotelviewid}', 'HotelPostsController#show');
Route::get('travelapp.me/hotel/viewpost/createhotel, 'HotelPostsController#createhotel');
The problem I am facing is that in views folder I have created a sub folder by name of hotel, it has 3 files index, viewpost and createhotel. the frst page is index and when a user clicks on some post it opens in viewpost. Now from there I want to create a button that goes to the third page i.e. creathotel. I have created a funtion in controller also added routes but it gives the error of undefined routes.
Change
Route::get('travelapp.me/hotel/viewpost/createhotel, 'HotelPostsController#createhotel');
to
Route::get('/hotel/viewpost/createhotel, 'HotelPostsController#createhotel');
And your button to go to create page:
Create Hotel
The method url() will give you the full URL automatically. You just need to create URL from root (/) and you dont have to attache full domain.
You can do like this (Just an example)
Route::get('/hotel-create, 'HotelPostsController#createhotel');
and button to go to that page
Create Hotel
Now in this example, When you click on Create Hotel link, this will gonna call the method createhotel() of HotelPostsController controller.
Update:
Problem
In your controller you are not passing any data to the view
public function createhotel()
{
return view("hotel.createhotel");
}
So how can you access the variable called $data on
<img src={{asset($data->image)}} alt="Image" style="width:100%">
Solution: (Pass your data to template)
public function createhotel()
{
$imagedata['data'] = \DB::table('hotels')->select('id','image','name','city','rating','price' )->where('id', $hotelviewid)->first();
$reviewdata['reviews'] = \DB::table('hotel_reviews')->where('hotel_id', $hotelviewid)->get();
return view("hotel.createhotel",$imagedata,$reviewdata);
}
The route() helper method accepts the name as the parameter, not the actual route.
route('create') is what you want. To use the url, url('/hotel/create').
Route::get('/hotel/create', 'HotelReviewController#create')->name('create');
change it to
Route::get('/hotel/create', 'HotelReviewController#create')->name('createhotel');
it will work i hope. you are using named route read here about routing.
https://laravel.com/docs/5.6/routing#named-routes
in your index action value filled by a view blade page and it seems wrong
<form method="get" action="/hotel/viewpost.blade.php">
and in viewpost you need to change {{ route("/create") }} to {!! route("create")!!}

new to CRUD in Laravel 5

I'm very new to Laravel 5. I'm currently doing a task project with CRUD functions. I did the delete function, but update and add are still messy. Please help me.
My database has only 1 table, 'tasks' with 3 columns: id, name and day.
My TaskModel:
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class TasksModel extends Model {
//
protected $table = 'tasks';
}
Here is my home view:
<html>
<header>
<style>
.wrapper{
width:600px;
margin:auto;
}
</style>
<title>Tasks List</title>
</header>
<body>
<div class="wrapper">
<h2 align="center"><font color="#a52a2a">Task List</font></h2>
<table name ="todo_table" border="1px" cellspacing="0" width = "600px">
<tr align="center">
<td>ID</td>
<td>Name</td>
<td>Time</td>
<td>Action</td>
</tr>
<?php
$records = \App\TasksModel::all()->sortBy('id');
foreach($records as $mytask)
{
?>
<tr align="center">
<td><?php echo $mytask->id; ?></td>
<td width="200px"><?php echo $mytask->name; ?></td>
<td><?php echo $mytask->day; ?></td>
<td width="100px">
<img src = "/public/images/add.jpg" width="30px" height="30px">
<img src = "/public/images/del.jpg" width="30px" height="`30px">
<img src = "/public/images/update.jpg" width="30px" height="30px">
</td>
</tr>
<?php
}// End of foreach($records as $mytask)
?>
</table>
</div>
</body>
</html>
Here's my Add view:
<html>
<head>
<style>
.wrapper{
width:600px;
margin:auto;
}
</style>
</head>
<body>
<div>
{!! Form::open(array('url' => 'process', 'method' => 'post')) !!}
<div class="wrapper">
<h2><font color="#a52a2a">Add Task</font></h2>
<p><input type = "text" name = "new-task" placeholder = "Add new task..." /></p>
<p><input type = "text" name = "new-time" placeholder = "Add new time..." /></p>
{!! Form::submit('Add', array('name' => 'bt_add')) !!}
</div>
{!! Form::close() !!}
</div>
</body>
</html>
My Route:
Route::get('/', 'HomeController#index');
Route::get('add', 'HoneController#add');
Route::get('delete/id={del}', 'HomeController#delete');
Route::get('update/id={edit}', 'HomeController#update');
Route::get('process', 'ProcessController#index'); // I think process page will handle update/add
You don't need to do CRUD manually, Laravel can do that automatically using RESTFul Controllers.
Take a look here:
http://laravel.com/docs/5.0/controllers#restful-resource-controllers
To build the RESTFul URLs you use route method
http://laravel.com/docs/5.0/helpers#urls
simple :)
First off the below belongs in your Task controller. Your view should be dumb. There is basically no reason to insert raw php into a view file.
<?php
$records = \App\TasksModel::all()->sortBy('id');
foreach($records as $mytask)
{
...
}
?>
You'll have your TasksController respond to the route and prepare the data for the view. Then in the view do something like:
#foreach($tasks as $task)
...
#endforeach
Your routes should be updated to:
Route::delete('task/{id}', TaskController#delete);
Your form will need to have a method of delete as well.
You can do CRUD in laravel easily by following these steps
Route::group(['prefix' => 'admin'], function () {
...
Route::resource('/categories', 'admin\CategoryController');
...
});
Create the resource using PHP artisan command available in Laravel
php artisan make:controller CategoryController --resource
This will create the resource controller and you will have emtpy methods index, store, update, show, destroy.
You can then tie your methods to views
For detailed explaination please follow the tutorial at
http://deepdivetuts.com/basic-create-edit-update-delete-functionality-laravel-5-3

using $this in view file codeIgniter

im a newbie in CI, i have some question
i have controller like below
public function show_admin()
{
$data['data_admin'] = $this->M_Admin->get_admin();
$data['page'] = 'show_admin';
$this->load->view('admin/template',$data);
}
and then i have template in my view folder, like below
<body>
<div id="wrapper">
<div id="header">
<?php
$data['session'] = $this->session->all_userdata();
$this->load->view('admin/header',$data);?>
<div id="content">
<?php
$this->load->view('admin/'.$page);?>
</div>
<div id="footer">
<?php $this->load->view('admin/footer');?>
</div>
</div>
</body>
and the show_admin (view file) like below
<div id="isi_content">
<span><img src="<?php echo base_url();?>assets/admin/images/add.png">Tambah</span>
<table class="table table-hover table-bordered">
<tr>
<th>No</th>
<th>Nama</th>
<th>Username</th>
<th>Login Terakhir</th>
<th>Aksi</th>
</tr>
<?php
$no=1;
foreach($data_admin as $admin){
$id = $admin['id_admin'];
$url = site_url('admin/C_Admin/c_delete_admin');
echo
'<tr>
<td>'.$no.'</td>
<td>'.$admin['nama_admin'].'</td>
<td>'.$admin['username'].'</td>
<td>'.$admin['tgl_last_visit'].'</td>
<td class=aksi><a href='.site_url('admin/C_Admin/c_edit_admin/'.$admin['id_admin'].'').'><img src='.base_url().'assets/admin/images/edit.png></a>
<img src='.base_url().'assets/admin/images/delete.png></td>
</tr>';
$no++;
}
?>
</table>
</div>
and that codes run nicely,
is that normal in codeIgniter use $this in view file??
im confuse about this..
thanks for your answer...
No, you should not use that session variable nor load any views on another view. This all should be done in the Controller. What you can do is break your code in pieces, like the header in its one view file and the footer in another view file, then you can load them in your controller like so:
public function show_admin()
{
$data['data_admin'] = $this->M_Admin->get_admin();
$data['page'] = 'show_admin';
$head_data['session'] = $this->session->all_userdata();
$this->load->view('header', $head_data);
$this->load->view('admin/template',$data);
$this->load->view('footer');
}

Resources