1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-08 12:12:48 +01:00

Local Pdf generation #886

This commit is contained in:
Hillel Coren 2017-01-02 20:47:40 +02:00
parent 9632b437ce
commit d0cb07eb2d
7 changed files with 426 additions and 61 deletions

View File

@ -26,6 +26,8 @@ MAILGUN_SECRET=
#POSTMARK_API_TOKEN= #POSTMARK_API_TOKEN=
PHANTOMJS_CLOUD_KEY='a-demo-key-with-low-quota-per-ip-address' PHANTOMJS_CLOUD_KEY='a-demo-key-with-low-quota-per-ip-address'
#PHANTOMJS_BIN_PATH=/usr/local/bin/phantomjs
LOG=single LOG=single
REQUIRE_HTTPS=false REQUIRE_HTTPS=false
API_SECRET=password API_SECRET=password

View File

@ -1,5 +1,7 @@
<?php namespace App\Libraries; <?php namespace App\Libraries;
use JonnyW\PhantomJs\Client;
class CurlUtils class CurlUtils
{ {
public static function post($url, $data, $headers = false) public static function post($url, $data, $headers = false)
@ -38,4 +40,28 @@ class CurlUtils
return $response; return $response;
} }
public static function phantom($method, $url)
{
if ( ! $path = env('PHANTOMJS_BIN_PATH')) {
return false;
}
$client = Client::getInstance();
$client->getEngine()->setPath($path);
$request = $client->getMessageFactory()->createRequest($url, $method);
$response = $client->getMessageFactory()->createResponse();
// Send the request
$client->send($request, $response);
if ($response->getStatus() === 200) {
return $response->getContent();
} else {
//$response->getStatus();
return false;
}
}
} }

View File

