Skip to content

Commit dbbb6c0

Browse files
committed
feat(split): add the split feature
1 parent 00efc25 commit dbbb6c0

8 files changed

Lines changed: 182 additions & 0 deletions

File tree

src/Modules/ChromiumPdf.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Gotenberg\Modules;
66

77
use Gotenberg\Exceptions\NativeFunctionErrored;
8+
use Gotenberg\SplitMode;
89
use Gotenberg\Stream;
910
use Psr\Http\Message\RequestInterface;
1011

@@ -153,6 +154,18 @@ public function footer(Stream $footer): self
153154
return $this;
154155
}
155156

157+
/**
158+
* Splits the resulting PDF.
159+
*/
160+
public function split(SplitMode $mode): self
161+
{
162+
$this->formValue('splitMode', $mode->mode);
163+
$this->formValue('splitSpan', $mode->span);
164+
$this->formValue('splitUnify', $mode->unify ?: '0');
165+
166+
return $this;
167+
}
168+
156169
/**
157170
* Sets the PDF/A format of the resulting PDF.
158171
*/

src/Modules/LibreOffice.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Gotenberg\HrtimeIndex;
99
use Gotenberg\Index;
1010
use Gotenberg\MultipartFormDataModule;
11+
use Gotenberg\SplitMode;
1112
use Gotenberg\Stream;
1213
use Psr\Http\Message\RequestInterface;
1314

@@ -324,6 +325,18 @@ public function merge(): self
324325
return $this;
325326
}
326327

