Files
myep/src/BusProNet/XmlParser/DocumentsParser.php
T

75 lines
2.2 KiB
PHP

<?php
namespace App\BusProNet\XmlParser;
use App\BusProNet\Model\File;
use PhpZip\Exception\ZipException;
use PhpZip\ZipFile;
use Symfony\Component\DomCrawler\Crawler;
class DocumentsParser
{
public function parseConfirmation(Crawler $result): ?File
{
$pdfData = $this->decode($result->filterXPath('//bestaetigungpdf'));
return new File('bestaetigung.pdf', $pdfData, 'application/pdf');
}
public function parseDocuments(Crawler $result): ?File
{
$documents = $result->filterXPath('//reisedokumente/reisedokument');
if (1 === $documents->count()) {
$node = $documents->first();
[$filename, $pdfData] = $this->getFileInfo($node);
return new File($filename.'.pdf', $pdfData, 'application/pdf');
}
// In case of multiple documents create ZIP file
try {
$zip = new ZipFile();
$documents->each(function (Crawler $node) use (&$zip) {
[$filename, $pdfData] = $this->getFileInfo($node);
$zip->addFromString($filename.'.pdf', $pdfData);
});
return new File('reisedokumente.zip', $zip->outputAsString(), 'application/zip');
} catch (ZipException $e) {
return null;
}
}
private function decode(Crawler $node): string
{
if (0 === $node->count()) {
throw new \InvalidArgumentException('Missing PDF node in document response.');
}
$parts = explode(',', $node->text(), 2);
if (2 !== count($parts)) {
throw new \InvalidArgumentException('Invalid PDF payload in document response.');
}
[, $pdfData] = $parts;
return base64_decode($pdfData);
}
/** @return array{string, string} */
private function getFileInfo(Crawler $node): array
{
$pdfData = $this->decode($node->filterXPath('.//pdf'));
$filenameNode = $node->filterXPath('.//datei');
if (0 === $filenameNode->count()) {
throw new \InvalidArgumentException('Missing filename node in document response.');
}
$filename = $filenameNode->text();
return [$filename, $pdfData];
}
}