Subversion Repositories ALCASAR

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log

<?php
/**
 * ALCASAR tickets generator
 *
 * Generate tickets of users.
 * Use wkhtmltopdf to convert HTML to PDF.
 *
 * @author    Tom Houdayer
 * @copyright Copyright (C) ALCASAR (http://www.alcasar.net)
 * @license   GPL-3.0
 * @version   $Id: TicketsGenerator.php 2168 2017-04-18 17:39:54Z tom.houdayer $
 */

class TicketsGenerator
{
        /**
         * @var string Path to wkhtmltopdf executable.
         */
        private $wkhtmltopdfPath = 'wkhtmltopdf';

        /**
         * @var object[] Tickets of users.
         */
        private $tickets = [];

        /**
         * @var string Language of tickets.
         */
        private $language = 'en';

        /**
         * @var string HTML template filename.
         */
        private $template = __DIR__ . '/' . 'tickets.template.php';

        /**
         * @var string|null HTML generated filename (null if not generated).
         */
        private $htmlGeneratedFilename;

        /**
         * Constructor.
         *
         * @param array $options Options of the instance.
         */
        public function __construct($options = [])
        {
                if (isset($options['wkhtmltopdfPath'])) {
                        $this->wkhtmltopdfPath = $options['wkhtmltopdfPath'];
                }
                if (isset($options['language'])) {
                        $this->language = $options['language'];
                }
                if (isset($options['template'])) {
                        $this->template = $options['template'];
                }
        }

        /**
         * Add a ticket.
         *
         * @param array $user      User.
         * @param bool  $duplicate Print a duplicated ticket if true.
         */
        public function addTicket($user, $duplicate = true)
        {
                $this->tickets[] = (object) [
                        'username'        => $user['username'],
                        'password'        => $user['password'],
                        'maxAllSession'   => $user['maxAllSession'],
                        'sessionTimeout'  => $user['sessionTimeout'],
                        'maxDailySession' => $user['maxDailySession'],
                        'expiration'      => ((isset($user['expiration'])) ? $user['expiration'] : '-'),
                        'isDuplicate'     => false
                ];
                if ($duplicate) {
                        $this->tickets[] = (object) [
                                'username'        => $user['username'],
                                'password'        => $user['password'],
                                'maxAllSession'   => $user['maxAllSession'],
                                'sessionTimeout'  => $user['sessionTimeout'],
                                'maxDailySession' => $user['maxDailySession'],
                                'expiration'      => ((isset($user['expiration'])) ? $user['expiration'] : '-'),
                                'isDuplicate'     => true
                        ];
                }
        }

        /**
         * Generate and save the PDF to the filesystem.
         *
         * @param string $filename File name of the generated PDF.
         *
         * @return bool Result of the convertion (true if success).
         */
        public function saveAs($filename)
        {
                if (file_exists($filename)) {
                        return false;
                }

                // TODO: Regex validation of $filename

                if (!$this->generateHtml("$filename.html")) {
                        return false;
                }

                $command = $this->wkhtmltopdfPath . ' --quiet --disable-smart-shrinking --footer-font-size 8 --footer-left "ALCASAR" --footer-center "[page] / [toPage]" --footer-right "' . date('Y-m-d H:i:s') . '" ' . escapeshellarg("$filename.html") . ' ' . escapeshellarg($filename);
                $output;
                $exitCode;
                exec($command, $output, $exitCode);

                unlink("$filename.html");

                if ($exitCode !== 0) {
                        return false;
                }

                return true;
        }

        /**
         * Send the PDF to the  browser.
         *
         * @return bool Result of the convertion (true if success).
         */
        public function output()
        {
                $filename = tempnam('/tmp', 'ALCASAR-PDF_');
                unlink($filename);

                if (!$this->saveAs($filename)) {
                        return false;
                }

                header('Content-Type: application/pdf');
                header('Content-Disposition: inline; filename="tickets.pdf"');
                header('Cache-Control: private, max-age=0, must-revalidate');
                header('Pragma: public');
                readfile($filename);

                unlink($filename);

                return true;
        }

        /**
         * Generate HTML document from the template.
         *
         * @param string $output File name of the generated template.
         *
         * @return bool Result of the generation (true if success).
         */
        private function generateHtml($output)
        {
                if (file_exists($output)) {
                        return false;
                }

                if (!file_exists($this->template)) {
                        return false;
                }

                $language = $this->language;
                $users    = $this->tickets;

                ob_start();
                require($this->template);
                $content = ob_get_clean();

                $ret = file_put_contents($output, $content);
                if ($ret === false) {
                        return false;
                }

                return true;
        }
}