Skip to content

Instantly share code, notes, and snippets.

@hounw
Created April 24, 2025 00:46
Show Gist options
  • Save hounw/863f5278148b5315785e750664b426c7 to your computer and use it in GitHub Desktop.
Save hounw/863f5278148b5315785e750664b426c7 to your computer and use it in GitHub Desktop.
Create a shopify import CSV from your Opencart 2.3.x catalog using a simple php script.
<?php
// Place in your opencart 2.3.x root directory to create a CSV file to import in a shopify store. Only simple products exported.
// Include OpenCart config to get DB + URL constants
require_once('config.php');
try {
$pdo = new PDO(
"mysql:host=" . DB_HOSTNAME . ";dbname=" . DB_DATABASE . ";charset=utf8",
DB_USERNAME,
DB_PASSWORD,
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
} catch (PDOException $e) {
die("Database connection failed: " . $e->getMessage());
}
// Determine base URL for images
if (defined('HTTP_IMAGE')) {
$imageBase = HTTP_IMAGE;
} elseif (defined('HTTPS_IMAGE')) {
$imageBase = HTTPS_IMAGE;
} else {
// fallback to server URL + image folder
$imageBase = rtrim(HTTP_SERVER, '/') . '/image/';
}
// Open the CSV for writing
$csvFile = __DIR__ . '/products.csv';
if (!$fp = fopen($csvFile, 'w')) {
die("Cannot open file ($csvFile) for writing");
}
// Shopify‐style header
fputcsv($fp, [
'Handle',
'Title',
'Body (HTML)',
'Tags',
'Variant Price',
'Variant Inventory Qty',
'Image Src'
]);
// Fetch all products (language_id = 2)
$sql = "
SELECT
p.product_id,
p.image AS main_image,
p.price,
p.quantity,
pd.name,
pd.description
FROM " . DB_PREFIX . "product AS p
JOIN " . DB_PREFIX . "product_description AS pd
ON p.product_id = pd.product_id
AND pd.language_id = 2
";
$stmt = $pdo->query($sql, PDO::FETCH_ASSOC);
while ($product = $stmt->fetch()) {
$pid = $product['product_id'];
// 1) Get SEO URL (handle)
$aliasStmt = $pdo->prepare("
SELECT keyword
FROM " . DB_PREFIX . "url_alias
WHERE query = :query
LIMIT 1
");
$aliasStmt->execute([':query' => "product_id={$pid}"]);
$handle = $aliasStmt->fetchColumn() ?: $pid;
// 2) Get category names as tags
$catStmt = $pdo->prepare("
SELECT cd.name
FROM " . DB_PREFIX . "product_to_category AS pc
JOIN " . DB_PREFIX . "category_description AS cd
ON pc.category_id = cd.category_id
AND cd.language_id = 2
WHERE pc.product_id = :pid
");
$catStmt->execute([':pid' => $pid]);
$tags = implode(',', $catStmt->fetchAll(PDO::FETCH_COLUMN));
// 3) Gather images: main + additional
$images = [];
if ($product['main_image']) {
$images[] = $product['main_image'];
}
$imgStmt = $pdo->prepare("
SELECT image
FROM " . DB_PREFIX . "product_image
WHERE product_id = :pid
ORDER BY sort_order ASC
");
$imgStmt->execute([':pid' => $pid]);
foreach ($imgStmt->fetchAll(PDO::FETCH_COLUMN) as $img) {
$images[] = $img;
}
// 4) Write first row: all fields + first image URL
$firstImagePath = $images[0] ?? '';
$firstImageUrl = $firstImagePath
? $imageBase . ltrim($firstImagePath, '/')
: '';
fputcsv($fp, [
$handle,
$product['name'],
html_entity_decode($product['description'], ENT_QUOTES | ENT_HTML5, 'UTF-8'),
$tags,
$product['price'],
$product['quantity'],
$firstImageUrl
]);
// 5) Additional rows for extra images
for ($i = 1; $i < count($images); $i++) {
$imgUrl = $imageBase . ltrim($images[$i], '/');
fputcsv($fp, [
$handle, // same handle
'', // Title blank
'', // Body blank
'', // Tags blank
'', // Price blank
'', // Inventory blank
$imgUrl
]);
}
}
fclose($fp);
echo "✅ CSV file created at: {$csvFile}\n";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment