Seite 1 von 1

Kleines Script um Optionen aus einer CSV -Datei anzulegen

Verfasst: 14 Jun 2026, 10:49
von juratextex
Script: Optionen in Gambio 5.0 per CSV anlegen

Beschreibung
Dieses Script ermöglicht es, Wert-Optionen (z. B. Größen, Farben, Ausführungen etc.) für bereits existierende Hauptoptionen in Gambio 5.0 effizient über eine CSV-Datei anzulegen.
Das Script ist besonders hilfreich für den Massenimport von Produktvarianten, ohne jede Option manuell im Admin-Bereich anlegen zu müssen.
Voraussetzungen

Die Hauptoption (Eigenschaft) muss bereits im Gambio-Admin unter Artikel → Optionen angelegt sein.
Der Eigenschaftsname in der CSV muss exakt mit dem Namen der bereits angelegten Hauptoption übereinstimmen (Groß-/Kleinschreibung beachten).

Ich hoffe das dieses kleine Script einigen helfen kann.


****************************************************************************************************

Code: Alles auswählen

<?php
// Fehlerberichterstattung aktivieren
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

// ================================================
// Gambio Admin-Schutz & Konfiguration laden
// ================================================

// Pfad zur Gambio-Konfiguration (anpassen, falls das Skript in einem tiefen Unterordner liegt)
$bootstrapPath = __DIR__ . '/includes/application_top.php';

if (!file_exists($bootstrapPath)) {
    die("Fehler: 'application_top.php' wurde nicht gefunden. Bitte platziere das Skript im Gambio-Hauptverzeichnis.");
}

// Gambio-Framework initialisieren
require_once $bootstrapPath;

// Prüfung, ob der Nutzer im Admin-Bereich eingeloggt ist
if (!isset($_SESSION['customer_id']) || (isset($_SESSION['account_type']) && $_SESSION['account_type'] !== '0')) {
    header('HTTP/1.1 403 Forbidden');
    die("<h1>Zugriff verweigert</h1><p>Sie müssen als Administrator im Shop angemeldet sein, um dieses Skript zu nutzen.</p>");
}

// ================================================
// Konfiguration aus Gambio übernehmen
// ================================================
global $db_link;
$link = $db_link;

if (!$link) {
    die("Verbindungsfehler: Keine aktive Datenbankverbindung über Gambio gefunden.");
}

$delimiter   = ';'; 
$debug       = true;          
$language_id = (int)($_SESSION['languages_id'] ?? 2);

echo "<h1>Gambio 5.0 Properties / Varianten Import 1.3</h1>";



