diff --git a/README.md b/README.md index 66924f4..b7e8b98 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,9 @@ PHP wrapper for the qpdf library. -Basic Example: +Basic Examples: +### Merge ```php $qpdf = new \EddTurtle\Qpdf\Pdf(); @@ -17,4 +18,42 @@ if (!$result || !empty($qpdf->getError())) { } else { var_dump('success'); } +``` + +### Split a multi page PDF file +```php +$qpdf = new \EddTurtle\Qpdf\Pdf(); +$qpdf->addPage(__DIR__ . "/files/TestPdfTwoPage.pdf"); +$qpdf->split(__DIR__."/output/test-split.pdf"); + +if (!$result || !empty($qpdf->getError())) { + var_dump($qpdf->getError()); +} else { + var_dump('success'); +} +// Results in "/output/" containing 'test-split-1.pdf' and 'test-split-2.pdf' +``` + +### Rotate a PDF file +```php +$qpdf = new \EddTurtle\Qpdf\Pdf(); +$pdf->addPage(__DIR__ . "/files/TestPdfTwoPage.pdf"); +$result = $pdf->rotate(__DIR__ . "/output/rotated.pdf", "+90", "1"); + +if (!$result || !empty($qpdf->getError())) { + var_dump($qpdf->getError()); +} else { + var_dump('success'); +} +// Results in "/output/rotated.pdf" having its first page rotated 90° clockwise +``` + + +### Count PDF pages +```php +$qpdf = new \EddTurtle\Qpdf\Pdf(); +$pdf->addPage(__DIR__ . "/files/TestPdfTwoPage.pdf"); +$pdf->addPage(__DIR__ . "/files/TestPdf.pdf"); +$count = $pdf->getPageCount(); +// Results in $count containing a value of 3 ``` \ No newline at end of file diff --git a/src/Pdf.php b/src/Pdf.php index 35fd0c0..087feb8 100644 --- a/src/Pdf.php +++ b/src/Pdf.php @@ -8,7 +8,7 @@ class Pdf { /** - * @var Command the command instance that executes pdftk + * @var Command the command instance that executes QPDF */ protected $command; @@ -39,6 +39,12 @@ public function getCommand() return $this->command; } + public function resetCommand() + { + $this->command = new Command($this->options); + return $this->command; + } + public function execute() { $command = $this->getCommand(); @@ -80,6 +86,14 @@ public function getVersion() return false; } + /** + * Add a PDF file path to be operated upon + * + * @param string $pathName String path to pdf file + * @return false|$this + * + * + */ public function addPage($pdfName) { if (!file_exists($pdfName)) { @@ -90,11 +104,24 @@ public function addPage($pdfName) return $this; } + /** + * Return array of all added file paths + * + * @return array + * + */ public function getPages() { return $this->pages; } + /** + * Merge all added pages in the object into a single output file. + * + * @param string $target Path to output file + * @return bool + * + */ public function merge($target) { $cmd = $this->getCommand(); @@ -105,4 +132,85 @@ public function merge($target) return $this->execute(); } + /** + * Split a document into a smaller number of pages. + * + * @param string $target Path to output file + * @param string $pagesPerGroup Integer indicating how many pages per output file. Default is 1. + * in the QPDF docs. Null value assumes to apply to all pages. Default is null. + * @return bool + * + * @throws \Exception + */ + public function split($target, $pagesPerGroup=1) + { + if(count($this->pages) > 1) { + throw new \Exception("Error! Currently unable to split when more than one PDF file is specified."); + } + + $cmd = $this->getCommand(); + $cmd->addArg('--split-pages=', $pagesPerGroup, false); + $cmd->addArg('', $this->pages, false); + $cmd->addArg('--', null, false); + $cmd->addArg( $target, null, false); + return $this->execute(); + } + + /** + * Rotate pages in the object. + * + * @param string $target Path to output file + * @param string $direction String indicating rotation direction and amount. '+' for clockwise or '-' + * for counter-clockwise. Followed by '90', '180' or '270' for amount of + * rotation in degrees. Defaults to '+90' + * @param string|null $pageString String to indicate which pages to rotate. See ['Page Ranges'](https://qpdf.readthedocs.io/en/stable/cli.html#page-ranges) + * in the QPDF docs. Null value assumes to apply to all pages. Default is null. + * @return bool + * + * @throws \Exception + */ + public function rotate($target, $direction='+90', $pageString=null) + { + $rotationCmd = $direction; + if($pageString) { + $rotationCmd .= ':'.$pageString; + } + + if(count($this->pages) > 1) { + throw new \Exception("Error! Currently unable to rotate when more than one PDF file is specified."); + } + + $cmd = $this->getCommand(); + $cmd->addArg('--rotate=', $rotationCmd, false); + $cmd->addArg('', $this->pages, false); + $cmd->addArg('--', null, false); + $cmd->addArg( $target, null, false); + return $this->execute(); + } + + /** + * Get a count of all pages in the current object (across all added documents). + * + * @return int Number of pages + * + * @throws \Exception + */ + public function getPageCount() + { + $pageTotal = 0; + foreach($this->pages as $file) { + $cmd = $this->resetCommand(); + $cmd->addArg('--show-npages', null, false); + $cmd->addArg('', $file, false); + $res = $this->execute(); + if(!$res) { + throw new \Exception("Error getting page count. " . $this->getError()); + } else { + $pageTotal += intval($this->output); + } + } + return $pageTotal; + } + + } \ No newline at end of file diff --git a/tests/PdfTest.php b/tests/PdfTest.php index 25d4760..d000126 100644 --- a/tests/PdfTest.php +++ b/tests/PdfTest.php @@ -29,4 +29,40 @@ public function testMerge() $this->assertEmpty($pdf->getError()); } + public function testSplit() + { + $pdf = new Pdf(); + $pdf->addPage(__DIR__ . "/files/TestPdfTwoPage.pdf"); + $pdf->split(__DIR__."/output/test-split.pdf"); + $this->assertEmpty($pdf->getError()); + } + + public function testRotate() + { + $pdf = new Pdf(); + $pdf->addPage(__DIR__ . "/files/TestPdfTwoPage.pdf"); + $pdf->rotate(__DIR__ . "/output/rotated.pdf", "+90", "1"); + $this->assertEmpty($pdf->getError()); + } + + public function testGetPageCount() + { + $pdf = new Pdf(); + $pdf->addPage(__DIR__ . "/files/TestPdfTwoPage.pdf"); + $pdf->addPage(__DIR__ . "/files/TestPdf.pdf"); + $count = $pdf->getPageCount(); + $this->assertEmpty($pdf->getError()); + $this->assertEquals(3, $count); + } + + public function testEnsureErrorWithMultiFileRotate() + { + $pdf = new Pdf(); + $pdf->addPage(__DIR__ . "/files/TestPdfTwoPage.pdf"); + $pdf->addPage(__DIR__ . "/files/TestPdf.pdf"); + $this->expectExceptionMessage('Error! Currently unable to rotate when more than one PDF file is specified.'); + $pdf->rotate(__DIR__ . "/output/rotated.pdf", "+90", "1"); + + } + } \ No newline at end of file diff --git a/tests/files/TestPdfTwoPage.pdf b/tests/files/TestPdfTwoPage.pdf new file mode 100644 index 0000000..2cb4ce2 Binary files /dev/null and b/tests/files/TestPdfTwoPage.pdf differ