Commit 314c6706 authored by Carsten  Rose's avatar Carsten Rose
Browse files

print.php / wkhtmltopdf: wrapper to offer HTML to PDF conversion.

Index.rst: Update Administratormanual how to install and use print.php.
print.php: wrapper for wkhtmltopdf.
parent 2ad562bd
...@@ -14,6 +14,9 @@ Administrator Manual ...@@ -14,6 +14,9 @@ Administrator Manual
Preparation Preparation
----------- -----------
Report & Form
^^^^^^^^^^^^^
The QFQ extension needs in PHP 5.x the PHP MySQL native driver. The following functions are used and are only available with the The QFQ extension needs in PHP 5.x the PHP MySQL native driver. The following functions are used and are only available with the
native driver (see also: http://dev.mysql.com/downloads/connector/php-mysqlnd/): native driver (see also: http://dev.mysql.com/downloads/connector/php-mysqlnd/):
...@@ -34,6 +37,34 @@ Preparation steps for Ubuntu 16.04:: ...@@ -34,6 +37,34 @@ Preparation steps for Ubuntu 16.04::
sudo apt install php7.0-intl sudo apt install php7.0-intl
Print page via wkhtmltopdf
^^^^^^^^^^^^^^^^^^^^^^^^^^
Different browser prints the same page in different variations. To prevent this, QFQ implements a small PHP wrapper `print.php`
which uses http://wkhtmltopdf.org/ (webkit based) to convert HTML to PDF. The converter is not included in QFQ and has
to be manually installed.
Hint: The Ubuntu package `wkhtmltopdf` needs a running Xserver - this does not work on a headless webserver. Best is to
install the QT version from the named website above.
In config.qfq.ini specify the:
* installed `wkhtmltopdf` binary,
* the site base URL.
Provide a `print this page`-link (replace {current pageId})::
<a href="typo3conf/ext/qfq/qfq/api/print.php?id={current pageId}">Print this page</a>
Any parameter specified after `print.php` will be delivered to `wkhtmltopdf` as part of the URL.
Typoscript code to implement a print link on every page::
10 = TEXT
10 {
wrap = <a href="typo3conf/ext/qfq/qfq/api/print.php?id=|&type=2"><span class="glyphicon glyphicon-print" aria-hidden="true"></span> Printview</a>
data = page:uid
}
Setup Setup
----- -----
...@@ -162,7 +193,10 @@ config.qfq.ini ...@@ -162,7 +193,10 @@ config.qfq.ini
+-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+ +-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| FORM_BUTTON_ON_CHANGE_CLASS | FORM_BUTTON_ON_CHANGE_CLASS=alert-info btn-info | Color for save button after modification | | FORM_BUTTON_ON_CHANGE_CLASS | FORM_BUTTON_ON_CHANGE_CLASS=alert-info btn-info | Color for save button after modification |
+-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+ +-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| BASE_URL_PRINT | BASE_URL_PRINT=http://example.com | URL where wkhtmltopdf will fetch the HTML (no parameter, those comes later)|
+-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| WKHTMLTOPDF | WKHTMLTOPDF=/usr/bin/wkhtmltopdf | Binary where to find wkhtmltopdf |
+-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
Example: *typo3conf/config.qfq.ini* Example: *typo3conf/config.qfq.ini*
...@@ -190,6 +224,8 @@ Example: *typo3conf/config.qfq.ini* ...@@ -190,6 +224,8 @@ Example: *typo3conf/config.qfq.ini*
;FORM_BS_LABEL_COLUMNS = 3 ;FORM_BS_LABEL_COLUMNS = 3
;FORM_BS_INPUT_COLUMNS = 6 ;FORM_BS_INPUT_COLUMNS = 6
;FORM_BS_NOTE_COLUMNS = 3 ;FORM_BS_NOTE_COLUMNS = 3
BASE_URL_PRINT=http://example.com
WKHTMLTOPDF=/usr/bin/wkhtmltopdf
Documentation Documentation
------------- -------------
......
...@@ -41,3 +41,7 @@ DATE_FORMAT = yyyy-mm-dd ...@@ -41,3 +41,7 @@ DATE_FORMAT = yyyy-mm-dd
;FORM_BS_LABEL_COLUMNS = 3 ;FORM_BS_LABEL_COLUMNS = 3
;FORM_BS_INPUT_COLUMNS = 6 ;FORM_BS_INPUT_COLUMNS = 6
;FORM_BS_NOTE_COLUMNS = 3 ;FORM_BS_NOTE_COLUMNS = 3
; Configure URL where `wkhtmltopdf` fetches pages and produces PDFs
BASE_URL_PRINT = http://example.com/
WKHTMLTOPDF = /opt/wkhtmltox/bin/wkhtmltopdf
<?php
/**
* Created by PhpStorm.
* User: ep
* Date: 12/23/15
* Time: 6:17 PM
*/
namespace qfq;
use qfq;
require_once(__DIR__ . '/../qfq/store/Config.php');
require_once(__DIR__ . '/../qfq/Constants.php');
require_once(__DIR__ . '/../qfq/helper/KeyValueStringParser.php');
const PAGEID = 'id';
const PARAM_GET = 'paramGet';
const URL_PRINT = 'urlPrint';
/**
* Create a temporary file.
*
* @return string
*/
function createEmptyFile() {
return tempnam(sys_get_temp_dir(), "webkitPrintPdf");
}
/**
* Set HTML Header to initiate PDF download.
*
* @param $filename
*/
function setHeader($filename) {
header("Content-Disposition: inline; filename=\"$filename\"");
header("Content-Type: application/pdf");
header("Content-Transfer-Encoding: binary");
}
/**
* Read QFQ config. Only SYSTEM_BASE_URL_PRINT and SYSTEM_WKHTMLTOPDF will be used.
* Check and get all clean _GET Parameter. Build a URL based on SYSTEM_BASE_URL_PRINT and the delivered URL params.
*
* @return array
* @throws UserFormException
* @throws \exception
*/
function init() {
$cfg = new Config();
$config = $cfg->readConfig('');
$param = readCleanGetParam();
if (!isset($config[SYSTEM_BASE_URL_PRINT]) || $config[SYSTEM_BASE_URL_PRINT] == '') {
throw new \exception(CONFIG_INI . ' - Missing ' . SYSTEM_BASE_URL_PRINT);
}
if (!isset($config[SYSTEM_WKHTMLTOPDF]) || $config[SYSTEM_WKHTMLTOPDF] == '') {
throw new \exception(CONFIG_INI . ' - Missing ' . SYSTEM_WKHTMLTOPDF);
}
if (!is_executable($config[SYSTEM_WKHTMLTOPDF])) {
throw new \exception(CONFIG_INI . ' - ' . SYSTEM_WKHTMLTOPDF . '=' . $config[SYSTEM_WKHTMLTOPDF] . ' - not found or not executable.');
}
if (!isset($param[PAGEID]) || $param[PAGEID] == '') {
throw new \exception("Missing GET Parameter '" . PAGEID . "'.");
}
$setup = array();
$setup[URL_PRINT] = $config[SYSTEM_BASE_URL_PRINT] . '/?' . KeyValueStringParser::unparse($param, '=', '&');
$setup[PAGEID] = $param[PAGEID];
$setup[SYSTEM_WKHTMLTOPDF] = $config[SYSTEM_WKHTMLTOPDF];
return $setup;
}
;
/**
* Return an array with GET params who are clean - they do not violate $pattern.
*
* @return array
*/
function readCleanGetParam() {
$param = array();
$pattern = '^[\-_\.,;:\/a-zA-Z0-9]*$'; // ':alnum:' does not work here in FF
foreach ($_GET as $key => $value) {
if (preg_match("/$pattern/", $value) === 1) {
$param[$key] = $value;
}
}
return $param;
}
/**
* @param array $setup
* @throws \exception
*/
function page2pdf($setup) {
$rc = 0;
$file = createEmptyFile();
$cmd = $setup[SYSTEM_WKHTMLTOPDF] . " '" . $setup[URL_PRINT] . "' " . $file . " > $file.log 2>&1";
$line = system($cmd, $rc);
if ($rc == 0) {
setHeader('print.' . $setup[PAGEID] . '.pdf');
@readfile($file);
@unlink($file);
@unlink($file . '.log');
exit; // Do an extremely hard exit here to make sure there are no more additional bytes sent (makes the delivered PDF unusable).
} else {
throw new \exception("Error [RC=$rc] $line: $cmd");
}
}
/**
* Main
*/
try {
$setup = init();
page2pdf($setup);
} catch (\Exception $e) {
echo "Exception: " . $e->getMessage();
}
...@@ -322,6 +322,9 @@ const SYSTEM_FORM_BS_NOTE_COLUMNS = 'FORM_BS_NOTE_COLUMNS'; ...@@ -322,6 +322,9 @@ const SYSTEM_FORM_BS_NOTE_COLUMNS = 'FORM_BS_NOTE_COLUMNS';
const SYSTEM_FORM_BUTTON_ON_CHANGE_CLASS = 'FORM_BUTTON_ON_CHANGE_CLASS'; const SYSTEM_FORM_BUTTON_ON_CHANGE_CLASS = 'FORM_BUTTON_ON_CHANGE_CLASS';
const SYSTEM_BASE_URL_PRINT = 'BASE_URL_PRINT';
const SYSTEM_WKHTMLTOPDF = 'WKHTMLTOPDF';
// computed automatically during runtime // computed automatically during runtime
const SYSTEM_PATH_EXT = 'EXT_PATH'; const SYSTEM_PATH_EXT = 'EXT_PATH';
const SYSTEM_SITE_PATH = 'SITE_PATH'; const SYSTEM_SITE_PATH = 'SITE_PATH';
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment