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 $stream = fopen('php://temp', 'w+b'); try { // Zero headers trip up some unzip clients, and the data is in memory anyway $zip = new ZipStream( outputStream: $stream, defaultEnableZeroHeader: false, sendHttpHeaders: false, ); $documents->each(function (Crawler $node) use ($zip) { [$filename, $pdfData] = $this->getFileInfo($node); $zip->addFile($filename.'.pdf', $pdfData); }); $zip->finish(); rewind($stream); return new File('reisedokumente.zip', stream_get_contents($stream), 'application/zip'); } catch (ZipException $e) { return null; } finally { fclose($stream); } } 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]; } }