Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Markdown screenshot URL + Add headers to client call + Some renaming + Add metadata to files + Units in paper size #41

Merged
merged 8 commits into from
May 30, 2024
Merged
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
8 changes: 4 additions & 4 deletions docs/custom-builders.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Alternatively, you can use the BodyPart enum to rename your file on the fly.

.. code-block:: php

use Sensiolabs\GotenbergBundle\Enum\PdfPart;
use Sensiolabs\GotenbergBundle\Enum\Part;
use Symfony\Component\Mime\Part\DataPart;
use Symfony\Component\Mime\Part\File;

Expand All @@ -54,7 +54,7 @@ Alternatively, you can use the BodyPart enum to rename your file on the fly.

public function content(string $path): self
{
$dataPart = DataPart::fromPath($path, PdfPart::BodyPart->value);
$dataPart = DataPart::fromPath($path, Part::BodyPart->value);

$this->multipartFormData[] = [
'files' => $dataPart,
Expand Down Expand Up @@ -92,7 +92,7 @@ and use everything you want.

.. code-block:: php

use Sensiolabs\GotenbergBundle\Enum\PdfPart;
use Sensiolabs\GotenbergBundle\Enum\Part;
use Symfony\Component\Mime\Part\DataPart;
use Symfony\Component\Mime\Part\File;

Expand All @@ -107,7 +107,7 @@ and use everything you want.

public function content(string $path): self
{
$dataPart = DataPart::fromPath($path, PdfPart::BodyPart->value);
$dataPart = DataPart::fromPath($path, Part::BodyPart->value);

$this->multipartFormData[] = [
'files' => $dataPart,
Expand Down
127 changes: 91 additions & 36 deletions src/Builder/Pdf/AbstractChromiumPdfBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
namespace Sensiolabs\GotenbergBundle\Builder\Pdf;

use Sensiolabs\GotenbergBundle\Client\GotenbergClientInterface;
use Sensiolabs\GotenbergBundle\Enum\PaperSize;
use Sensiolabs\GotenbergBundle\Enum\PaperSizeInterface;
use Sensiolabs\GotenbergBundle\Enum\PdfPart;
use Sensiolabs\GotenbergBundle\Enum\Part;
use Sensiolabs\GotenbergBundle\Enum\PdfFormat;
use Sensiolabs\GotenbergBundle\Enum\Unit;
use Sensiolabs\GotenbergBundle\Exception\InvalidBuilderConfiguration;
use Sensiolabs\GotenbergBundle\Exception\PdfPartRenderingException;
use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter;
Expand Down Expand Up @@ -36,6 +39,18 @@ public function setConfigurations(array $configurations): static
return $this;
}

/**
* Define whether to print the entire content in one single page.
*
* If the singlePage form field is set to true, it automatically overrides the values from the paperHeight and nativePageRanges form fields.
*/
public function singlePage(bool $bool = true): static
{
$this->formFields['singlePage'] = $bool;

return $this;
}

/**
* Overrides the default paper size, in inches.
*
Expand All @@ -55,32 +70,32 @@ public function setConfigurations(array $configurations): static
*
* @see https://gotenberg.dev/docs/routes#page-properties-chromium
*/
public function paperSize(float $width, float $height): static
public function paperSize(float $width, float $height, Unit $unit = Unit::Inches): static
{
$this->paperWidth($width);
$this->paperHeight($height);
$this->paperWidth($width, $unit);
$this->paperHeight($height, $unit);

return $this;
}

public function paperStandardSize(PaperSizeInterface $paperSize): static
{
$this->paperWidth($paperSize->width());
$this->paperHeight($paperSize->height());
$this->paperWidth($paperSize->width(), $paperSize->unit());
$this->paperHeight($paperSize->height(), $paperSize->unit());

return $this;
}

public function paperWidth(float $width): static
public function paperWidth(float $width, Unit $unit = Unit::Inches): static
{
$this->formFields['paperWidth'] = $width;
$this->formFields['paperWidth'] = $width.$unit->value;

return $this;
}

public function paperHeight(float $height): static
public function paperHeight(float $height, Unit $unit = Unit::Inches): static
{
$this->formFields['paperHeight'] = $height;
$this->formFields['paperHeight'] = $height.$unit->value;

return $this;
}
Expand All @@ -90,40 +105,40 @@ public function paperHeight(float $height): static
*
* @see https://gotenberg.dev/docs/routes#page-properties-chromium
*/
public function margins(float $top, float $bottom, float $left, float $right): static
public function margins(float $top, float $bottom, float $left, float $right, Unit $unit = Unit::Inches): static
{
$this->marginTop($top);
$this->marginBottom($bottom);
$this->marginLeft($left);
$this->marginRight($right);
$this->marginTop($top, $unit);
$this->marginBottom($bottom, $unit);
$this->marginLeft($left, $unit);
$this->marginRight($right, $unit);

return $this;
}

public function marginTop(float $top): static
public function marginTop(float $top, Unit $unit = Unit::Inches): static
{
$this->formFields['marginTop'] = $top;
$this->formFields['marginTop'] = $top.$unit->value;

return $this;
}

public function marginBottom(float $bottom): static
public function marginBottom(float $bottom, Unit $unit = Unit::Inches): static
{
$this->formFields['marginBottom'] = $bottom;
$this->formFields['marginBottom'] = $bottom.$unit->value;

return $this;
}

public function marginLeft(float $left): static
public function marginLeft(float $left, Unit $unit = Unit::Inches): static
{
$this->formFields['marginLeft'] = $left;
$this->formFields['marginLeft'] = $left.$unit->value;

return $this;
}

public function marginRight(float $right): static
public function marginRight(float $right, Unit $unit = Unit::Inches): static
{
$this->formFields['marginRight'] = $right;
$this->formFields['marginRight'] = $right.$unit->value;

return $this;
}
Expand Down Expand Up @@ -209,7 +224,7 @@ public function nativePageRanges(string $range): static
*/
public function header(string $template, array $context = []): static
{
return $this->withRenderedPart(PdfPart::HeaderPart, $template, $context);
return $this->withRenderedPart(Part::Header, $template, $context);
}

/**
Expand All @@ -220,23 +235,23 @@ public function header(string $template, array $context = []): static
*/
public function footer(string $template, array $context = []): static
{
return $this->withRenderedPart(PdfPart::FooterPart, $template, $context);
return $this->withRenderedPart(Part::Footer, $template, $context);
}

/**
* HTML file containing the header. (default None).
*/
public function headerFile(string $path): static
{
return $this->withPdfPartFile(PdfPart::HeaderPart, $path);
return $this->withPdfPartFile(Part::Header, $path);
}

/**
* HTML file containing the footer. (default None).
*/
public function footerFile(string $path): static
{
return $this->withPdfPartFile(PdfPart::FooterPart, $path);
return $this->withPdfPartFile(Part::Footer, $path);
}

/**
Expand Down Expand Up @@ -422,9 +437,15 @@ public function skipNetworkIdleEvent(bool $bool = true): static
*
* @See https://gotenberg.dev/docs/routes#pdfa-chromium.
*/
public function pdfFormat(string $format): static
public function pdfFormat(PdfFormat|null $format = null): static
{
$this->formFields['pdfa'] = $format;
if (null === $format) {
unset($this->formFields['pdfa']);

return $this;
}

$this->formFields['pdfa'] = $format->value;

return $this;
}
Expand All @@ -441,7 +462,33 @@ public function pdfUniversalAccess(bool $bool = true): static
return $this;
}

protected function withPdfPartFile(PdfPart $pdfPart, string $path): static
/**
* Resets the metadata.
*
* @see https://gotenberg.dev/docs/routes#metadata-chromium
* @see https://exiftool.org/TagNames/XMP.html#pdf
*
* @param array<string, mixed> $metadata
*/
public function metadata(array $metadata): static
{
$this->formFields['metadata'] = $metadata;

return $this;
}

/**
* The metadata to write.
*/
public function addMetadata(string $key, string $value): static
{
$this->formFields['metadata'] ??= [];
$this->formFields['metadata'][$key] = $value;

return $this;
}

protected function withPdfPartFile(Part $pdfPart, string $path): static
{
$dataPart = new DataPart(
new DataPartFile($this->asset->resolve($path)),
Expand All @@ -459,7 +506,7 @@ protected function withPdfPartFile(PdfPart $pdfPart, string $path): static
*
* @throws PdfPartRenderingException if the template could not be rendered
*/
protected function withRenderedPart(PdfPart $pdfPart, string $template, array $context = []): static
protected function withRenderedPart(Part $pdfPart, string $template, array $context = []): static
{
if (!$this->twig instanceof Environment) {
throw new \LogicException(sprintf('Twig is required to use "%s" method. Try to run "composer require symfony/twig-bundle".', __METHOD__));
Expand All @@ -478,15 +525,22 @@ protected function withRenderedPart(PdfPart $pdfPart, string $template, array $c

private function addConfiguration(string $configurationName, mixed $value): void
{
$splitAndParseStringWithUnit = static function (mixed $raw, callable $callback): void {
[$value, $unit] = sscanf((string) $raw, '%d%s') ?? throw new \InvalidArgumentException(sprintf('Unexpected value "%s", expected format is "%%d%%s"', $raw));

$callback((float) $value, Unit::tryFrom((string) $unit) ?? Unit::Inches);
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we could emit a log if the unit is invalid ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. Will do in another PR where I will add several logs like this one.

};

match ($configurationName) {
'pdf_format' => $this->pdfFormat($value),
'single_page' => $this->singlePage($value),
'pdf_format' => $this->pdfFormat(PdfFormat::from($value)),
'pdf_universal_access' => $this->pdfUniversalAccess($value),
'paper_width' => $this->paperWidth($value),
'paper_height' => $this->paperHeight($value),
'margin_top' => $this->marginTop($value),
'margin_bottom' => $this->marginBottom($value),
'margin_left' => $this->marginLeft($value),
'margin_right' => $this->marginRight($value),
'margin_top' => $splitAndParseStringWithUnit($value, $this->marginTop(...)),
'margin_bottom' => $splitAndParseStringWithUnit($value, $this->marginBottom(...)),
'margin_left' => $splitAndParseStringWithUnit($value, $this->marginLeft(...)),
'margin_right' => $splitAndParseStringWithUnit($value, $this->marginRight(...)),
'prefer_css_page_size' => $this->preferCssPageSize($value),
'print_background' => $this->printBackground($value),
'omit_background' => $this->omitBackground($value),
Expand All @@ -501,6 +555,7 @@ private function addConfiguration(string $configurationName, mixed $value): void
'fail_on_http_status_codes' => $this->failOnHttpStatusCodes($value),
'fail_on_console_exceptions' => $this->failOnConsoleExceptions($value),
'skip_network_idle_event' => $this->skipNetworkIdleEvent($value),
'metadata' => $this->metadata($value),
default => throw new InvalidBuilderConfiguration(sprintf('Invalid option "%s": no method does not exist in class "%s" to configured it.', $configurationName, static::class)),
};
}
Expand Down
13 changes: 8 additions & 5 deletions src/Builder/Pdf/AbstractPdfBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use Sensiolabs\GotenbergBundle\Client\GotenbergClientInterface;
use Sensiolabs\GotenbergBundle\Client\GotenbergResponse;
use Sensiolabs\GotenbergBundle\Enum\PdfPart;
use Sensiolabs\GotenbergBundle\Enum\Part;
use Sensiolabs\GotenbergBundle\Exception\JsonEncodingException;
use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter;
use Symfony\Component\HttpFoundation\File\File;
Expand Down Expand Up @@ -38,20 +38,23 @@ public function __construct(
'assets' => static function (array $value): array {
return ['files' => $value];
},
PdfPart::HeaderPart->value => static function (DataPart $value): array {
Part::Header->value => static function (DataPart $value): array {
return ['files' => $value];
},
PdfPart::BodyPart->value => static function (DataPart $value): array {
Part::Body->value => static function (DataPart $value): array {
return ['files' => $value];
},
PdfPart::FooterPart->value => static function (DataPart $value): array {
Part::Footer->value => static function (DataPart $value): array {
return ['files' => $value];
},
'failOnHttpStatusCodes' => function (mixed $value): array {
return $this->encodeData('failOnHttpStatusCodes', $value);
},
'cookies' => function (mixed $value): array {
return $this->encodeData('cookies', array_values($value));
return $this->encodeData('cookies', \array_values($value));
},
'metadata' => function (mixed $value): array {
return $this->encodeData('metadata', $value);
},
];
}
Expand Down
8 changes: 4 additions & 4 deletions src/Builder/Pdf/HtmlPdfBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Sensiolabs\GotenbergBundle\Builder\Pdf;

use Sensiolabs\GotenbergBundle\Enum\PdfPart;
use Sensiolabs\GotenbergBundle\Enum\Part;
use Sensiolabs\GotenbergBundle\Exception\MissingRequiredFieldException;
use Sensiolabs\GotenbergBundle\Exception\PdfPartRenderingException;

Expand All @@ -18,20 +18,20 @@ final class HtmlPdfBuilder extends AbstractChromiumPdfBuilder
*/
public function content(string $template, array $context = []): self
{
return $this->withRenderedPart(PdfPart::BodyPart, $template, $context);
return $this->withRenderedPart(Part::Body, $template, $context);
}

/**
* The HTML file to convert into PDF.
*/
public function contentFile(string $path): self
{
return $this->withPdfPartFile(PdfPart::BodyPart, $path);
return $this->withPdfPartFile(Part::Body, $path);
}

public function getMultipartFormData(): array
{
if (!\array_key_exists(PdfPart::BodyPart->value, $this->formFields)) {
if (!\array_key_exists(Part::Body->value, $this->formFields)) {
throw new MissingRequiredFieldException('Content is required');
}

Expand Down
Loading