epcqr/prototyp/createodt.php

89 lines
2.8 KiB
PHP

<?php
$templateOdt = 'test.odt';
$imageFile = 'qr.png';
$outputOdt = 'output.odt';
$tmpDir = sys_get_temp_dir() . '/odt_' . uniqid();
mkdir($tmpDir);
// 1. ODT entpacken
$zip = new ZipArchive();
if ($zip->open($templateOdt) !== TRUE) {
die("Fehler beim Öffnen von $templateOdt\n");
}
$zip->extractTo($tmpDir);
$zip->close();
// 2. Bild nach Pictures kopieren
if (!is_dir("$tmpDir/Pictures")) {
mkdir("$tmpDir/Pictures");
}
copy($imageFile, "$tmpDir/Pictures/qrcode.png");
// 3. manifest.xml aktualisieren (WICHTIG!)
$manifestFile = "$tmpDir/META-INF/manifest.xml";
$manifest = file_get_contents($manifestFile);
// Prüfen ob Eintrag schon existiert
if (strpos($manifest, 'Pictures/qrcode.png') === false) {
$newEntry = '<manifest:file-entry manifest:media-type="image/png" manifest:full-path="Pictures/qrcode.png"/>';
$manifest = str_replace('</manifest:manifest>', $newEntry . "\n</manifest:manifest>", $manifest);
file_put_contents($manifestFile, $manifest);
}
// 4. content.xml laden
$contentFile = "$tmpDir/content.xml";
$content = file_get_contents($contentFile);
// 5. Bild-XML (ODF-konform)
$imageXml = '<draw:frame draw:name="QRCode" text:anchor-type="as-char" svg:width="2cm" svg:height="2cm" fo:border="0.05cm solid #000000" fo:padding="0.1cm">' .
'<draw:image xlink:href="Pictures/qrcode.png" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>' .
'</draw:frame>';
// {qrcode} ersetzen
$content = str_replace('{qrcode}', $imageXml, $content);
file_put_contents($contentFile, $content);
// 6. Neue ODT bauen
$zip = new ZipArchive();
if ($zip->open($outputOdt, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== TRUE) {
die("Fehler beim Erstellen von $outputOdt\n");
}
// 6a. mimetype MUSS zuerst & unkomprimiert
$zip->addFile("$tmpDir/mimetype", "mimetype");
$zip->setCompressionName("mimetype", ZipArchive::CM_STORE);
// 6b. Restliche Dateien rekursiv hinzufügen
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($tmpDir, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($files as $file) {
if (!$file->isFile()) continue;
$filePath = $file->getRealPath();
$relativePath = substr($filePath, strlen($tmpDir) + 1);
// mimetype überspringen (schon hinzugefügt)
if ($relativePath === 'mimetype') continue;
// Backslashes zu Forward-Slashes (für Windows-Kompatibilität)
$relativePath = str_replace('\\', '/', $relativePath);
$zip->addFile($filePath, $relativePath);
}
$zip->close();
// 7. Cleanup
function deleteDir($dir) {
if (!is_dir($dir)) return;
foreach (scandir($dir) as $item) {
if ($item == '.' || $item == '..') continue;
$path = "$dir/$item";
is_dir($path) ? deleteDir($path) : unlink($path);
}
rmdir($dir);
}
deleteDir($tmpDir);
echo "Fertig: $outputOdt\n";