Skip to content

Commit

Permalink
Update AssetBaseDirFormatter
Browse files Browse the repository at this point in the history
  • Loading branch information
StevenRenaux committed Feb 27, 2024
1 parent 23473a3 commit 0edcf0b
Show file tree
Hide file tree
Showing 19 changed files with 98 additions and 75 deletions.
8 changes: 2 additions & 6 deletions config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@
->args([
service('sensiolabs_gotenberg.client'),
abstract_arg('user configuration options'),
param('kernel.project_dir'),
service(Filesystem::class),
service('sensiolabs_gotenberg.asset.base_dir_formatter'),
service('twig')->nullOnInvalid(),
])
->public()
Expand All @@ -37,17 +36,14 @@

$services->set('sensiolabs_gotenberg.asset.base_dir_formatter', AssetBaseDirFormatter::class)
->args([
abstract_arg('asset_base_dir to assets'),
service(Filesystem::class),
param('kernel.project_dir'),
abstract_arg('base_directory to assets'),
])
->alias(AssetBaseDirFormatter::class, 'sensiolabs_gotenberg.asset.base_dir_formatter')
;

$services->set('sensiolabs_gotenberg.twig.asset_extension', GotenbergAssetExtension::class)
->args([
service(AssetBaseDirFormatter::class),
])
->tag('twig.extension')
;
};
2 changes: 1 addition & 1 deletion docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ The default configuration for the bundle looks like :
sensiolabs_gotenberg:
base_uri: 'http://localhost:3000'
asset_base_dir: '%kernel.project_dir%/public/'
base_directory: '%kernel.project_dir%'
options:
paper_width: null # 8.5
paper_height: null # 11
Expand Down
6 changes: 3 additions & 3 deletions docs/customization.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ If a template needs to link to a static asset (e.g. an image), this bundle provi
Twig function to help generate that path.

This function work as `asset() Twig function`_ and fetch your assets in the public folder of your application
If your files are in another folder, you can override the default value of ``asset_base_dir`` in your
If your files are in another folder, you can override the default value of ``base_directory`` in your
configuration file ``config/sensiolabs_gotenberg.yml``.
The path provided can be relative as well as absolute.

