query("SHOW COLUMNS FROM games"); $gameCols = []; while ($c = $colStmt->fetch(PDO::FETCH_ASSOC)) { $name = (string)$c['Field']; if ($name === 'id' || $name === 'category_id') { continue; } $gameCols[] = $name; } // Discover categories table columns $catStmt = $pdo->query("SHOW COLUMNS FROM categories"); $catCols = []; while ($c = $catStmt->fetch(PDO::FETCH_ASSOC)) { $catCols[] = (string)$c['Field']; } $hasCatSlug = in_array('slug', $catCols, true); $inserted = 0; $skipped = 0; $failed = 0; $errors = []; $categoryCache = []; foreach ($data['games'] as $idx => $g) { if (!is_array($g)) { $failed++; continue; } $fields = (isset($g['fields']) && is_array($g['fields'])) ? $g['fields'] : []; $categoryName = trim((string)($g['category_name'] ?? '')); // Duplicate detection: $slug = isset($fields['slug']) ? (string)$fields['slug'] : ''; $externalId = isset($fields['external_id']) ? (string)$fields['external_id'] : ''; $provider = isset($fields['provider']) ? (string)$fields['provider'] : ''; $dupId = null; if ($externalId !== '' && $provider !== '') { $st = $pdo->prepare("SELECT id FROM games WHERE external_id = :eid AND provider = :prov LIMIT 1"); $st->execute([':eid'=>$externalId, ':prov'=>$provider]); $dupId = $st->fetchColumn() ?: null; } if (!$dupId && $slug !== '') { $st = $pdo->prepare("SELECT id FROM games WHERE slug = :slug LIMIT 1"); $st->execute([':slug'=>$slug]); $dupId = $st->fetchColumn() ?: null; } if ($dupId) { $skipped++; continue; } // Resolve / create category by name $categoryId = null; if ($categoryName !== '') { if (isset($categoryCache[$categoryName])) { $categoryId = $categoryCache[$categoryName]; } else { $st = $pdo->prepare("SELECT id FROM categories WHERE name = :n LIMIT 1"); $st->execute([':n'=>$categoryName]); $categoryId = $st->fetchColumn(); if (!$categoryId) { if ($hasCatSlug) { // generate unique slug from name $base = strtolower(trim(preg_replace('/[^a-z0-9]+/i', '-', $categoryName), '-')); if ($base === '') { $base = 'category'; } $slugCandidate = $base; $suffix = 2; while (true) { $st2 = $pdo->prepare("SELECT id FROM categories WHERE slug = :s LIMIT 1"); $st2->execute([':s'=>$slugCandidate]); if (!$st2->fetchColumn()) { break; } $slugCandidate = $base.'-'.$suffix; $suffix++; } $ins = $pdo->prepare("INSERT INTO categories (name, slug) VALUES (:n, :s)"); $ins->execute([':n'=>$categoryName, ':s'=>$slugCandidate]); } else { $ins = $pdo->prepare("INSERT INTO categories (name) VALUES (:n)"); $ins->execute([':n'=>$categoryName]); } $categoryId = (int)$pdo->lastInsertId(); } $categoryCache[$categoryName] = (int)$categoryId; } } if (!$fields) { $failed++; continue; } // Build insert columns intersection $insertCols = []; $params = []; foreach ($gameCols as $col) { if (array_key_exists($col, $fields)) { $insertCols[] = $col; $params[':'.$col] = $fields[$col]; } } if ($categoryId) { $insertCols[] = 'category_id'; $params[':category_id'] = $categoryId; } if (!$insertCols) { $failed++; continue; } $colSql = implode(',', $insertCols); $paramSql = implode(',', array_keys($params)); $sql = "INSERT INTO games ($colSql) VALUES ($paramSql)"; try { $st = $pdo->prepare($sql); $st->execute($params); $inserted++; } catch (Throwable $e) { $failed++; if ($failed <= 5) { $errors[] = 'Game #'.($idx + 1).': '.$e->getMessage(); } } } $summary = [ 'inserted' => $inserted, 'skipped' => $skipped, 'failed' => $failed, 'errors' => $errors, ]; if ($inserted > 0) { $msg = "Imported {$inserted} external game(s). Skipped {$skipped}, failed {$failed}."; } else { $err = "Nothing imported. Skipped {$skipped}, failed {$failed}."; } } catch (Throwable $e) { $err = 'Import failed: '.$e->getMessage(); } } } } } require __DIR__ . '/../inc/header.php'; ?>

External Games Import

Import summary

  • Inserted:
  • Skipped (duplicates):
  • Failed:

Sample errors:

Upload external export JSON

Export games from another installation using the “Export as JSON” bulk action in its admin panel, then upload the JSON file here to import.

The file should be generated by the games export feature.