Html2Pdf.php 3.73 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<?php
/**
 * Created by PhpStorm.
 * User: crose
 * Date: 4/17/17
 * Time: 10:17 PM
 */

namespace qfq;

require_once(__DIR__ . '/../store/Config.php');
require_once(__DIR__ . '/../Constants.php');
require_once(__DIR__ . '/../helper/KeyValueStringParser.php');


class Html2Pdf {

    /**
     * @var array
     */
    private $config = array();

    /**
     * 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.
     *
     * @param array $config
     * @throws UserFormException
     * @throws \exception
     */
    public function __construct(array $config = array()) {

        if (count($config) == 0) {
            $cfg = new Config();

            $config = $cfg->readConfig('');
        }

        $this->config = $config;

        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.');
        }
    }

    /**
     * Return an array with GET params who are clean - they do not violate $pattern.
     *
     * @return array
     */
    private function readCleanGetParam(array $get) {

        $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;
    }

    /**
     * Set HTML Header to initiate PDF download.
     *
     * @param $filename
     */
    private function setHeader($filename) {

        header("Content-Disposition: inline; filename=\"$filename\"");
        header("Content-Type: application/pdf");
        header("Content-Transfer-Encoding: binary");
    }

    /**
     * @return string
     * @throws \exception
     */
    public function page2pdf(array $get) {

        if (!isset($get[HTML2PDF_PAGEID]) || $get[HTML2PDF_PAGEID] == '') {
            throw new \exception("Missing GET Parameter '" . HTML2PDF_PAGEID . "'.");
        }

        $urlPrint = escapeshellarg($this->config[SYSTEM_BASE_URL_PRINT] . '/?' . KeyValueStringParser::unparse($get, '=', '&'));
        $wkhtml = $this->config[SYSTEM_WKHTMLTOPDF];

        $rc = 0;
        $filename = tempnam(sys_get_temp_dir(), DOWNLOAD_FILE_PREFIX);
        $filenameEscape = escapeshellarg($filename);

//        $cmd = $wkhtml . " '" . $urlPrint . "' " . $filename . " > $filename.log 2>&1";
//        $cmd = "$wkhtml '$urlPrint' $filename > $filename.log 2>&1";
        $cmd = "$wkhtml $urlPrint $filenameEscape";

        $line = system($cmd, $rc);

        if ($rc != 0) {
            throw new \exception("Error [RC=$rc] $line: $cmd");
        }

        return $filename;
    }

    /**
     * @throws \exception
     */
    public function outputHtml2Pdf() {

        $get = $this->readCleanGetParam($_GET);
        $pageId = Support::setIfNotSet($get, HTML2PDF_PAGEID, 0);

        $filename = $this->page2pdf($get);

        $this->setHeader('print.' . $pageId . '.pdf');
        @readfile($filename);
        @unlink($filename);
//        @unlink($filename . '.log');

        exit; // Do an extremely hard exit here to make sure there are no more additional bytes sent (makes the delivered PDF unusable).

    }

}