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]; } }