OpenXE/classes/Components/Pdf/Merger/FpdiPdfMerger.php
2021-05-21 08:49:41 +02:00

91 lines
2.8 KiB
PHP

<?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';
}
}