if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['csv_file'])) {
    
    $fileError = $_FILES['csv_file']['error'];
    
    if ($fileError === UPLOAD_ERR_OK) {
        $tmpName = $_FILES['csv_file']['tmp_name'];
        $fileName = $_FILES['csv_file']['name'];
        
        $fileExtension = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
        if ($fileExtension !== 'csv' && $fileExtension !== 'txt') {
            die("<p style='color: red;'><strong>Fehler:</strong> Bitte nur CSV- oder TXT-Dateien hochladen.</p><p><a href=''>Zurück zum Upload</a></p>");
        }

        $properties = loadCsvToArray($tmpName, $delimiter);

        if (empty($properties)) {
            echo "<p style='color: orange;'>Die CSV-Datei enthielt keine gültigen Daten oder die Struktur war fehlerhaft.</p>";
        } else {
            $anz_neueProperty = 0;
            $anz_neueValue = 0;
            $anz_updateValue = 0;

            foreach ($properties as $propertyName => $values) {
                if (empty($propertyName)) continue;

                // Hauptoption (Eigenschaft) prüfen und ggf. neu anlegen
                if (!existProperty($propertyName)) {
                    $property_id = createProperty($propertyName);
                    if ($property_id > 0) {
                        $anz_neueProperty++;
                        echo "<p style='color: green;'><strong>Neue Hauptoption angelegt:</strong> $propertyName (ID: $property_id)</p>";
                    } else {
                        echo "<p style='color: red;'><strong>Fehler beim Anlegen der Hauptoption:</strong> $propertyName</p>";
                        continue;
                    }
                } else {
                    $property_id = getPropertyId($propertyName);
                    echo "<p><strong>Existierende Hauptoption gefunden:</strong> $propertyName (ID: $property_id)</p>";
                }

                if ($property_id == 0) continue;

                echo "<ul>";
                $sort_order = getMaxSortorderPropertyValue($property_id);

                foreach ($values as $valueData) {
                    $valueName  = $valueData['name'];
                    $valueModel = $valueData['model'];

                    // Wert prüfen
                    $existing_value_id = getPropertyValueId($property_id, $valueName);

                    if (!$existing_value_id) {
                        // Wert existiert nicht -> Neu anlegen
                        $sort_order += 10;
                        createPropertyValue($property_id, $valueName, $sort_order, $valueModel);
                        $anz_neueValue++;
                        echo "<li style='color: blue;'>Wert hinzugefügt: <strong>$valueName</strong> (Art-Nr: " . ($valueModel ? htmlspecialchars($valueModel) : '<i>keine</i>') . ")</li>";
                    } else {
                        // Wert existiert bereits -> Artikelnummer prüfen und updaten falls abweichend
                        if (updatePropertyValueModel($existing_value_id, $valueModel)) {
                            $anz_updateValue++;
                            echo "<li style='color: darkorange;'>Wert aktualisiert: <strong>$valueName</strong> -> Neue Art-Nr: " . htmlspecialchars($valueModel) . "</li>";
                        } else {
                            if ($debug) {
                                echo "<li style='color: #777;'>Wert unverändert: $valueName (Art-Nr stimmt überein)</li>";
                            }
                        }
                    }
                }
                echo "</ul>";
            }

            echo "<hr><strong>Fertig!</strong><br>";
            echo "Neue Hauptoptionen: $anz_neueProperty<br>";
            echo "Neue Werte angelegt: $anz_neueValue<br>";
            echo "Artikelnummern aktualisiert: $anz_updateValue<br>";
        }

        echo "<br><p><a href=''>Weitere Datei hochladen</a></p>";
        
    } else {
        echo "<p style='color: red;'><strong>Upload-Fehler:</strong> Code $fileError</p>";
        echo "<p><a href=''>Zurück zum Upload</a></p>";
    }

} else {
    ?>
    <div style="background: #f4f4f4; padding: 20px; border-radius: 5px; max-width: 500px; border: 1px solid #ccc;">
        <h3>CSV-Datei für den Import auswählen</h3>
        <p style="font-size: 0.9em; color: #555;">Format: <code>Eigenschaftsname;Wertname;Artikelnummer</code></p>
        <p style="font-size: 0.9em; color: #555;">Wichtig !!: <code>Hauptoption muss schon angelegt sein und mit dem Namen - Eigenschaftsname in der CSV-Datei übereinstimmen</code></p>
        
        <form action="" method="post" enctype="multipart/form-data">
            <p>
                <label for="csv_file">Datei (Trennzeichen: <strong><?php echo htmlspecialchars($delimiter); ?></strong>):</label><br><br>
                <input type="file" name="csv_file" id="csv_file" accept=".csv,.txt" required>
            </p>
            <p>
                <button type="submit" style="padding: 8px 15px; background: #007bff; color: #fff; border: 0; border-radius: 3px; cursor: pointer;">Import starten</button>
            </p>
        </form>
    </div>
    <?php
}

// ================== HILFSFUNKTIONEN ==================

function loadCsvToArray($file, $delimiter) {
    $data = [];
    if (($handle = fopen($file, "r")) !== FALSE) {
        fgetcsv($handle, 1000, $delimiter); 
        while (($row = fgetcsv($handle, 1000, $delimiter)) !== FALSE) {
            if (count($row) >= 2) {
                $prop  = trim($row[0]);
                $val   = trim($row[1]);
                $model = isset($row[2]) ? trim($row[2]) : '';
                
                if (empty($prop) || empty($val)) continue;

                if (!isset($data[$prop])) {
                    $data[$prop] = [];
                }
                
                $exists = false;
                foreach ($data[$prop] as $existingValue) {
                    if ($existingValue['name'] === $val) {
                        $exists = true;
                        break;
                    }
                }

                if (!$exists) {
                    $data[$prop][] = [
                        'name'  => $val,
                        'model' => $model
                    ];
                }
            }
        }
        fclose($handle);
    }
    return $data;
}

function existProperty($property) {
    global $link, $language_id;
    $prop = mysqli_real_escape_string($link, $property);
    $sql = "SELECT properties_id FROM properties_description 
            WHERE language_id = $language_id AND properties_name = '$prop' LIMIT 1";
    $result = mysqli_query($link, $sql);
    return $result && mysqli_num_rows($result) > 0;
}

function getPropertyId($property) {
    global $link, $language_id;
    $prop = mysqli_real_escape_string($link, $property);
    $sql = "SELECT properties_id FROM properties_description 
            WHERE language_id = $language_id AND properties_name = '$prop' LIMIT 1";
    $result = mysqli_query($link, $sql);
    if ($result && $row = mysqli_fetch_assoc($result)) {
        return $row['properties_id'];
    }
    return 0;
}

