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
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
native driver (see also: http://dev.mysql.com/downloads/connector/php-mysqlnd/):
......@@ -34,6 +37,34 @@ Preparation steps for Ubuntu 16.04::
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
-----
......@@ -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 |
+-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| 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*
......@@ -190,6 +224,8 @@ Example: *typo3conf/config.qfq.ini*
;FORM_BS_LABEL_COLUMNS = 3
;FORM_BS_INPUT_COLUMNS = 6
;FORM_BS_NOTE_COLUMNS = 3
BASE_URL_PRINT=http://example.com
WKHTMLTOPDF=/usr/bin/wkhtmltopdf
Documentation
-------------
......
......@@ -41,3 +41,7 @@ DATE_FORMAT = yyyy-mm-dd
;FORM_BS_LABEL_COLUMNS = 3
;FORM_BS_INPUT_COLUMNS = 6
;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';
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
const SYSTEM_PATH_EXT = 'EXT_PATH';
const SYSTEM_SITE_PATH = 'SITE_PATH';
......
Markdown is supported
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