328+
/**
329+
* Splits the resulting PDFs.
330+
*/
331+
public function split(SplitMode $mode): self
332+
{
333+
$this->formValue('splitMode', $mode->mode);
334+
$this->formValue('splitSpan', $mode->span);
335+
$this->formValue('splitUnify', $mode->unify ?: '0');
336+
337+
return $this;
338+
}
339+
327340
/**
328341
* Converts the given document(s) to PDF(s). Gotenberg will return either
329342
* a unique PDF if you request a merge or a ZIP archive with the PDFs.

src/Modules/PdfEngines.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Gotenberg\HrtimeIndex;
99
use Gotenberg\Index;
1010
use Gotenberg\MultipartFormDataModule;
11+
use Gotenberg\SplitMode;
1112
use Gotenberg\Stream;
1213
use Psr\Http\Message\RequestInterface;
1314

@@ -87,6 +88,26 @@ public function merge(Stream ...$pdfs): RequestInterface
8788
return $this->request();
8889
}
8990

91+
/**
92+
* Splits PDFs.
93+
*/
94+
public function split(SplitMode $mode, Stream ...$pdfs): RequestInterface
95+
{
96+
$this->formValue('splitMode', $mode->mode);
97+
$this->formValue('splitSpan', $mode->span);
98+
$this->formValue('splitUnify', $mode->unify ?: '0');
99+
100+
$index = $this->index ?? new HrtimeIndex();
101+
102+
foreach ($pdfs as $pdf) {
103+
$this->formFile($index->create() . '_' . $pdf->getFilename(), $pdf->getStream());
104+
}
105+
106+
$this->endpoint = '/forms/pdfengines/split';
107+
108+
return $this->request();
109+
}
110+
90111
/**
91112
* Converts PDF(s) to a specific PDF/A format.
92113
* Gotenberg will return the PDF or a ZIP archive with the PDFs.

src/SplitMode.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Gotenberg;
6+
7+
class SplitMode
8+
{
9+
public function __construct(
10+
public readonly string $mode,
11+
public readonly string $span,
12+
public readonly bool $unify,
13+
) {
14+
}
15+
16+
public static function intervals(int $span): self
17+
{
18+
return new self(
19+
'intervals',
20+
$span . '',
21+
false,
22+
);
23+
}
24+
25+
public static function pages(string $span, bool $unify = false): self
26+
{
27+
return new self(
28+
'pages',
29+
$span,
30+
$unify,
31+
);
32+
}
33+
}

tests/Modules/ChromiumPdfTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Gotenberg\Gotenberg;
77
use Gotenberg\Modules\ChromiumCookie;
88
use Gotenberg\Modules\ChromiumPdf;
9+
use Gotenberg\SplitMode;
910
use Gotenberg\Stream;
1011

1112
it(
@@ -47,6 +48,7 @@ function (
4748
bool $failOnResourceLoadingFailed = false,
4849
bool $failOnConsoleExceptions = false,
4950
bool|null $skipNetworkIdleEvent = null,
51+
SplitMode|null $splitMode = null,
5052
string|null $pdfa = null,
5153
bool $pdfua = false,
5254
array $metadata = [],
@@ -82,6 +84,7 @@ function (
8284
$failOnResourceLoadingFailed,
8385
$failOnConsoleExceptions,
8486
$skipNetworkIdleEvent,
87+
$splitMode,
8588
$pdfa,
8689
$pdfua,
8790
$metadata,
@@ -123,6 +126,7 @@ function (
123126
$failOnResourceLoadingFailed,
124127
$failOnConsoleExceptions,
125128
$skipNetworkIdleEvent,
129+
$splitMode,
126130
$pdfa,
127131
$pdfua,
128132
$metadata,
@@ -167,6 +171,7 @@ function (
167171
true,
168172
true,
169173
true,
174+
SplitMode::intervals(1),
170175
'PDF/A-1a',
171176
true,
172177
[ 'Producer' => 'Gotenberg' ],
@@ -215,6 +220,7 @@ function (
215220
bool $failOnResourceLoadingFailed = false,
216221
bool $failOnConsoleExceptions = false,
217222
bool|null $skipNetworkIdleEvent = null,
223+
SplitMode|null $splitMode = null,
218224
string|null $pdfa = null,
219225
bool $pdfua = false,
220226
array $metadata = [],
@@ -250,6 +256,7 @@ function (
250256
$failOnResourceLoadingFailed,
251257
$failOnConsoleExceptions,
252258
$skipNetworkIdleEvent,
259+
$splitMode,
253260
$pdfa,
254261
$pdfua,
255262
$metadata,
@@ -293,6 +300,7 @@ function (
293300
$failOnResourceLoadingFailed,
294301
$failOnConsoleExceptions,
295302
$skipNetworkIdleEvent,
303+
$splitMode,
296304
$pdfa,
297305
$pdfua,
298306
$metadata,
@@ -336,6 +344,7 @@ function (
336344
true,
337345
true,
338346
true,
347+
SplitMode::intervals(1),
339348
'PDF/A-1a',
340349
true,
341350
[ 'Producer' => 'Gotenberg' ],
@@ -386,6 +395,7 @@ function (
386395
bool $failOnResourceLoadingFailed = false,
387396
bool $failOnConsoleExceptions = false,
388397
bool|null $skipNetworkIdleEvent = null,
398+
SplitMode|null $splitMode = null,
389399
string|null $pdfa = null,
390400
bool $pdfua = false,
391401
array $metadata = [],
@@ -421,6 +431,7 @@ function (
421431
$failOnResourceLoadingFailed,
422432
$failOnConsoleExceptions,
423433
$skipNetworkIdleEvent,
434+
$splitMode,
424435
$pdfa,
425436
$pdfua,
426437
$metadata,
@@ -469,6 +480,7 @@ function (
469480
$failOnResourceLoadingFailed,
470481
$failOnConsoleExceptions,
471482
$skipNetworkIdleEvent,
483+
$splitMode,
472484
$pdfa,
473485
$pdfua,
474486
$metadata,
@@ -521,6 +533,7 @@ function (
521533
true,
522534
true,
523535
true,
536+
SplitMode::intervals(1),
524537
'PDF/A-1a',
525538
true,
526539
[ 'Producer' => 'Gotenberg' ],
@@ -567,6 +580,7 @@ function hydrateChromiumPdfFormData(
567580
bool $failOnResourceLoadingFailed = false,
568581
bool $failOnConsoleExceptions = false,
569582
bool|null $skipNetworkIdleEvent = null,
583+
SplitMode|null $splitMode = null,
570584
string|null $pdfa = null,
571585
bool $pdfua = false,
572586
array $metadata = [],
@@ -668,6 +682,10 @@ function hydrateChromiumPdfFormData(
668682
$chromium->skipNetworkIdleEvent($skipNetworkIdleEvent);
669683
}
670684

685+
if ($splitMode !== null) {
686+
$chromium->split($splitMode);
687+
}
688+
671689
if ($pdfa !== null) {
672690
$chromium->pdfa($pdfa);
673691
}
@@ -724,6 +742,7 @@ function expectChromiumPdfOptions(
724742
bool $failOnResourceLoadingFailed,
725743
bool $failOnConsoleExceptions,
726744
bool|null $skipNetworkIdleEvent,
745+
SplitMode|null $splitMode,
727746
string|null $pdfa,
728747
bool $pdfua,
729748
array $metadata,
@@ -808,6 +827,13 @@ function expectChromiumPdfOptions(
808827
expect($body)->unless($failOnResourceLoadingFailed === false, fn ($body) => $body->toContainFormValue('failOnResourceLoadingFailed', '1'));
809828
expect($body)->unless($failOnConsoleExceptions === false, fn ($body) => $body->toContainFormValue('failOnConsoleExceptions', '1'));
810829
expect($body)->unless($skipNetworkIdleEvent === null, fn ($body) => $body->toContainFormValue('skipNetworkIdleEvent', $skipNetworkIdleEvent === true ? '1' : '0'));
830+
831+
if ($splitMode !== null) {
832+
expect($body)->toContainFormValue('splitMode', $splitMode->mode);
833+
expect($body)->toContainFormValue('splitSpan', $splitMode->span);
834+
expect($body)->toContainFormValue('splitUnify', $splitMode->unify ? '1' : '0');
835+
}
836+
811837
expect($body)->unless($pdfa === null, fn ($body) => $body->toContainFormValue('pdfa', $pdfa));
812838
expect($body)->unless($pdfua === false, fn ($body) => $body->toContainFormValue('pdfua', '1'));
813839

tests/Modules/LibreOfficeTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Gotenberg\Exceptions\NativeFunctionErrored;
66
use Gotenberg\Gotenberg;
7+
use Gotenberg\SplitMode;
78
use Gotenberg\Stream;
89
use Gotenberg\Test\DummyIndex;
910

@@ -37,6 +38,7 @@ function (
3738
int|null $quality = null,
3839
bool $reduceImageResolution = false,
3940
int|null $maxImageResolution = null,
41+
SplitMode|null $splitMode = null,
4042
string|null $pdfa = null,
4143
bool $pdfua = false,
4244
array $metadata = [],
@@ -136,6 +138,10 @@ function (
136138
$libreOffice->pdfa($pdfa);
137139
}
138140

141+
if ($splitMode !== null) {
142+
$libreOffice->split($splitMode);
143+
}
144+
139145
if ($pdfua) {
140146
$libreOffice->pdfua();
141147
}
@@ -176,6 +182,13 @@ function (
176182
expect($body)->unless($quality === null, fn ($body) => $body->toContainFormValue('quality', $quality));
177183
expect($body)->unless($reduceImageResolution === false, fn ($body) => $body->toContainFormValue('reduceImageResolution', '1'));
178184
expect($body)->unless($maxImageResolution === null, fn ($body) => $body->toContainFormValue('maxImageResolution', $maxImageResolution));
185+
186+
if ($splitMode !== null) {
187+
expect($body)->toContainFormValue('splitMode', $splitMode->mode);
188+
expect($body)->toContainFormValue('splitSpan', $splitMode->span);
189+
expect($body)->toContainFormValue('splitUnify', $splitMode->unify ? '1' : '0');
190+
}
191+
179192
expect($body)->unless($pdfa === null, fn ($body) => $body->toContainFormValue('pdfa', $pdfa));
180193
expect($body)->unless($pdfua === false, fn ($body) => $body->toContainFormValue('pdfua', '1'));
181194
expect($body)->unless($merge === false, fn ($body) => $body->toContainFormValue('merge', '1'));
@@ -229,6 +242,7 @@ function (
229242
100,
230243
true,
231244
150,
245+
SplitMode::intervals(1),
232246
'PDF/A-1a',
233247
true,
234248
[ 'Producer' => 'Gotenberg' ],

tests/Modules/PdfEnginesTest.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Gotenberg\Exceptions\NativeFunctionErrored;
66
use Gotenberg\Gotenberg;
7+
use Gotenberg\SplitMode;
78
use Gotenberg\Stream;
89
use Gotenberg\Test\DummyIndex;
910

@@ -68,6 +69,42 @@ function (array $pdfs, string|null $pdfa = null, bool $pdfua = false, array $met
6869
],
6970
]);
7071

72+
it(
73+
'creates a valid request for the "/forms/pdfengines/split" endpoint',
74+
/** @param Stream[] $pdfs */
75+
function (array $pdfs, SplitMode $mode): void {
76+
$pdfEngines = Gotenberg::pdfEngines('')->index(new DummyIndex());
77+
78+
$request = $pdfEngines->split($mode, ...$pdfs);
79+
$body = sanitize($request->getBody()->getContents());
80+
81+
expect($request->getUri()->getPath())->toBe('/forms/pdfengines/split');
82+
expect($body)->toContainFormValue('splitMode', $mode->mode);
83+
expect($body)->toContainFormValue('splitSpan', $mode->span);
84+
expect($body)->toContainFormValue('splitUnify', $mode->unify ? '1' : '0');
85+
86+
foreach ($pdfs as $pdf) {
87+
$pdf->getStream()->rewind();
88+
expect($body)->toContainFormFile('foo_' . $pdf->getFilename(), $pdf->getStream()->getContents(), 'application/pdf');
89+
}
90+
},
91+
)->with([
92+
[
93+
[
94+
Stream::string('my.pdf', 'PDF content'),
95+
],
96+
SplitMode::intervals(1),
97+
],
98+
[
99+
[
100+
Stream::string('my.pdf', 'PDF content'),
101+
Stream::string('my_second.pdf', 'Second PDF content'),
102+
Stream::string('my_third.pdf', 'Third PDF content'),
103+
],
104+
SplitMode::pages('1-2', true),
105+
],
106+
]);
107+
71108
it(
72109
'creates a valid request for the "/forms/pdfengines/convert" endpoint',
73110
function (string $pdfa, Stream ...$pdfs): void {

tests/SplitModeTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Gotenberg\SplitMode;
6+
7+
it(
8+
'creates an intervals split mode',
9+
function (): void {
10+
$mode = SplitMode::intervals(1);
11+
expect($mode->mode)->toBe('intervals');
12+
expect($mode->span)->toBe('1');
13+
expect($mode->unify)->toBeFalse();
14+
},
15+
);
16+
17+
it(
18+
'creates a pages split mode',
19+
function (): void {
20+
$mode = SplitMode::pages('1-2', true);
21+
expect($mode->mode)->toBe('pages');
22+
expect($mode->span)->toBe('1-2');
23+
expect($mode->unify)->toBeTrue();
24+
},
25+
);

0 commit comments

Comments
 (0)