Bilder von URL in Medienpool importieren

Quell-ID: GitHub Discussion #7

Use Case

Bilder sollen automatisch von externen URLs heruntergeladen und in den REDAXO-Medienpool importiert werden.

Verwendete AddOns

  • REDAXO Core (rex_socket, rex_mediapool, rex_media_service)

Zielbeschreibung

Mehrere Bilder aus einem Array mit Titeln und URLs sollen in den Medienpool übernommen werden, ohne bereits vorhandene Dateien zu duplizieren.

Lösung

<?php
$images = [
    'Title 1' => 'https://images.pexels.com/photos/7488465/pexels-photo-7488465.jpeg',
    'Title 2' => 'https://images.pexels.com/photos/6441504/pexels-photo-6441504.jpeg'
];

foreach ($images as $title => $url) {
    // Dateiname aus der URL holen
    $baseName = basename($url);

    // Medienpool-Name erstellen
    $fileName = rex_mediapool::filename($baseName, false);

    // Prüfen, ob die Datei noch nicht existiert
    if (rex_media::get($fileName) === null) {
        $mediaPath = rex_path::media($fileName);

        // Bild von URL laden
        $response = rex_socket::factoryUrl($url)->doGet();

        // Prüfen ob Download erfolgreich war
        if (!$response->isOk()) {
            continue; // Überspringe bei Fehler
        }

        // Bild in den media-Ordner schreiben
        $response->writeBodyTo($mediaPath);

        // Medienpool-Daten vorbereiten
        $mediaData = [
            'category_id' => null, // Optional: Kategorie-ID
            'title' => $title,
            'filename' => $fileName,
            'file' => [
                'name' => $fileName,
                'path' => $mediaPath,
            ],
        ];

        // Bild dem Medienpool hinzufügen
        rex_media_service::addMedia($mediaData, false);
    }
}

Alternative mit continue

<?php
foreach ($images as $title => $url) {
    $baseName = basename($url);
    $fileName = rex_mediapool::filename($baseName, false);

    // Überspringen, wenn Datei schon existiert
    if (rex_media::get($fileName) !== null) {
        continue;
    }

    $mediaPath = rex_path::media($fileName);
    $image = rex_socket::factoryUrl($url)->doGet();
    $image->writeBodyTo($mediaPath);

    $mediaData = [
        'category_id' => null,
        'title' => $title,
        'filename' => $fileName,
        'file' => [
            'name' => $fileName,
            'path' => $mediaPath,
        ],
    ];

    rex_media_service::addMedia($mediaData, false);
}

Besserer Ansatz mit Fehlerbehandlung

<?php
class MediaImporter
{
    public static function importFromUrl(string $url, string $title, ?int $categoryId = null): ?string
    {
        try {
            $baseName = basename(parse_url($url, PHP_URL_PATH));
            $fileName = rex_mediapool::filename($baseName, false);

            // Bereits vorhanden?
            if (rex_media::get($fileName) !== null) {
                return $fileName;
            }

            $mediaPath = rex_path::media($fileName);
            
            // Bild laden mit Timeout
            $socket = rex_socket::factoryUrl($url);
            $socket->setTimeout(30);
            $response = $socket->doGet();

            if ($response->isOk()) {
                $response->writeBodyTo($mediaPath);

                $mediaData = [
                    'category_id' => $categoryId,
                    'title' => $title,
                    'filename' => $fileName,
                    'file' => [
                        'name' => $fileName,
                        'path' => $mediaPath,
                    ],
                ];

                $result = rex_media_service::addMedia($mediaData, false);
                
                if ($result['ok']) {
                    return $fileName;
                }
            }
        } catch (Exception $e) {
            rex_logger::factory()->log('error', 'Media import failed: ' . $e->getMessage());
        }

        return null;
    }
}

// Verwendung
foreach ($images as $title => $url) {
    $importedFile = MediaImporter::importFromUrl($url, $title);
    if ($importedFile) {
        echo "Importiert: $importedFile\n";
    }
}

Diese Variante bietet Fehlerbehandlung, Logging und ist wiederverwendbar.