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