Replace file-path-based zip entries with in-memory content via file_get_contents. Rename .pro entry to 'data' (raw protobuf), add addStoredEntry() helper with CM_STORE compression, and remove temp directory management.
102 lines
3.1 KiB
PHP
102 lines
3.1 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Service;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use InvalidArgumentException;
|
|
use ProPresenter\Parser\ProFileGenerator;
|
|
use RuntimeException;
|
|
use ZipArchive;
|
|
|
|
class ProBundleExportService
|
|
{
|
|
private const ALLOWED_BLOCK_TYPES = ['information', 'moderation', 'sermon'];
|
|
|
|
public function generateBundle(Service $service, string $blockType): string
|
|
{
|
|
if (! in_array($blockType, self::ALLOWED_BLOCK_TYPES, true)) {
|
|
throw new InvalidArgumentException('Ungültiger Blocktyp für .probundle Export.');
|
|
}
|
|
|
|
$slides = $service->slides()
|
|
->where('type', $blockType)
|
|
->orderBy('sort_order')
|
|
->get();
|
|
|
|
$groupName = ucfirst($blockType);
|
|
$slideData = [];
|
|
$mediaFiles = [];
|
|
|
|
foreach ($slides as $slide) {
|
|
$sourcePath = Storage::disk('public')->path('slides/'.$slide->stored_filename);
|
|
if (! file_exists($sourcePath)) {
|
|
continue;
|
|
}
|
|
|
|
$imageFilename = basename($slide->stored_filename);
|
|
$imageContent = file_get_contents($sourcePath);
|
|
if ($imageContent === false) {
|
|
continue;
|
|
}
|
|
|
|
$mediaFiles[$imageFilename] = $imageContent;
|
|
|
|
$slideData[] = [
|
|
'text' => $slide->original_filename ?? '',
|
|
'media' => $imageFilename,
|
|
'format' => 'JPG',
|
|
];
|
|
}
|
|
|
|
$groups = [
|
|
[
|
|
'name' => $groupName,
|
|
'color' => [0, 0, 0, 1],
|
|
'slides' => $slideData,
|
|
],
|
|
];
|
|
|
|
$arrangements = [
|
|
[
|
|
'name' => 'normal',
|
|
'groupNames' => [$groupName],
|
|
],
|
|
];
|
|
|
|
$song = ProFileGenerator::generate($groupName, $groups, $arrangements);
|
|
$protoBytes = $song->getPresentation()->serializeToString();
|
|
|
|
$bundlePath = sys_get_temp_dir().'/'.uniqid($blockType.'-').'.probundle';
|
|
|
|
$zip = new ZipArchive();
|
|
$openResult = $zip->open($bundlePath, ZipArchive::CREATE | ZipArchive::OVERWRITE);
|
|
if ($openResult !== true) {
|
|
throw new InvalidArgumentException('Konnte .probundle nicht erstellen.');
|
|
}
|
|
|
|
$this->addStoredEntry($zip, 'data', $protoBytes);
|
|
|
|
foreach ($mediaFiles as $filename => $contents) {
|
|
$this->addStoredEntry($zip, $filename, $contents);
|
|
}
|
|
|
|
if (! $zip->close()) {
|
|
throw new RuntimeException('Fehler beim Finalisieren der .probundle Datei.');
|
|
}
|
|
|
|
return $bundlePath;
|
|
}
|
|
|
|
private function addStoredEntry(ZipArchive $zip, string $entryName, string $contents): void
|
|
{
|
|
if (! $zip->addFromString($entryName, $contents)) {
|
|
throw new RuntimeException(sprintf('Fehler beim Hinzufügen von %s zur .probundle Datei.', $entryName));
|
|
}
|
|
|
|
if (! $zip->setCompressionName($entryName, ZipArchive::CM_STORE)) {
|
|
throw new RuntimeException(sprintf('Fehler beim Setzen der Kompression für %s.', $entryName));
|
|
}
|
|
}
|
|
}
|