added export context (#2216)
This commit is contained in:
@@ -9,10 +9,10 @@
|
||||
|
||||
namespace App\Export\Base;
|
||||
|
||||
use App\Export\ExportContext;
|
||||
use App\Export\ExportItemInterface;
|
||||
use App\Repository\ProjectRepository;
|
||||
use App\Repository\Query\TimesheetQuery;
|
||||
use App\Timesheet\UserDateTimeFactory;
|
||||
use App\Utils\HtmlToPdfConverter;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
|
||||
@@ -26,10 +26,6 @@ class PDFRenderer
|
||||
* @var Environment
|
||||
*/
|
||||
private $twig;
|
||||
/**
|
||||
* @var UserDateTimeFactory
|
||||
*/
|
||||
private $dateTime;
|
||||
/**
|
||||
* @var HtmlToPdfConverter
|
||||
*/
|
||||
@@ -46,11 +42,14 @@ class PDFRenderer
|
||||
* @var string
|
||||
*/
|
||||
private $template = 'default.pdf.twig';
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $pdfOptions = [];
|
||||
|
||||
public function __construct(Environment $twig, UserDateTimeFactory $dateTime, HtmlToPdfConverter $converter, ProjectRepository $projectRepository)
|
||||
public function __construct(Environment $twig, HtmlToPdfConverter $converter, ProjectRepository $projectRepository)
|
||||
{
|
||||
$this->twig = $twig;
|
||||
$this->dateTime = $dateTime;
|
||||
$this->converter = $converter;
|
||||
$this->projectRepository = $projectRepository;
|
||||
}
|
||||
@@ -72,6 +71,18 @@ class PDFRenderer
|
||||
return ['decimal' => $decimal];
|
||||
}
|
||||
|
||||
public function getPdfOptions(): array
|
||||
{
|
||||
return $this->pdfOptions;
|
||||
}
|
||||
|
||||
public function setPdfOption(string $key, string $value): PDFRenderer
|
||||
{
|
||||
$this->pdfOptions[$key] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ExportItemInterface[] $timesheets
|
||||
* @param TimesheetQuery $query
|
||||
@@ -82,21 +93,33 @@ class PDFRenderer
|
||||
*/
|
||||
public function render(array $timesheets, TimesheetQuery $query): Response
|
||||
{
|
||||
$context = new ExportContext();
|
||||
$context->setOption('filename', 'kimai-export.pdf');
|
||||
|
||||
$summary = $this->calculateSummary($timesheets);
|
||||
$content = $this->twig->render($this->getTemplate(), array_merge([
|
||||
'entries' => $timesheets,
|
||||
'query' => $query,
|
||||
'now' => $this->dateTime->createDateTime(),
|
||||
// @deprecated since 1.13
|
||||
'now' => new \DateTime('now', new \DateTimeZone(date_default_timezone_get())),
|
||||
'summaries' => $summary,
|
||||
'budgets' => $this->calculateProjectBudget($timesheets, $query, $this->projectRepository),
|
||||
'decimal' => false,
|
||||
'pdfContext' => $context
|
||||
], $this->getOptions($query)));
|
||||
|
||||
$content = $this->converter->convertToPdf($content);
|
||||
$pdfOptions = array_merge($context->getOptions(), $this->getPdfOptions());
|
||||
|
||||
$content = $this->converter->convertToPdf($content, $pdfOptions);
|
||||
|
||||
$response = new Response($content);
|
||||
|
||||
$disposition = $response->headers->makeDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'kimai-export.pdf');
|
||||
$filename = $context->getOption('filename');
|
||||
if (empty($filename)) {
|
||||
$filename = 'kimai-export.pdf';
|
||||
}
|
||||
|
||||
$disposition = $response->headers->makeDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $filename);
|
||||
|
||||
$response->headers->set('Content-Type', 'application/pdf');
|
||||
$response->headers->set('Content-Disposition', $disposition);
|
||||
|
||||
37
src/Export/ExportContext.php
Normal file
37
src/Export/ExportContext.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai time-tracking app.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Export;
|
||||
|
||||
/**
|
||||
* A simple class that is available in twig renderer context, which can be used to define global renderer options.
|
||||
*/
|
||||
final class ExportContext
|
||||
{
|
||||
private $options = [];
|
||||
|
||||
public function setOption(string $key, string $value): void
|
||||
{
|
||||
$this->options[$key] = $value;
|
||||
}
|
||||
|
||||
public function getOptions(): array
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
public function getOption(string $key): ?string
|
||||
{
|
||||
if (\array_key_exists($key, $this->options)) {
|
||||
return $this->options[$key];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,6 @@
|
||||
namespace App\Export\Renderer;
|
||||
|
||||
use App\Repository\ProjectRepository;
|
||||
use App\Timesheet\UserDateTimeFactory;
|
||||
use App\Utils\HtmlToPdfConverter;
|
||||
use Twig\Environment;
|
||||
|
||||
@@ -20,10 +19,6 @@ final class PdfRendererFactory
|
||||
* @var Environment
|
||||
*/
|
||||
private $twig;
|
||||
/**
|
||||
* @var UserDateTimeFactory
|
||||
*/
|
||||
private $dateTime;
|
||||
/**
|
||||
* @var HtmlToPdfConverter
|
||||
*/
|
||||
@@ -33,17 +28,16 @@ final class PdfRendererFactory
|
||||
*/
|
||||
private $projectRepository;
|
||||
|
||||
public function __construct(Environment $twig, UserDateTimeFactory $dateTime, HtmlToPdfConverter $converter, ProjectRepository $projectRepository)
|
||||
public function __construct(Environment $twig, HtmlToPdfConverter $converter, ProjectRepository $projectRepository)
|
||||
{
|
||||
$this->twig = $twig;
|
||||
$this->dateTime = $dateTime;
|
||||
$this->converter = $converter;
|
||||
$this->projectRepository = $projectRepository;
|
||||
}
|
||||
|
||||
public function create(string $id, string $template): PDFRenderer
|
||||
{
|
||||
$renderer = new PDFRenderer($this->twig, $this->dateTime, $this->converter, $this->projectRepository);
|
||||
$renderer = new PDFRenderer($this->twig, $this->converter, $this->projectRepository);
|
||||
$renderer->setId($id);
|
||||
$renderer->setTemplate($template);
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace App\Twig;
|
||||
|
||||
use App\Configuration\LanguageFormattings;
|
||||
use App\Constants;
|
||||
use App\Entity\User;
|
||||
use App\Utils\LocaleFormats;
|
||||
use App\Utils\LocaleFormatter;
|
||||
use DateTime;
|
||||
@@ -89,6 +90,7 @@ class DateExtensions extends AbstractExtension
|
||||
{
|
||||
return [
|
||||
new TwigFunction('get_format_duration', [$this, 'getDurationFormat']),
|
||||
new TwigFunction('create_date', [$this, 'createDate']),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -130,6 +132,13 @@ class DateExtensions extends AbstractExtension
|
||||
return $this->formatter->dateTimeFull($date);
|
||||
}
|
||||
|
||||
public function createDate(string $date, ?User $user = null): \DateTime
|
||||
{
|
||||
$timezone = $user !== null ? $user->getTimezone() : date_default_timezone_get();
|
||||
|
||||
return new DateTime($date, new \DateTimeZone($timezone));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DateTime|string $date
|
||||
* @param string $format
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
namespace App\Utils;
|
||||
|
||||
use App\Constants;
|
||||
use Mpdf\Config\ConfigVariables;
|
||||
use Mpdf\Config\FontVariables;
|
||||
use Mpdf\Mpdf;
|
||||
use Mpdf\Output\Destination;
|
||||
|
||||
@@ -25,6 +27,32 @@ class MPdfConverter implements HtmlToPdfConverter
|
||||
$this->cacheDirectory = $cacheDirectory;
|
||||
}
|
||||
|
||||
protected function sanitizeOptions(array $options): array
|
||||
{
|
||||
$configs = new ConfigVariables();
|
||||
$fonts = new FontVariables();
|
||||
$allowed = [
|
||||
'mode', 'format', 'default_font_size', 'default_font', 'margin_left', 'margin_right', 'margin_top',
|
||||
'margin_bottom', 'margin_header', 'margin_footer', 'orientation'
|
||||
];
|
||||
|
||||
$filtered = array_filter($options, function ($key) use ($allowed, $configs, $fonts) {
|
||||
if (!\in_array($key, $allowed)) {
|
||||
if (!\array_key_exists($key, $configs->getDefaults())) {
|
||||
return \array_key_exists($key, $fonts->getDefaults());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}, ARRAY_FILTER_USE_KEY);
|
||||
|
||||
if (\array_key_exists('tempDir', $filtered)) {
|
||||
unset($filtered['tempDir']);
|
||||
}
|
||||
|
||||
return $filtered;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $html
|
||||
* @param array $options
|
||||
@@ -33,7 +61,11 @@ class MPdfConverter implements HtmlToPdfConverter
|
||||
*/
|
||||
public function convertToPdf(string $html, array $options = [])
|
||||
{
|
||||
$options = array_merge($options, ['tempDir' => $this->cacheDirectory]);
|
||||
$options = array_merge(
|
||||
$this->sanitizeOptions($options),
|
||||
['tempDir' => $this->cacheDirectory, 'exposeVersion' => false]
|
||||
);
|
||||
|
||||
$mpdf = new Mpdf($options);
|
||||
$mpdf->creator = Constants::SOFTWARE;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user