mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-09 12:42:36 +01:00
Improve proposal PDF rendering
This commit is contained in:
parent
d5bf19ad98
commit
c8d44ba1b2
@ -50,4 +50,21 @@ class BaseController extends Controller
|
||||
return redirect("{$entityTypes}");
|
||||
}
|
||||
}
|
||||
|
||||
protected function downloadResponse($filename, $contents, $type = 'application/pdf')
|
||||
{
|
||||
header('Content-Type: ' . $type);
|
||||
header('Content-Length: ' . strlen($contents));
|
||||
|
||||
if (! request()->debug) {
|
||||
header('Content-disposition: attachment; filename="' . $filename . '"');
|
||||
}
|
||||
|
||||
header('Cache-Control: public, must-revalidate, max-age=0');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
|
||||
echo $contents;
|
||||
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use mPDF;
|
||||
use App\Models\Account;
|
||||
use App\Models\Document;
|
||||
use App\Models\Invitation;
|
||||
use App\Ninja\Repositories\ProposalRepository;
|
||||
use App\Jobs\ConvertProposalToPdf;
|
||||
|
||||
class ClientPortalProposalController extends BaseController
|
||||
{
|
||||
@ -39,8 +39,12 @@ class ClientPortalProposalController extends BaseController
|
||||
'proposalInvitation' => $invitation,
|
||||
];
|
||||
|
||||
if (request()->phantomjs) {
|
||||
return $proposal->present()->htmlDocument;
|
||||
} else {
|
||||
return view('invited.proposal', $data);
|
||||
}
|
||||
}
|
||||
|
||||
public function downloadProposal($invitationKey)
|
||||
{
|
||||
@ -50,9 +54,9 @@ class ClientPortalProposalController extends BaseController
|
||||
|
||||
$proposal = $invitation->proposal;
|
||||
|
||||
$mpdf = new mPDF();
|
||||
$mpdf->WriteHTML($proposal->present()->htmlDocument);
|
||||
$mpdf->Output($proposal->present()->filename, 'D');
|
||||
$pdf = dispatch(new ConvertProposalToPdf($proposal));
|
||||
|
||||
$this->downloadResponse($proposal->getFilename(), $pdf);
|
||||
}
|
||||
|
||||
public function getProposalImage($accountKey, $documentKey)
|
||||
|
@ -6,6 +6,7 @@ use App\Http\Requests\CreateProposalRequest;
|
||||
use App\Http\Requests\ProposalRequest;
|
||||
use App\Http\Requests\UpdateProposalRequest;
|
||||
use App\Jobs\SendInvoiceEmail;
|
||||
use App\Jobs\ConvertProposalToPdf;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Proposal;
|
||||
use App\Models\ProposalTemplate;
|
||||
@ -17,7 +18,6 @@ use Auth;
|
||||
use Input;
|
||||
use Session;
|
||||
use View;
|
||||
use mPDF;
|
||||
|
||||
class ProposalController extends BaseController
|
||||
{
|
||||
@ -167,14 +167,8 @@ class ProposalController extends BaseController
|
||||
{
|
||||
$proposal = $request->entity();
|
||||
|
||||
$mpdf = new mPDF();
|
||||
//$mpdf->showImageErrors = config('app.debug');
|
||||
$mpdf->WriteHTML($proposal->present()->htmlDocument);
|
||||
$pdf = dispatch(new ConvertProposalToPdf($proposal));
|
||||
|
||||
if ($request->debug) {
|
||||
$mpdf->Output();
|
||||
} else {
|
||||
$mpdf->Output($proposal->present()->filename, 'D');
|
||||
}
|
||||
$this->downloadResponse($proposal->getFilename(), $pdf);
|
||||
}
|
||||
}
|
||||
|
25
app/Jobs/ConvertProposalToPdf.php
Normal file
25
app/Jobs/ConvertProposalToPdf.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Jobs\Job;
|
||||
use App\Libraries\CurlUtils;
|
||||
|
||||
class ConvertProposalToPdf extends Job
|
||||
{
|
||||
public function __construct($proposal)
|
||||
{
|
||||
$this->proposal = $proposal;
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$proposal = $this->proposal;
|
||||
$url = $proposal->getHeadlessLink();
|
||||
|
||||
$filename = sprintf('%s/storage/app/%s.pdf', base_path(), strtolower(str_random(RANDOM_KEY_LENGTH)));
|
||||
$pdf = CurlUtils::renderPDF($url, $filename);
|
||||
|
||||
return $pdf;
|
||||
}
|
||||
}
|
@ -66,4 +66,32 @@ class CurlUtils
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function renderPDF($url, $filename)
|
||||
{
|
||||
if (! $path = env('PHANTOMJS_BIN_PATH')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$client = Client::getInstance();
|
||||
$client->isLazy();
|
||||
$client->getEngine()->addOption("--load-images=true");
|
||||
$client->getEngine()->setPath($path);
|
||||
|
||||
$request = $client->getMessageFactory()->createPdfRequest($url, 'GET');
|
||||
$request->setOutputFile($filename);
|
||||
//$request->setOrientation('landscape');
|
||||
$request->setMargin('0');
|
||||
|
||||
$response = $client->getMessageFactory()->createResponse();
|
||||
$client->send($request, $response);
|
||||
|
||||
if ($response->getStatus() === 200) {
|
||||
$pdf = file_get_contents($filename);
|
||||
unlink($filename);
|
||||
return $pdf;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -96,6 +96,25 @@ class Proposal extends EntityModel
|
||||
{
|
||||
return $this->invoice->invoice_number;
|
||||
}
|
||||
|
||||
public function getLink($forceOnsite = false, $forcePlain = false)
|
||||
{
|
||||
$invitation = $this->invitations->first();
|
||||
|
||||
return $invitation->getLink('proposal', $forceOnsite, $forcePlain);
|
||||
}
|
||||
|
||||
public function getHeadlessLink()
|
||||
{
|
||||
return sprintf('%s?phantomjs=true&phantomjs_secret=%s', $this->getLink(true, true), env('PHANTOMJS_SECRET'));
|
||||
}
|
||||
|
||||
public function getFilename($extension = 'pdf')
|
||||
{
|
||||
$entityType = $this->getEntityType();
|
||||
|
||||
return trans('texts.proposal') . '_' . $this->invoice->invoice_number . '.' . $extension;
|
||||
}
|
||||
}
|
||||
|
||||
Proposal::creating(function ($project) {
|
||||
|
7
storage/templates/clean.css
vendored
7
storage/templates/clean.css
vendored
@ -11,6 +11,7 @@ body {
|
||||
}
|
||||
|
||||
.blue-upper {
|
||||
padding-bottom: 8px;
|
||||
font-size: 11px;
|
||||
letter-spacing: 3px;
|
||||
text-transform: uppercase;
|
||||
@ -94,7 +95,7 @@ a.button:hover {
|
||||
}
|
||||
|
||||
table td {
|
||||
padding: 20px 30px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
tr.top-header {
|
||||
@ -122,10 +123,6 @@ tr.top-header p {
|
||||
padding: 0 0 120px 0;
|
||||
}
|
||||
|
||||
.card-content {
|
||||
padding: 80px 30px;
|
||||
}
|
||||
|
||||
tr.block-quote {
|
||||
margin: 50px 0 ;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user