function createProperty($property) {
    global $link, $language_id;
    $prop = mysqli_real_escape_string($link, $property);
    
    // Holt die korrekte Sortiernummer dynamisch ab
    $next_sort = getMaxSortorderProperty(100);

    $sql = "INSERT INTO properties (sort_order, display_type) VALUES ($next_sort, 'dropdown')";
    if (mysqli_query($link, $sql)) {
        $property_id = mysqli_insert_id($link);
        
        // Beschreibung für aktuelle Sprache
        createPropertyDescription($property_id, $prop, $language_id);
        
        // Ausweichsprache (Gambio nutzt ID 1 oft als Englisch, ID 2 als Deutsch)
        if ($language_id == 2) { 
            createPropertyDescription($property_id, $prop, 1);
        }
        return $property_id;
    }
    return 0;
}

function createPropertyDescription($property_id, $name, $lang_id) {
    global $link;
    $name_esc = mysqli_real_escape_string($link, $name);
    
    // IGNORIEREN falls der Eintrag (Kombination aus ID und Sprach-ID) unerwartet schon existiert
    $sql = "INSERT IGNORE INTO properties_description (properties_id, language_id, properties_name, properties_admin_name) 
            VALUES ($property_id, $lang_id, '$name_esc', '$name_esc')";
    mysqli_query($link, $sql);
}

function getPropertyValueId($property_id, $value) {
    global $link, $language_id;
    $val = mysqli_real_escape_string($link, $value);
    $sql = "SELECT pv.properties_values_id 
            FROM properties_values pv 
            JOIN properties_values_description pvd ON pv.properties_values_id = pvd.properties_values_id 
            WHERE pv.properties_id = $property_id 
              AND pvd.language_id = $language_id 
              AND pvd.values_name = '$val' LIMIT 1";
    $result = mysqli_query($link, $sql);
    if ($result && $row = mysqli_fetch_assoc($result)) {
        return (int)$row['properties_values_id'];
    }
    return 0;
}

function createPropertyValue($property_id, $value, $sort_order, $value_model) {
    global $link, $language_id;
    $val = mysqli_real_escape_string($link, $value);
    $model_esc = mysqli_real_escape_string($link, $value_model);

    $sql = "INSERT INTO properties_values (properties_id, sort_order, value_model, value_price, display_image) 
            VALUES ($property_id, $sort_order, '$model_esc', 0.0000, '')";
    mysqli_query($link, $sql);
    $value_id = mysqli_insert_id($link);

    createPropertyValueDescription($value_id, $val, $language_id);
    if ($language_id == 2) {
        createPropertyValueDescription($value_id, $val, 1);
    }
}

function updatePropertyValueModel($value_id, $value_model) {
    global $link;
    $value_id = (int)$value_id;
    $model_esc = mysqli_real_escape_string($link, $value_model);

    $checkSql = "SELECT value_model FROM properties_values WHERE properties_values_id = $value_id LIMIT 1";
    $res = mysqli_query($link, $checkSql);
    if ($res && $row = mysqli_fetch_assoc($res)) {
        if ($row['value_model'] === $value_model) {
            return false; 
        }
    }

    $sql = "UPDATE properties_values SET value_model = '$model_esc' WHERE properties_values_id = $value_id";
    return mysqli_query($link, $sql);
}

function createPropertyValueDescription($value_id, $name, $lang_id) {
    global $link;
    $name_esc = mysqli_real_escape_string($link, $name);
    $sql = "INSERT IGNORE INTO properties_values_description (properties_values_id, language_id, values_name) 
            VALUES ($value_id, $lang_id, '$name_esc')";
    mysqli_query($link, $sql);
}

function getMaxSortorderProperty($start) {
    global $link; 
    $sql = "SELECT MAX(sort_order) as max_sort FROM properties";
    $result = mysqli_query($link, $sql);
    if ($result && $row = mysqli_fetch_assoc($result)) {
        return max((int)$row['max_sort'] + 10, $start);
    }
    return $start;
}

function getMaxSortorderPropertyValue($property_id) {
    global $link; 
    $sql = "SELECT MAX(sort_order) as max_sort FROM properties_values WHERE properties_id = $property_id";
    $result = mysqli_query($link, $sql);
    if ($result && $row = mysqli_fetch_assoc($result)) {
        return (int)$row['max_sort'] ?: 0;
    }
    return 0;
}
?>
-----------------
Edit ddehning 14.06.26: Codeformatierung eingefügt für bessere Lesbarkeit