Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
33 changes: 26 additions & 7 deletions src/Formatter/AssetBaseDirFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,51 @@

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(static fn ($value) => 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" not found in assets directories: "%s".', $path, implode('", "', $this->baseDir)));
}
}
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