Expand All @@ -34,8 +34,8 @@ The path provided can be relative as well as absolute.
<title>PDF body</title>
</head>
<body>
<img src="{{ gotenberg_asset('ceo.jpeg') }}" alt="CEO"/>
<img src="{{ gotenberg_asset('img/admin.jpeg') }}" alt="Admin"/>
<img src="{{ gotenberg_asset('public/img/ceo.jpeg') }}" alt="CEO"/>
<img src="{{ gotenberg_asset('public/img/admin.jpeg') }}" alt="Admin"/>
<main>
<h1>Hello world!</h1>
</main>
Expand Down
15 changes: 7 additions & 8 deletions src/Builder/AbstractChromiumPdfBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use Sensiolabs\GotenbergBundle\Enum\PdfPart;
use Sensiolabs\GotenbergBundle\Exception\ExtraHttpHeadersJsonEncodingException;
use Sensiolabs\GotenbergBundle\Exception\PdfPartRenderingException;
use Symfony\Component\Filesystem\Filesystem;
use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter;
use Symfony\Component\Mime\Part\DataPart;
use Symfony\Component\Mime\Part\File as DataPartFile;
use Twig\Environment;
Expand All @@ -15,11 +15,10 @@ abstract class AbstractChromiumPdfBuilder extends AbstractPdfBuilder
{
public function __construct(
GotenbergClientInterface $gotenbergClient,
string $projectDir,
Filesystem $filesystem,
AssetBaseDirFormatter $asset,
private readonly ?Environment $twig = null,
) {
parent::__construct($gotenbergClient, $projectDir, $filesystem);
parent::__construct($gotenbergClient, $asset);
}

/**
Expand Down Expand Up @@ -234,9 +233,9 @@ public function assets(string ...$paths): static
*/
public function addAsset(string $path): static
{
$dataPart = new DataPart(new DataPartFile($this->resolveFilePath($path)));
$dataPart = new DataPart(new DataPartFile($this->asset->resolve($path)));

$this->formFields['assets'][$path] = $dataPart;
$this->formFields['assets'][$this->asset->resolve($path)] = $dataPart;

return $this;
}
Expand Down Expand Up @@ -413,7 +412,7 @@ public function getMultipartFormData(): array
protected function withPdfPartFile(PdfPart $pdfPart, string $path): static
{
$dataPart = new DataPart(
new DataPartFile($this->resolveFilePath($path)),
new DataPartFile($this->asset->resolve($path)),
$pdfPart->value,
);

Expand All @@ -436,7 +435,7 @@ protected function withRenderedPart(PdfPart $pdfPart, string $template, array $c
try {
$html = $this->twig->render($template, array_merge($context, ['_builder' => $this]));
} catch (\Throwable $error) {
throw new PdfPartRenderingException(sprintf('Could not render template "%s" into PDF part "%s".', $template, $pdfPart->value), previous: $error);
throw new PdfPartRenderingException(sprintf('Could not render template "%s" into PDF part "%s". %s', $template, $pdfPart->value, $error->getMessage()), previous: $error);
}

$this->formFields[$pdfPart->value] = new DataPart($html, $pdfPart->value, 'text/html');
Expand Down
16 changes: 3 additions & 13 deletions src/Builder/AbstractPdfBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use Sensiolabs\GotenbergBundle\Client\GotenbergClientInterface;
use Sensiolabs\GotenbergBundle\Client\PdfResponse;
use Sensiolabs\GotenbergBundle\Exception\MissingRequiredFieldException;
use Symfony\Component\Filesystem\Filesystem;
use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\String\UnicodeString;

Expand All @@ -18,8 +18,7 @@ abstract class AbstractPdfBuilder implements PdfBuilderInterface

public function __construct(
protected readonly GotenbergClientInterface $gotenbergClient,
protected readonly string $projectDir,
protected readonly Filesystem $filesystem,
protected readonly AssetBaseDirFormatter $asset,
) {
}

Expand Down Expand Up @@ -66,20 +65,11 @@ public function setConfigurations(array $configurations): static
*/
protected function assertFileExtension(string $path, array $validExtensions): void
{
$file = new File($this->resolveFilePath($path));
$file = new File($this->asset->resolve($path));
$extension = $file->getExtension();

if (!\in_array($extension, $validExtensions, true)) {
throw new \InvalidArgumentException(sprintf('The file extension "%s" is not available in Gotenberg.', $extension));
}
}

protected function resolveFilePath(string $path): string
{
if ($this->filesystem->isAbsolutePath($path)) {
return $path;
}

return "{$this->projectDir}/{$path}";
}
}
2 changes: 1 addition & 1 deletion src/Builder/LibreOfficePdfBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public function files(string ...$paths): self
foreach ($paths as $path) {
$this->assertFileExtension($path, self::AVAILABLE_EXTENSIONS);

$dataPart = new DataPart(new DataPartFile($this->resolveFilePath($path)));
$dataPart = new DataPart(new DataPartFile($this->asset->resolve($path)));

$this->formFields['files'][$path] = $dataPart;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Builder/MarkdownPdfBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public function files(string ...$paths): self
foreach ($paths as $path) {
$this->assertFileExtension($path, ['md']);

$dataPart = new DataPart(new DataPartFile($this->resolveFilePath($path)));
$dataPart = new DataPart(new DataPartFile($this->asset->resolve($path)));

$this->formFields['files'][$path] = $dataPart;
}
Expand Down
6 changes: 3 additions & 3 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ public function getConfigTreeBuilder(): TreeBuilder
->thenInvalid('Invalid API Gotenberg host.')
->end()
->end()
->scalarNode('asset_base_dir')
->info('Base DIR where assets are located')
->defaultValue('%kernel.project_dir%/public/')
->scalarNode('base_directory')
->info('Base directory will be used for assets, files, markdown')
->defaultValue('%kernel.project_dir%')
->cannotBeEmpty()
->end()
->arrayNode('default_options')
Expand Down
4 changes: 2 additions & 2 deletions src/DependencyInjection/SensiolabsGotenbergExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public function load(array $configs, ContainerBuilder $container): void

$configuration = new Configuration();

/** @var array{base_uri: string, asset_base_dir: string, default_options: array<string, mixed>} $config */
/** @var array{base_uri: string, base_directory: string, default_options: array<string, mixed>} $config */
$config = $this->processConfiguration($configuration, $configs);

$definition = $container->getDefinition('sensiolabs_gotenberg.client');
Expand All @@ -26,7 +26,7 @@ public function load(array $configs, ContainerBuilder $container): void
$definition->replaceArgument(1, $this->cleanDefaultOptions($config['default_options']));

$definition = $container->getDefinition('sensiolabs_gotenberg.asset.base_dir_formatter');
$definition->replaceArgument(0, $config['asset_base_dir']);
$definition->replaceArgument(0, $config['base_directory']);
}

/**
Expand Down
17 changes: 12 additions & 5 deletions src/Formatter/AssetBaseDirFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,25 @@

use Symfony\Component\Filesystem\Filesystem;

final readonly class AssetBaseDirFormatter implements \Stringable
final readonly class AssetBaseDirFormatter
{
public function __construct(private string $baseDir, private Filesystem $filesystem, private string $projectDir)
private string $baseDir;

public function __construct(private Filesystem $filesystem, private string $projectDir, string $baseDir)
{
$this->baseDir = rtrim($baseDir, '/');
}

public function __toString(): string
public function resolve(string $path): string
{
if ($this->filesystem->isAbsolutePath($path)) {
return $path;
}

if ($this->filesystem->isAbsolutePath($this->baseDir)) {
return $this->baseDir;
return "{$this->baseDir}/{$path}";
}

return "{$this->projectDir}/{$this->baseDir}";
return "{$this->projectDir}/{$this->baseDir}/{$path}";
}
}
13 changes: 6 additions & 7 deletions src/Pdf/Gotenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use Sensiolabs\GotenbergBundle\Builder\MarkdownPdfBuilder;
use Sensiolabs\GotenbergBundle\Builder\UrlPdfBuilder;
use Sensiolabs\GotenbergBundle\Client\GotenbergClientInterface;
use Symfony\Component\Filesystem\Filesystem;
use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter;
use Twig\Environment;

final readonly class Gotenberg implements GotenbergInterface
Expand All @@ -18,36 +18,35 @@
public function __construct(
private GotenbergClientInterface $gotenbergClient,
private array $userConfigurations,
private string $projectDir,
private Filesystem $filesystem,
private AssetBaseDirFormatter $asset,
private ?Environment $twig = null,
) {
}

public function html(): HtmlPdfBuilder
{
return (new HtmlPdfBuilder($this->gotenbergClient, $this->projectDir, $this->filesystem, $this->twig))
return (new HtmlPdfBuilder($this->gotenbergClient, $this->asset, $this->twig))
->setConfigurations($this->userConfigurations)
;
}

public function url(): UrlPdfBuilder
{
return (new UrlPdfBuilder($this->gotenbergClient, $this->projectDir, $this->filesystem, $this->twig))
return (new UrlPdfBuilder($this->gotenbergClient, $this->asset, $this->twig))
->setConfigurations($this->userConfigurations)
;
}

public function markdown(): MarkdownPdfBuilder
{
return (new MarkdownPdfBuilder($this->gotenbergClient, $this->projectDir, $this->filesystem, $this->twig))
return (new MarkdownPdfBuilder($this->gotenbergClient, $this->asset, $this->twig))
->setConfigurations($this->userConfigurations)
;
}

public function office(): LibreOfficePdfBuilder
{
return (new LibreOfficePdfBuilder($this->gotenbergClient, $this->projectDir, $this->filesystem))
return (new LibreOfficePdfBuilder($this->gotenbergClient, $this->asset))
->setConfigurations($this->userConfigurations)
;
}
Expand Down
6 changes: 1 addition & 5 deletions src/Twig/GotenbergAssetExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@

final class GotenbergAssetExtension extends AbstractExtension
{
public function __construct(private readonly string $formattedAssetBaseDir)
{
}

public function getFunctions(): array
{
return [
Expand All @@ -31,7 +27,7 @@ public function getAssetUrl(array $context, string $path): string
throw new \LogicException('You need to extend from AbstractChromiumPdfBuilder to use gotenberg_asset function.');
}

$builder->assets($this->formattedAssetBaseDir.$path);
$builder->addAsset($path);

return (new File($path))->getFilename();
}
Expand Down
4 changes: 2 additions & 2 deletions tests/Builder/AbstractBuilderTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@

abstract class AbstractBuilderTestCase extends TestCase
{
protected const FIXTURE_DIR = __DIR__.'/../Fixtures';
protected const FIXTURE_DIR = '/../Fixtures';

protected static Environment $twig;

public static function setUpBeforeClass(): void
{
self::$twig = new Environment(new FilesystemLoader(self::FIXTURE_DIR.'/templates'));
self::$twig = new Environment(new FilesystemLoader(__DIR__.'/../Fixtures/templates'));
}
}
31 changes: 25 additions & 6 deletions tests/Builder/HtmlPdfBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Sensiolabs\GotenbergBundle\Client\GotenbergClientInterface;
use Sensiolabs\GotenbergBundle\Exception\ExtraHttpHeadersJsonEncodingException;
use Sensiolabs\GotenbergBundle\Exception\PdfPartRenderingException;
use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Mime\Part\DataPart;

Expand All @@ -17,7 +18,10 @@ public function testWithConfigurations(): void
{
$client = $this->createMock(GotenbergClientInterface::class);
$filesystem = $this->createMock(Filesystem::class);
$builder = new HtmlPdfBuilder($client, self::FIXTURE_DIR, $filesystem);

$assetBaseDirFormatter = new AssetBaseDirFormatter($filesystem, self::FIXTURE_DIR, self::FIXTURE_DIR);

$builder = new HtmlPdfBuilder($client, $assetBaseDirFormatter);
$builder->contentFile('content.html');
$builder->setConfigurations(self::getUserConfig());

Expand Down Expand Up @@ -57,7 +61,10 @@ public function testWithTemplate(): void
{
$client = $this->createMock(GotenbergClientInterface::class);
$filesystem = $this->createMock(Filesystem::class);
$builder = new HtmlPdfBuilder($client, self::FIXTURE_DIR, $filesystem, self::$twig);

$assetBaseDirFormatter = new AssetBaseDirFormatter($filesystem, self::FIXTURE_DIR, self::FIXTURE_DIR);

$builder = new HtmlPdfBuilder($client, $assetBaseDirFormatter, self::$twig);
$builder->content('content.html.twig');

$multipartFormData = $builder->getMultipartFormData();
Expand All @@ -74,7 +81,10 @@ public function testWithAssets(): void
{
$client = $this->createMock(GotenbergClientInterface::class);
$filesystem = $this->createMock(Filesystem::class);
$builder = new HtmlPdfBuilder($client, self::FIXTURE_DIR, $filesystem);

$assetBaseDirFormatter = new AssetBaseDirFormatter($filesystem, self::FIXTURE_DIR, self::FIXTURE_DIR);

$builder = new HtmlPdfBuilder($client, $assetBaseDirFormatter);
$builder->contentFile('content.html');
$builder->assets('assets/logo.png');

Expand All @@ -93,7 +103,10 @@ public function testWithHeader(): void
{
$client = $this->createMock(GotenbergClientInterface::class);
$filesystem = $this->createMock(Filesystem::class);
$builder = new HtmlPdfBuilder($client, self::FIXTURE_DIR, $filesystem);

$assetBaseDirFormatter = new AssetBaseDirFormatter($filesystem, self::FIXTURE_DIR, self::FIXTURE_DIR);

$builder = new HtmlPdfBuilder($client, $assetBaseDirFormatter);
$builder->headerFile('header.html');
$builder->contentFile('content.html');

Expand All @@ -115,7 +128,10 @@ public function testInvalidTwigTemplate(): void

$client = $this->createMock(GotenbergClientInterface::class);
$filesystem = $this->createMock(Filesystem::class);
$builder = new HtmlPdfBuilder($client, self::FIXTURE_DIR, $filesystem, self::$twig);

$assetBaseDirFormatter = new AssetBaseDirFormatter($filesystem, self::FIXTURE_DIR, self::FIXTURE_DIR);

$builder = new HtmlPdfBuilder($client, $assetBaseDirFormatter, self::$twig);

$builder->content('invalid.html.twig');
}
Expand All @@ -127,7 +143,10 @@ public function testInvalidExtraHttpHeaders(): void

$client = $this->createMock(GotenbergClientInterface::class);
$filesystem = $this->createMock(Filesystem::class);
$builder = new HtmlPdfBuilder($client, self::FIXTURE_DIR, $filesystem);

$assetBaseDirFormatter = new AssetBaseDirFormatter($filesystem, self::FIXTURE_DIR, self::FIXTURE_DIR);

$builder = new HtmlPdfBuilder($client, $assetBaseDirFormatter);
$builder->contentFile('content.html');
// @phpstan-ignore-next-line
$builder->extraHttpHeaders([
Expand Down
Loading

0 comments on commit 0edcf0b

Please sign in to comment.