diff --git a/src/Backend/WkHtmlToPdf/Option.php b/src/Backend/WkHtmlToPdf/Option.php
new file mode 100644
index 00000000..e69de29b
diff --git a/src/Backend/WkHtmlToPdf/OptionGroup.php b/src/Backend/WkHtmlToPdf/OptionGroup.php
new file mode 100644
index 00000000..c7738c10
--- /dev/null
+++ b/src/Backend/WkHtmlToPdf/OptionGroup.php
@@ -0,0 +1,21 @@
+ */
+ public function compile(): array
+ {
+ $options = [];
+
+ foreach ($this as $property) {
+ if ($property instanceof Option) {
+ $options = array_merge($options, $property->compile());
+ }
+ }
+
+ return $options;
+ }
+}
diff --git a/src/Backend/WkHtmlToPdf/Options/GlobalOptions.php b/src/Backend/WkHtmlToPdf/Options/GlobalOptions.php
new file mode 100644
index 00000000..8f35e54e
--- /dev/null
+++ b/src/Backend/WkHtmlToPdf/Options/GlobalOptions.php
@@ -0,0 +1,22 @@
+number];
+ }
+}
diff --git a/src/Backend/WkHtmlToPdf/Options/GlobalOptions/DpiOption.php b/src/Backend/WkHtmlToPdf/Options/GlobalOptions/DpiOption.php
new file mode 100644
index 00000000..27542c90
--- /dev/null
+++ b/src/Backend/WkHtmlToPdf/Options/GlobalOptions/DpiOption.php
@@ -0,0 +1,15 @@
+dpi];
+ }
+}
diff --git a/src/Backend/WkHtmlToPdf/Options/GlobalOptions/GrayscaleOption.php b/src/Backend/WkHtmlToPdf/Options/GlobalOptions/GrayscaleOption.php
new file mode 100644
index 00000000..7093e0a7
--- /dev/null
+++ b/src/Backend/WkHtmlToPdf/Options/GlobalOptions/GrayscaleOption.php
@@ -0,0 +1,15 @@
+
@@ -26,7 +32,9 @@ public function __construct(
private string $binary,
private int $timeout,
WkHtmlToPdfFactory $factory,
- Options $options
+ Options $options,
+ private readonly StreamFactoryInterface $streamFactory,
+ private readonly UriFactoryInterface $uriFactory,
) {
$this->factory = $factory;
$this->options = $options;
@@ -34,6 +42,112 @@ public function __construct(
public function generateFromHtmlFile(SplFileInfo $file): StreamInterface
{
- throw new \Exception("Not implemented for {$this->binary} with timeout {$this->timeout}.");
+ $filepath = $file->getRealPath();
+
+ if ($filepath === false) {
+ throw new \RuntimeException("File not found: {$file->getPathname()}.");
+ }
+
+ return $this->generateFromUri(
+ $this->uriFactory->createUri($filepath)->withScheme('file')
+ );
+ }
+
+ public function generateFromUri(UriInterface $uri): StreamInterface
+ {
+ $outputStream = FileStream::createTmpFile($this->streamFactory);
+
+ $process = new Process(
+ command: [
+ $this->binary,
+ ...$this->compileOptions(),
+ $uri->toString(),
+ $outputStream->file->getPathname(),
+ ],
+ timeout: $this->timeout,
+ );
+
+ return $outputStream;
+ }
+
+ /**
+ * @return array
+ */
+ private function compileOptions(): array
+ {
+ return array_merge(
+ $this->compileGlobalOptions(),
+ $this->compileOutlineOptions(),
+ $this->compilePageOptions(),
+ $this->compileHeadersAndFootersOptions(),
+ $this->compileTocOptions(),
+ );
+ }
+
+ /**
+ * @return array
+ */
+ private function compileGlobalOptions(): array
+ {
+ if (isset($this->options->extraOptions['global']) && \is_array($this->options->extraOptions['global'])) {
+ return $this->options->extraOptions['global'];
+ }
+
+ if ($this->options->pageOrientation !== null) {
+ $options['orientation'] = match ($this->options->pageOrientation) {
+ PageOrientation::PORTRAIT => 'Portrait',
+ PageOrientation::LANDSCAPE => 'Landscape',
+ };
+ }
+
+ return [];
+ }
+
+ /**
+ * @return array
+ */
+ private function compileOutlineOptions(): array
+ {
+ if (isset($this->options->extraOptions['outline']) && \is_array($this->options->extraOptions['outline'])) {
+ return $this->options->extraOptions['outline'];
+ }
+
+ return [];
+ }
+
+ /**
+ * @return array
+ */
+ private function compilePageOptions(): array
+ {
+ if (isset($this->options->extraOptions['page']) && \is_array($this->options->extraOptions['page'])) {
+ return $this->options->extraOptions['page'];
+ }
+
+ return [];
+ }
+
+ /**
+ * @return array
+ */
+ private function compileHeadersAndFootersOptions(): array
+ {
+ if (isset($this->options->extraOptions['headersAndFooters']) && \is_array($this->options->extraOptions['headersAndFooters'])) {
+ return $this->options->extraOptions['headersAndFooters'];
+ }
+
+ return [];
+ }
+
+ /**
+ * @return array
+ */
+ private function compileTocOptions(): array
+ {
+ if (isset($this->options->extraOptions['toc']) && \is_array($this->options->extraOptions['toc'])) {
+ return $this->options->extraOptions['toc'];
+ }
+
+ return [];
}
}