<?php namespace Xentral\Components\Pdf\Merger; use fpdi; use Xentral\Components\Pdf\Exception\FileExistsException; use Xentral\Components\Pdf\Exception\FileNotFoundException; use Xentral\Components\Pdf\Exception\FileNotWritableException; use Xentral\Components\Pdf\Exception\InvalidArgumentException; use Xentral\Components\Pdf\Exception\PdfIncompatibleException; /** * Anti-Corruption-Layer für alte FPDI-Klasse */ final class FpdiPdfMerger extends AbstractPdfMerger { /** * @param string[] $sourceFiles Array with files pathes * @param string $targetFile Path to merged file * * @throws InvalidArgumentException If required parameter is invalid/empty * @throws FileNotWritableException If target file is not writable * @throws FileExistsException If target file already exists * @throws FileNotFoundException If one of the source files does not exist * @throws PdfIncompatibleException If XRef-Pointer is missing * * @return void */ public function mergeFiles(array $sourceFiles, $targetFile) { $this->preCheckMergeFiles($sourceFiles, $targetFile); $fpdi = new fpdi('P', 'mm', 'A4'); foreach ($sourceFiles as $file) { if (!$this->hasPdfXrefError($file)) { throw new PdfIncompatibleException(sprintf( 'Can not merge PDFs. Unable to find pointer to xref table in file "%s".', $file )); } $pageCount = $fpdi->setSourceFile($file); for ($pageNumber = 1; $pageNumber <= $pageCount; $pageNumber++) { $templateId = $fpdi->importPage($pageNumber); $size = $fpdi->getTemplateSize($templateId); // Create empty page if ($size['w'] > $size['h']) { // Landscape orientation $fpdi->addPage('L', [$size['h'], $size['w']]); } else { // Portrait orientation $fpdi->addPage('P', [$size['w'], $size['h']]); } // Import page $fpdi->useTemplate($templateId); } } $fpdi->Output($targetFile, 'F'); } /** * Helper method to detect xref-Error * * @see \fpdi_pdf_parser::pdf_find_xref * * @param string $pdfFile Path to pdf file * * @return bool */ public function hasPdfXrefError($pdfFile) { $resource = @fopen($pdfFile, 'rb'); fseek($resource, -50, SEEK_END); $data = fread($resource, 50); $foundXrefOffset = preg_match('/startxref\s*(\d+)\s*%%EOF\s*$/', $data, $matches); if (!$foundXrefOffset) { return false; } $xrefOffset = (int)$matches[1]; fseek($resource, $xrefOffset); $data = trim(fgets($resource)); return $data === 'xref'; } }