@ -10,6 +10,7 @@ use App\Events\InvoiceWasCreated;
use App\Events\InvoiceWasUpdated; use App\Events\InvoiceWasUpdated;
use App\Events\InvoiceInvitationWasEmailed; use App\Events\InvoiceInvitationWasEmailed;
use App\Events\QuoteInvitationWasEmailed; use App\Events\QuoteInvitationWasEmailed;
use App\Libraries\CurlUtils;
/** /**
* Class Invoice * Class Invoice
@ -1126,21 +1127,23 @@ class Invoice extends EntityModel implements BalanceAffecting
*/ */
public function getPDFString() public function getPDFString()
{ {
if (!env('PHANTOMJS_CLOUD_KEY')) { if ( ! env('PHANTOMJS_CLOUD_KEY') && ! env('PHANTOMJS_BIN_PATH')) {
return false; return false;
} }
$invitation = $this->invitations[0]; $invitation = $this->invitations[0];
$link = $invitation->getLink('view', true); $link = $invitation->getLink('view', true);
$key = env('PHANTOMJS_CLOUD_KEY');
if (Utils::isNinjaDev()) { if (env('PHANTOMJS_BIN_PATH')) {
$link = env('TEST_LINK'); $pdfString = CurlUtils::phantom('GET', $link . '?phantomjs=true');
} elseif ($key = env('PHANTOMJS_CLOUD_KEY')) {
if (Utils::isNinjaDev()) {
$link = env('TEST_LINK');
}
$url = "http://api.phantomjscloud.com/api/browser/v2/{$key}/?request=%7Burl:%22{$link}?phantomjs=true%22,renderType:%22html%22%7D";
$pdfString = CurlUtils::get($url);
} }
$url = "http://api.phantomjscloud.com/api/browser/v2/{$key}/?request=%7Burl:%22{$link}?phantomjs=true%22,renderType:%22html%22%7D";
$pdfString = file_get_contents($url);
$pdfString = strip_tags($pdfString); $pdfString = strip_tags($pdfString);
if ( ! $pdfString || strlen($pdfString) < 200) { if ( ! $pdfString || strlen($pdfString) < 200) {

View File

@ -83,7 +83,8 @@
"jaybizzle/laravel-crawler-detect": "1.*", "jaybizzle/laravel-crawler-detect": "1.*",
"codedge/laravel-selfupdater": "5.x-dev", "codedge/laravel-selfupdater": "5.x-dev",
"predis/predis": "^1.1", "predis/predis": "^1.1",
"nwidart/laravel-modules": "^1.14" "nwidart/laravel-modules": "^1.14",
"jonnyw/php-phantomjs": "4.*"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "~4.0", "phpunit/phpunit": "~4.0",

425
composer.lock generated
View File

@ -4,8 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"hash": "7e547dba71449ade427b93dc8b108e0f", "hash": "10dafe2e4414d132b3901b8950150c31",
"content-hash": "c05b529acf38d8dd1ab5452432e67887", "content-hash": "1e2d58c1e958d77ff76b29acccea8585",
"packages": [ "packages": [
{ {
"name": "agmscode/omnipay-agms", "name": "agmscode/omnipay-agms",
@ -2705,6 +2705,47 @@
], ],
"time": "2014-11-20 16:49:30" "time": "2014-11-20 16:49:30"
}, },
{
"name": "jakoch/phantomjs-installer",
"version": "2.1.1",
"source": {
"type": "git",
"url": "https://github.com/jakoch/phantomjs-installer.git",
"reference": "b8ee2aac9b95f9a9ee30a05a4df4a0984a8a8b85"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/jakoch/phantomjs-installer/zipball/b8ee2aac9b95f9a9ee30a05a4df4a0984a8a8b85",
"reference": "b8ee2aac9b95f9a9ee30a05a4df4a0984a8a8b85",
"shasum": ""
},
"require": {
"ext-openssl": "*"
},
"type": "custom-installer",
"autoload": {
"psr-0": {
"PhantomInstaller\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jens-André Koch",
"email": "jakoch@web.de"
}
],
"description": "A Composer package which installs the PhantomJS binary (Linux, Windows, Mac) into `/bin` of your project.",
"keywords": [
"binaries",
"headless",
"phantomjs"
],
"time": "2016-01-25 16:30:30"
},
{ {
"name": "jakub-onderka/php-console-color", "name": "jakub-onderka/php-console-color",
"version": "0.1", "version": "0.1",
@ -2992,6 +3033,62 @@
], ],
"time": "2016-01-25 15:38:17" "time": "2016-01-25 15:38:17"
}, },
{
"name": "jonnyw/php-phantomjs",
"version": "v4.5.1",
"source": {
"type": "git",
"url": "https://github.com/jonnnnyw/php-phantomjs.git",
"reference": "cf8d9a221f4c624aa1537c55a2e181f4b50367d7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/jonnnnyw/php-phantomjs/zipball/cf8d9a221f4c624aa1537c55a2e181f4b50367d7",
"reference": "cf8d9a221f4c624aa1537c55a2e181f4b50367d7",
"shasum": ""
},
"require": {
"jakoch/phantomjs-installer": "2.1.1",
"php": ">=5.3.0",
"symfony/config": "~2.3|~3.0",
"symfony/dependency-injection": "~2.3|~3.0",
"symfony/filesystem": "~2.3|~3.0",
"symfony/yaml": "~2.3|~3.0",
"twig/twig": "~1.16"
},
"require-dev": {
"phpunit/phpunit": "~4.0",
"smalot/pdfparser": "~0.9",
"zendframework/zendpdf": "~2.0"
},
"type": "library",
"autoload": {
"psr-0": {
"JonnyW\\PhantomJs\\": "src"
},
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jonny Wenmoth",
"email": "contact@jonnyw.me",
"homepage": "http://jonnyw.me/"
}
],
"description": "A PHP wrapper for loading pages through PhantomJS",
"keywords": [
"Headless Browser",
"phantomjs",
"testing"
],
"time": "2016-06-28 16:00:15"
},
{ {
"name": "justinbusschau/omnipay-secpay", "name": "justinbusschau/omnipay-secpay",
"version": "2.0.6", "version": "2.0.6",
@ -7098,6 +7195,62 @@
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2016-07-10 08:05:47" "time": "2016-07-10 08:05:47"
}, },
{
"name": "symfony/config",
"version": "v3.2.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/config.git",
"reference": "b4ec9f099599cfc5b7f4d07bb2e910781a2be5e4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/config/zipball/b4ec9f099599cfc5b7f4d07bb2e910781a2be5e4",
"reference": "b4ec9f099599cfc5b7f4d07bb2e910781a2be5e4",
"shasum": ""
},
"require": {
"php": ">=5.5.9",
"symfony/filesystem": "~2.8|~3.0"
},
"require-dev": {
"symfony/yaml": "~3.0"
},
"suggest": {
"symfony/yaml": "To use the yaml reference dumper"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.2-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\Config\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Config Component",
"homepage": "https://symfony.com",
"time": "2016-12-09 07:45:17"
},
{ {
"name": "symfony/console", "name": "symfony/console",
"version": "v3.0.9", "version": "v3.0.9",
@ -7268,6 +7421,66 @@
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2016-07-30 07:22:48" "time": "2016-07-30 07:22:48"
}, },
{
"name": "symfony/dependency-injection",
"version": "v3.1.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/dependency-injection.git",
"reference": "bd2a915cd29ccfc93c2835765a8b06dd1cc83aa9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/bd2a915cd29ccfc93c2835765a8b06dd1cc83aa9",
"reference": "bd2a915cd29ccfc93c2835765a8b06dd1cc83aa9",
"shasum": ""
},
"require": {
"php": ">=5.5.9"
},
"require-dev": {
"symfony/config": "~2.8|~3.0",
"symfony/expression-language": "~2.8|~3.0",
"symfony/yaml": "~2.8.7|~3.0.7|~3.1.1|~3.2"
},
"suggest": {
"symfony/config": "",
"symfony/expression-language": "For using expressions in service container configuration",
"symfony/proxy-manager-bridge": "Generate service proxies to lazy load them",
"symfony/yaml": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.1-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\DependencyInjection\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony DependencyInjection Component",
"homepage": "https://symfony.com",
"time": "2016-12-08 14:58:14"
},
{ {
"name": "symfony/event-dispatcher", "name": "symfony/event-dispatcher",
"version": "v2.8.14", "version": "v2.8.14",
@ -7328,6 +7541,55 @@
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2016-10-13 01:43:15" "time": "2016-10-13 01:43:15"
}, },
{
"name": "symfony/filesystem",
"version": "v3.2.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
"reference": "8d4cf7561a5b17e5eb7a02b80d0b8f014a3796d4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/8d4cf7561a5b17e5eb7a02b80d0b8f014a3796d4",
"reference": "8d4cf7561a5b17e5eb7a02b80d0b8f014a3796d4",
"shasum": ""
},
"require": {
"php": ">=5.5.9"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.2-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\Filesystem\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Filesystem Component",
"homepage": "https://symfony.com",
"time": "2016-11-24 00:46:43"
},
{ {
"name": "symfony/finder", "name": "symfony/finder",
"version": "v3.0.9", "version": "v3.0.9",
@ -8100,6 +8362,55 @@
], ],
"time": "2016-07-26 08:03:56" "time": "2016-07-26 08:03:56"
}, },
{
"name": "symfony/yaml",
"version": "v3.1.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "1819adf2066880c7967df7180f4f662b6f0567ac"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/1819adf2066880c7967df7180f4f662b6f0567ac",
"reference": "1819adf2066880c7967df7180f4f662b6f0567ac",
"shasum": ""
},
"require": {
"php": ">=5.5.9"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.1-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\Yaml\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
"time": "2016-07-17 14:02:08"
},
{ {
"name": "tijsverkoyen/css-to-inline-styles", "name": "tijsverkoyen/css-to-inline-styles",
"version": "1.5.5", "version": "1.5.5",
@ -8286,6 +8597,67 @@
], ],
"time": "2016-07-25 15:51:55" "time": "2016-07-25 15:51:55"
}, },
{
"name": "twig/twig",
"version": "v1.30.0",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
"reference": "c6ff71094fde15d12398eaba029434b013dc5e59"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/c6ff71094fde15d12398eaba029434b013dc5e59",
"reference": "c6ff71094fde15d12398eaba029434b013dc5e59",
"shasum": ""
},
"require": {
"php": ">=5.2.7"
},
"require-dev": {
"symfony/debug": "~2.7",
"symfony/phpunit-bridge": "~3.2@dev"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.30-dev"
}
},
"autoload": {
"psr-0": {
"Twig_": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Armin Ronacher",
"email": "armin.ronacher@active-4.com",
"role": "Project Founder"
},
{
"name": "Twig Team",
"homepage": "http://twig.sensiolabs.org/contributors",
"role": "Contributors"
}
],
"description": "Twig, the flexible, fast, and secure template language for PHP",
"homepage": "http://twig.sensiolabs.org",
"keywords": [
"templating"
],
"time": "2016-12-23 11:06:22"
},
{ {
"name": "vink/omnipay-komoju", "name": "vink/omnipay-komoju",
"version": "v1.0", "version": "v1.0",
@ -10581,55 +10953,6 @@
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2016-07-26 08:04:17" "time": "2016-07-26 08:04:17"
}, },
{
"name": "symfony/yaml",
"version": "v3.1.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "1819adf2066880c7967df7180f4f662b6f0567ac"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/1819adf2066880c7967df7180f4f662b6f0567ac",
"reference": "1819adf2066880c7967df7180f4f662b6f0567ac",
"shasum": ""
},
"require": {
"php": ">=5.5.9"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.1-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\Yaml\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
"time": "2016-07-17 14:02:08"
},
{ {
"name": "webmozart/assert", "name": "webmozart/assert",
"version": "1.1.0", "version": "1.1.0",

View File

@ -2295,6 +2295,8 @@ $LANG = array(
'inclusive' => 'Inclusive', 'inclusive' => 'Inclusive',
'exclusive' => 'Exclusive', 'exclusive' => 'Exclusive',
'postal_city_state' => 'Postal/City/State', 'postal_city_state' => 'Postal/City/State',
'phantomjs_help' => 'In certain cases the app uses :link_phantom to generate the PDF, install :link_docs to generate it locally.',
); );
return $LANG; return $LANG;

View File

@ -27,8 +27,16 @@
<h3 class="panel-title">{!! trans('texts.email_settings') !!}</h3> <h3 class="panel-title">{!! trans('texts.email_settings') !!}</h3>
</div> </div>
<div class="panel-body form-padding-right"> <div class="panel-body form-padding-right">
{!! Former::checkbox('pdf_email_attachment')->text(trans('texts.enable')) !!}
{!! Former::checkbox('document_email_attachment')->text(trans('texts.enable')) !!} {!! Former::checkbox('pdf_email_attachment')
->text(trans('texts.enable'))
->help( Utils::isNinja() ? trans('texts.phantomjs_help', [
'link_phantom' => link_to('https://phantomjscloud.com/', 'phantomjscloud.com', ['target' => '_blank']),
'link_docs' => link_to('https://www.invoiceninja.com/self-host/#phantomjs', 'PhantomJS', ['target' => '_blank'])
]) : false) !!}
{!! Former::checkbox('document_email_attachment')
->text(trans('texts.enable')) !!}
&nbsp; &nbsp;