Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions composer-dependency-analyser.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
->ignoreErrorsOnPackage('twig/twig', [
ErrorType::DEV_DEPENDENCY_IN_PROD,
])
->ignoreErrorsOnPackage('symfony/asset', [
ErrorType::DEV_DEPENDENCY_IN_PROD,
])
;

if (\PHP_VERSION_ID < 80200) { // TODO: Requires PHP >= 8.2
Expand Down
2 changes: 2 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"require": {
"php": ">=8.1",
"ext-json": "*",
"ext-filter": "*",
"psr/container": "^2.0",
"psr/log": "^3.0",
"symfony/config": "^6.4 || ^7.0",
Expand All @@ -45,6 +46,7 @@
"phpstan/phpstan-symfony": "^2.0",
"phpunit/phpunit": "^10.5.46",
"shipmonk/composer-dependency-analyser": "^1.8",
"symfony/asset": "^6.4 || ^7.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"symfony/asset": "^6.4 || ^7.0",
"symfony/asset": "^6.4 || ^7.0 || ^8.0",

"symfony/error-handler": "^6.4 || ^7.0",
"symfony/framework-bundle": "^6.4 || ^7.0",
"symfony/http-client": "^6.4 || ^7.0",
Expand Down
1 change: 1 addition & 0 deletions config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
->tag('twig.extension')
;
$services->set('sensiolabs_gotenberg.twig.asset_runtime', GotenbergRuntime::class)
->args([service('assets.packages')->nullOnInvalid()])
->tag('twig.runtime')
;

Expand Down
7 changes: 5 additions & 2 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@ public function getConfigTreeBuilder(): TreeBuilder
$treeBuilder->getRootNode()
->addDefaultsIfNotSet()
->children()
->scalarNode('assets_directory')
->arrayNode('assets_directory')
->normalizeKeys(false)
->prototype('scalar')->end()
->info('Base directory will be used for assets, files, markdown')
->defaultValue('%kernel.project_dir%/assets')
->defaultValue(['%kernel.project_dir%/assets'])
->beforeNormalization()->castToArray()->end()
->end()
->scalarNode('version')
->info('Version of Gotenberg')
Expand Down
35 changes: 28 additions & 7 deletions src/Formatter/AssetBaseDirFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,53 @@

namespace Sensiolabs\GotenbergBundle\Formatter;

use Symfony\Component\Filesystem\Exception\FileNotFoundException;
use Symfony\Component\Filesystem\Path;

/**
* @internal
*/
final class AssetBaseDirFormatter
{
private readonly string $baseDir;
/** @var string[] */
private readonly array $baseDir;

/**
* @param string[] $baseDir
*/
public function __construct(
private readonly string $projectDir,
string $baseDir,
array $baseDir,
) {
$this->baseDir = rtrim($baseDir, '/\\');
$this->baseDir = array_map(function ($value) {
return rtrim($value, '/\\');
}, $baseDir);
}

public function resolve(string $path): string
{
if (Path::isAbsolute($path)) {
if (Path::isAbsolute($path) || filter_var($path, \FILTER_VALIDATE_URL)) {
return $path;
}

if (Path::isAbsolute($this->baseDir)) {
return Path::join($this->baseDir, $path);
foreach ($this->baseDir as $baseDir) {
if (Path::isAbsolute($baseDir)) {
$filename = Path::join($baseDir, $path);
if (!file_exists($filename)) {
continue;
}

return $filename;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might be worth "caching" it WDYT ?

}

$filename = Path::join($this->projectDir, $baseDir, $path);
if (!file_exists($filename)) {
continue;
}

return $filename;
}

return Path::join($this->projectDir, $this->baseDir, $path);
throw new FileNotFoundException(\sprintf('File "%s" does not exist.', $path));
}
}
2 changes: 1 addition & 1 deletion src/Test/Builder/GotenbergBuilderTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ protected function setUp(): void
$this->client = new GotenbergClientAsserter();
$this->container = new Container();

$this->container->set('asset_base_dir_formatter', new AssetBaseDirFormatter(static::FIXTURE_DIR, static::FIXTURE_DIR));
$this->container->set('asset_base_dir_formatter', new AssetBaseDirFormatter(static::FIXTURE_DIR, [static::FIXTURE_DIR]));
$this->container->set('sensiolabs_gotenberg.client', $this->client);
$this->container->set('sensiolabs_gotenberg.version_fetcher', new StaticVersionFetcher($this->gotenbergVersion));
}
Expand Down
18 changes: 18 additions & 0 deletions src/Twig/GotenbergRuntime.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Sensiolabs\GotenbergBundle\Twig;

use Sensiolabs\GotenbergBundle\Builder\BuilderAssetInterface;
use Symfony\Component\Asset\Packages;

/**
* @internal
Expand All @@ -14,6 +15,10 @@ final class GotenbergRuntime
{
private BuilderAssetInterface|null $builder = null;

public function __construct(private readonly Packages|null $packages)
{
}

public function setBuilder(BuilderAssetInterface|null $builder): void
{
$this->builder = $builder;
Expand All @@ -27,20 +32,23 @@ public function setBuilder(BuilderAssetInterface|null $builder): void
*/
public function getAssetUrl(string $path): string
{
$path = $this->getVersionedPathIfExist($path);
$this->addAsset($path, 'gotenberg_asset');

return basename($path);
}

public function getFontStyleTag(string $path, string $name): string
{
$path = $this->getVersionedPathIfExist($path);
$this->addAsset($path, 'gotenberg_font_style_tag');

return '<style>'.$this->generateFontFace($path, $name).'</style>';
}

public function getFontFace(string $path, string $name): string
{
$path = $this->getVersionedPathIfExist($path);
$this->addAsset($path, 'gotenberg_font_face');

return $this->generateFontFace($path, $name);
Expand All @@ -62,4 +70,14 @@ private function addAsset(string $path, string $function): void

$this->builder->addAsset($path);
}

private function getVersionedPathIfExist(string $path): string
{
$packages = $this->packages;
if (null !== $packages) {
$path = ltrim($packages->getUrl($path), '/');
}

return $path;
}
}
4 changes: 3 additions & 1 deletion tests/Builder/Pdf/ConvertPdfBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ final class ConvertPdfBuilderTest extends GotenbergBuilderTestCase
/** @use WebhookTestCaseTrait<ConvertPdfBuilder> */
use WebhookTestCaseTrait;

private const ASSETS_DIR = __DIR__.'/../../Fixtures/assets';

protected function createBuilder(): ConvertPdfBuilder
{
return new ConvertPdfBuilder();
Expand Down Expand Up @@ -100,7 +102,7 @@ public function testFilesExtensionRequirement(): void
$this->expectExceptionMessage('The file extension "png" is not valid in this context.');

$this->getBuilder()
->files('b.png')
->files(self::ASSETS_DIR.'logo.png')
->generate()
;
}
Expand Down
4 changes: 3 additions & 1 deletion tests/Builder/Pdf/FlattenPdfBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ final class FlattenPdfBuilderTest extends GotenbergBuilderTestCase
/** @use WebhookTestCaseTrait<FlattenPdfBuilder> */
use WebhookTestCaseTrait;

private const ASSETS_DIR = __DIR__.'/../../Fixtures/assets';

protected function createBuilder(): FlattenPdfBuilder
{
return new FlattenPdfBuilder();
Expand Down Expand Up @@ -54,7 +56,7 @@ public function testFilesExtensionRequirement(): void
$this->expectExceptionMessage('The file extension "png" is not valid in this context.');

$this->getBuilder()
->files('b.png')
->files(self::ASSETS_DIR.'logo.png')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
->files(self::ASSETS_DIR.'logo.png')
->files(self::ASSETS_DIR.'/logo.png')

->generate()
;
}
Expand Down
18 changes: 9 additions & 9 deletions tests/Builder/Pdf/HtmlPdfBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public function testRequiredFormData(): void

public function testOutputFilename(): void
{
$this->container->set('asset_base_dir_formatter', new AssetBaseDirFormatter(self::FIXTURE_DIR, self::FIXTURE_DIR));
$this->container->set('asset_base_dir_formatter', new AssetBaseDirFormatter(self::FIXTURE_DIR, [self::FIXTURE_DIR]));

$this->getBuilder()
->contentFile('files/content.html')
Expand All @@ -64,7 +64,7 @@ public function testOutputFilename(): void

public function testWidth(): void
{
$this->container->set('asset_base_dir_formatter', new AssetBaseDirFormatter(self::FIXTURE_DIR, self::FIXTURE_DIR));
$this->container->set('asset_base_dir_formatter', new AssetBaseDirFormatter(self::FIXTURE_DIR, [self::FIXTURE_DIR]));

$this->getBuilder()
->contentFile('files/content.html')
Expand All @@ -83,7 +83,7 @@ public function testWidth(): void

public function testWithTwigContentFile(): void
{
$this->container->set('asset_base_dir_formatter', new AssetBaseDirFormatter(self::FIXTURE_DIR, self::FIXTURE_DIR));
$this->container->set('asset_base_dir_formatter', new AssetBaseDirFormatter(self::FIXTURE_DIR, [self::FIXTURE_DIR]));

$twig = new Environment(new FilesystemLoader(self::FIXTURE_DIR), [
'strict_variables' => true,
Expand All @@ -92,7 +92,7 @@ public function testWithTwigContentFile(): void
$twig->addRuntimeLoader(new class implements RuntimeLoaderInterface {
public function load(string $class): object|null
{
return GotenbergRuntime::class === $class ? new GotenbergRuntime() : null;
return GotenbergRuntime::class === $class ? new GotenbergRuntime(null) : null;
}
});

Expand Down Expand Up @@ -123,7 +123,7 @@ public function load(string $class): object|null

public function testWithTwigAndHeaderFooterParts(): void
{
$this->container->set('asset_base_dir_formatter', new AssetBaseDirFormatter(self::FIXTURE_DIR, self::FIXTURE_DIR));
$this->container->set('asset_base_dir_formatter', new AssetBaseDirFormatter(self::FIXTURE_DIR, [self::FIXTURE_DIR]));

$twig = new Environment(new FilesystemLoader(self::FIXTURE_DIR), [
'strict_variables' => true,
Expand All @@ -132,7 +132,7 @@ public function testWithTwigAndHeaderFooterParts(): void
$twig->addRuntimeLoader(new class implements RuntimeLoaderInterface {
public function load(string $class): object|null
{
return GotenbergRuntime::class === $class ? new GotenbergRuntime() : null;
return GotenbergRuntime::class === $class ? new GotenbergRuntime(null) : null;
}
});

Expand Down Expand Up @@ -195,7 +195,7 @@ public function load(string $class): object|null

public function testFilesAsHeaderAndFooter(): void
{
$this->container->set('asset_base_dir_formatter', new AssetBaseDirFormatter(self::FIXTURE_DIR, self::FIXTURE_DIR));
$this->container->set('asset_base_dir_formatter', new AssetBaseDirFormatter(self::FIXTURE_DIR, [self::FIXTURE_DIR]));

$this->getBuilder()
->headerFile('files/header.html')
Expand All @@ -217,7 +217,7 @@ public function testWithInvalidTwigTemplate(): void
{
$this->expectException(PartRenderingException::class);

$this->container->set('asset_base_dir_formatter', new AssetBaseDirFormatter(self::FIXTURE_DIR, self::FIXTURE_DIR));
$this->container->set('asset_base_dir_formatter', new AssetBaseDirFormatter(self::FIXTURE_DIR, [self::FIXTURE_DIR]));

$twig = new Environment(new FilesystemLoader(self::FIXTURE_DIR), [
'strict_variables' => true,
Expand All @@ -226,7 +226,7 @@ public function testWithInvalidTwigTemplate(): void
$twig->addRuntimeLoader(new class implements RuntimeLoaderInterface {
public function load(string $class): object|null
{
return GotenbergRuntime::class === $class ? new GotenbergRuntime() : null;
return GotenbergRuntime::class === $class ? new GotenbergRuntime(null) : null;
}
});

Expand Down
6 changes: 4 additions & 2 deletions tests/Builder/Pdf/MarkdownPdfBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ final class MarkdownPdfBuilderTest extends GotenbergBuilderTestCase
/** @use ChromiumPdfTestCaseTrait<MarkdownPdfBuilder> */
use ChromiumPdfTestCaseTrait;

private const ASSETS_DIR = __DIR__.'/../../Fixtures/assets';

protected function createBuilder(): MarkdownPdfBuilder
{
return new MarkdownPdfBuilder();
Expand Down Expand Up @@ -59,7 +61,7 @@ public function testFileWithContent(): void
$twig->addRuntimeLoader(new class implements RuntimeLoaderInterface {
public function load(string $class): object|null
{
return GotenbergRuntime::class === $class ? new GotenbergRuntime() : null;
return GotenbergRuntime::class === $class ? new GotenbergRuntime(null) : null;
}
});

Expand Down Expand Up @@ -121,7 +123,7 @@ public function testFilesExtensionRequirement(): void
$this->expectExceptionMessage('The file extension "png" is not valid in this context.');

$this->getBuilder()
->files('b.png')
->files(self::ASSETS_DIR.'logo.png')
->generate()
;
}
Expand Down
4 changes: 3 additions & 1 deletion tests/Builder/Pdf/MergePdfBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ final class MergePdfBuilderTest extends GotenbergBuilderTestCase
/** @use WebhookTestCaseTrait<MergePdfBuilder> */
use WebhookTestCaseTrait;

private const ASSETS_DIR = __DIR__.'/../../Fixtures/assets';

protected function createBuilder(): MergePdfBuilder
{
return new MergePdfBuilder();
Expand Down Expand Up @@ -86,7 +88,7 @@ public function testFilesExtensionRequirement(): void
$this->expectExceptionMessage('The file extension "png" is not valid in this context.');

$this->getBuilder()
->files('simple_pdf.pdf', 'b.png')
->files(self::ASSETS_DIR.'logo.png')
->generate()
;
}
Expand Down
4 changes: 3 additions & 1 deletion tests/Builder/Pdf/SplitPdfBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ final class SplitPdfBuilderTest extends GotenbergBuilderTestCase
/** @use WebhookTestCaseTrait<SplitPdfBuilder> */
use WebhookTestCaseTrait;

private const ASSETS_DIR = __DIR__.'/../../Fixtures/assets';

protected function createBuilder(): SplitPdfBuilder
{
return new SplitPdfBuilder();
Expand Down Expand Up @@ -95,7 +97,7 @@ public function testFilesExtensionRequirement(): void
$this->expectExceptionMessage('The file extension "png" is not valid in this context.');

$this->getBuilder()
->files('b.png')
->files(self::ASSETS_DIR.'logo.png')
->splitMode(SplitMode::Pages)
->splitSpan('1-2')
->generate()
Expand Down
4 changes: 2 additions & 2 deletions tests/Builder/Screenshot/HtmlScreenshotBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ protected function initializeBuilder(BuilderInterface $builder, Container $conta

public function testOutputFilename(): void
{
$this->container->set('asset_base_dir_formatter', new AssetBaseDirFormatter(self::FIXTURE_DIR, self::FIXTURE_DIR));
$this->container->set('asset_base_dir_formatter', new AssetBaseDirFormatter(self::FIXTURE_DIR, [self::FIXTURE_DIR]));

$this->getBuilder()
->contentFile('files/content.html')
Expand All @@ -60,7 +60,7 @@ public function testWithTwigContentFile(): void
$twig->addRuntimeLoader(new class implements RuntimeLoaderInterface {
public function load(string $class): object|null
{
return GotenbergRuntime::class === $class ? new GotenbergRuntime() : null;
return GotenbergRuntime::class === $class ? new GotenbergRuntime(null) : null;
}
});

Expand Down
Loading