use custom fonts in mpdf via twig template (#3509)
This commit is contained in:
@@ -57,7 +57,8 @@ services:
|
||||
$settings: '%kimai.config%'
|
||||
|
||||
App\Utils\MPdfConverter:
|
||||
arguments: ['%kernel.cache_dir%']
|
||||
arguments:
|
||||
$cacheDirectory: '%kernel.cache_dir%'
|
||||
|
||||
App\Plugin\PluginManager:
|
||||
arguments: [!tagged kimai.plugin]
|
||||
|
||||
@@ -14,19 +14,34 @@ namespace App\Export;
|
||||
*/
|
||||
final class ExportContext
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $options = [];
|
||||
|
||||
public function setOption(string $key, string $value): void
|
||||
/**
|
||||
* @param string $key
|
||||
* @param string|array $value
|
||||
* @return void
|
||||
*/
|
||||
public function setOption(string $key, $value): void
|
||||
{
|
||||
$this->options[$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getOptions(): array
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
public function getOption(string $key): ?string
|
||||
/**
|
||||
* @param string $key
|
||||
* @return array|string|null
|
||||
*/
|
||||
public function getOption(string $key)
|
||||
{
|
||||
if (\array_key_exists($key, $this->options)) {
|
||||
return $this->options[$key];
|
||||
|
||||
@@ -17,13 +17,19 @@ use Mpdf\Output\Destination;
|
||||
|
||||
class MPdfConverter implements HtmlToPdfConverter
|
||||
{
|
||||
/**
|
||||
* @var FileHelper
|
||||
*/
|
||||
private $fileHelper;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $cacheDirectory;
|
||||
|
||||
public function __construct(string $cacheDirectory)
|
||||
public function __construct(FileHelper $fileHelper, string $cacheDirectory)
|
||||
{
|
||||
$this->fileHelper = $fileHelper;
|
||||
$this->cacheDirectory = $cacheDirectory;
|
||||
}
|
||||
|
||||
@@ -33,7 +39,7 @@ class MPdfConverter implements HtmlToPdfConverter
|
||||
$fonts = new FontVariables();
|
||||
$allowed = [
|
||||
'mode', 'format', 'default_font_size', 'default_font', 'margin_left', 'margin_right', 'margin_top',
|
||||
'margin_bottom', 'margin_header', 'margin_footer', 'orientation'
|
||||
'margin_bottom', 'margin_header', 'margin_footer', 'orientation', 'fonts',
|
||||
];
|
||||
|
||||
$filtered = array_filter($options, function ($key) use ($allowed, $configs, $fonts) {
|
||||
@@ -66,8 +72,7 @@ class MPdfConverter implements HtmlToPdfConverter
|
||||
['tempDir' => $this->cacheDirectory, 'exposeVersion' => false]
|
||||
);
|
||||
|
||||
$mpdf = new Mpdf($options);
|
||||
$mpdf->creator = Constants::SOFTWARE;
|
||||
$mpdf = $this->initMpdf($options);
|
||||
|
||||
// some OS do not follow the PHP default settings
|
||||
if ((int) ini_get('pcre.backtrack_limit') < 1000000) {
|
||||
@@ -97,4 +102,50 @@ class MPdfConverter implements HtmlToPdfConverter
|
||||
|
||||
return $mpdf->Output('', Destination::STRING_RETURN);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
* @return Mpdf
|
||||
* @throws \Mpdf\MpdfException
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function initMpdf(array $options): Mpdf
|
||||
{
|
||||
$options['fontDir'] = $this->getFontDirectories();
|
||||
$options['fontdata'] = $this->mergeFontData($options);
|
||||
|
||||
$mpdf = new Mpdf($options);
|
||||
$mpdf->creator = Constants::SOFTWARE;
|
||||
|
||||
return $mpdf;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function getFontDirectories(): array
|
||||
{
|
||||
$defaultConfig = (new ConfigVariables())->getDefaults();
|
||||
$fontDirectories = $defaultConfig['fontDir'];
|
||||
$fontDirectories[] = $this->fileHelper->getDataDirectory('fonts');
|
||||
|
||||
return $fontDirectories;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
* @return array
|
||||
*/
|
||||
private function mergeFontData(array $options): array
|
||||
{
|
||||
$defaultFontConfig = (new FontVariables())->getDefaults();
|
||||
$fontData = $defaultFontConfig['fontdata'];
|
||||
|
||||
if (\array_key_exists('fonts', $options)) {
|
||||
$fontData = array_merge($fontData, $options['fonts']);
|
||||
}
|
||||
|
||||
return $fontData;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace App\Tests\Export\Renderer;
|
||||
|
||||
use App\Export\Renderer\PDFRenderer;
|
||||
use App\Project\ProjectStatisticService;
|
||||
use App\Tests\Mocks\FileHelperFactory;
|
||||
use App\Utils\HtmlToPdfConverter;
|
||||
use App\Utils\MPdfConverter;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
@@ -49,7 +50,7 @@ class PdfRendererTest extends AbstractRendererTest
|
||||
$twig = $kernel->getContainer()->get('twig');
|
||||
$stack = $kernel->getContainer()->get('request_stack');
|
||||
$cacheDir = $kernel->getContainer()->getParameter('kernel.cache_dir');
|
||||
$converter = new MPdfConverter($cacheDir);
|
||||
$converter = new MPdfConverter((new FileHelperFactory($this))->create(), $cacheDir);
|
||||
$request = new Request();
|
||||
$request->setLocale('en');
|
||||
$stack->push($request);
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace App\Tests\Export\Timesheet;
|
||||
|
||||
use App\Export\Timesheet\PDFRenderer;
|
||||
use App\Project\ProjectStatisticService;
|
||||
use App\Tests\Mocks\FileHelperFactory;
|
||||
use App\Utils\HtmlToPdfConverter;
|
||||
use App\Utils\MPdfConverter;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
@@ -42,7 +43,7 @@ class PdfRendererTest extends AbstractRendererTest
|
||||
$twig = $kernel->getContainer()->get('twig');
|
||||
$stack = $kernel->getContainer()->get('request_stack');
|
||||
$cacheDir = $kernel->getContainer()->getParameter('kernel.cache_dir');
|
||||
$converter = new MPdfConverter($cacheDir);
|
||||
$converter = new MPdfConverter((new FileHelperFactory($this))->create(), $cacheDir);
|
||||
$request = new Request();
|
||||
$request->setLocale('en');
|
||||
$stack->push($request);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
namespace App\Tests\Invoice\Renderer;
|
||||
|
||||
use App\Invoice\Renderer\PdfRenderer;
|
||||
use App\Tests\Mocks\FileHelperFactory;
|
||||
use App\Utils\MPdfConverter;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
@@ -56,7 +57,7 @@ class PdfRendererTest extends KernelTestCase
|
||||
$loader = $twig->getLoader();
|
||||
$loader->addPath(__DIR__ . '/../templates/', 'invoice');
|
||||
|
||||
$sut = new PdfRenderer($twig, new MPdfConverter($cacheDir));
|
||||
$sut = new PdfRenderer($twig, new MPdfConverter((new FileHelperFactory($this))->create(), $cacheDir));
|
||||
$model = $this->getInvoiceModel();
|
||||
$document = $this->getInvoiceDocument('default.pdf.twig', true);
|
||||
|
||||
|
||||
22
tests/Mocks/FileHelperFactory.php
Normal file
22
tests/Mocks/FileHelperFactory.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?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\Tests\Mocks;
|
||||
|
||||
use App\Utils\FileHelper;
|
||||
|
||||
class FileHelperFactory extends AbstractMockFactory
|
||||
{
|
||||
public function create(): FileHelper
|
||||
{
|
||||
$data = realpath(__DIR__ . '/../../var/data/');
|
||||
|
||||
return new FileHelper($data);
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
namespace App\Tests\Utils;
|
||||
|
||||
use App\Tests\Mocks\FileHelperFactory;
|
||||
use App\Utils\MPdfConverter;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||
|
||||
@@ -28,7 +29,7 @@ class MPdfConverterTest extends KernelTestCase
|
||||
$kernel = self::bootKernel();
|
||||
$cacheDir = $kernel->getContainer()->getParameter('kernel.cache_dir');
|
||||
|
||||
$sut = new MPdfConverter($cacheDir);
|
||||
$sut = new MPdfConverter((new FileHelperFactory($this))->create(), $cacheDir);
|
||||
$result = $sut->convertToPdf('<h1>Test</h1>');
|
||||
// Yeah, thats not a real test, I know ;-)
|
||||
$this->assertNotEmpty($result);
|
||||
|
||||
Reference in New Issue
Block a user