271 lines
9.3 KiB
PHP
271 lines
9.3 KiB
PHP
<?php
|
|
|
|
class EcomZoneProductSync
|
|
{
|
|
private $client;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->client = new EcomZoneClient();
|
|
}
|
|
|
|
private function resizeImage($src, $dest, $width, $height)
|
|
{
|
|
list($srcWidth, $srcHeight, $type) = getimagesize($src);
|
|
$srcImage = $this->createImageFromType($src, $type);
|
|
|
|
$destImage = imagecreatetruecolor($width, $height);
|
|
imagecopyresampled($destImage, $srcImage, 0, 0, 0, 0, $width, $height, $srcWidth, $srcHeight);
|
|
|
|
$this->saveImageFromType($destImage, $dest, $type);
|
|
|
|
imagedestroy($srcImage);
|
|
imagedestroy($destImage);
|
|
}
|
|
|
|
private function createImageFromType($filename, $type)
|
|
{
|
|
switch ($type) {
|
|
case IMAGETYPE_JPEG:
|
|
return imagecreatefromjpeg($filename);
|
|
case IMAGETYPE_PNG:
|
|
return imagecreatefrompng($filename);
|
|
case IMAGETYPE_GIF:
|
|
return imagecreatefromgif($filename);
|
|
default:
|
|
throw new Exception("Unsupported image type: " . $type);
|
|
}
|
|
}
|
|
|
|
private function saveImageFromType($image, $filename, $type)
|
|
{
|
|
switch ($type) {
|
|
case IMAGETYPE_JPEG:
|
|
$this->createDirectoryIfNotExists(dirname($filename));
|
|
imagejpeg($image, $filename);
|
|
break;
|
|
case IMAGETYPE_PNG:
|
|
$this->createDirectoryIfNotExists(dirname($filename));
|
|
imagepng($image, $filename);
|
|
break;
|
|
case IMAGETYPE_GIF:
|
|
$this->createDirectoryIfNotExists(dirname($filename));
|
|
imagegif($image, $filename);
|
|
break;
|
|
case IMAGETYPE_GIF:
|
|
imagegif($image, $filename);
|
|
break;
|
|
default:
|
|
throw new Exception("Unsupported image type: " . $type);
|
|
}
|
|
}
|
|
|
|
|
|
public function importProducts($perPage = 100)
|
|
{
|
|
$page = 1;
|
|
$totalImported = 0;
|
|
$totalAvailable = 0;
|
|
|
|
EcomZoneLogger::log("Starting product import - perPage: $perPage");
|
|
|
|
EcomZoneLogger::log("Number of products to be imported per page: $perPage", 'INFO');
|
|
|
|
try {
|
|
do {
|
|
$catalog = $this->client->getCatalog($page, $perPage);
|
|
$importedCount = 0;
|
|
foreach ($catalog['data'] as $product) {
|
|
if ($this->importSingleProduct($product)) {
|
|
$importedCount++;
|
|
}
|
|
}
|
|
|
|
$totalImported += $importedCount;
|
|
$totalAvailable = $catalog['total'];
|
|
$page++;
|
|
|
|
EcomZoneLogger::log("Imported page $page", 'INFO', [
|
|
'total_imported' => $totalImported,
|
|
'page' => $page,
|
|
'total_available' => $totalAvailable
|
|
]);
|
|
|
|
} while ($page <= ceil($totalAvailable / $perPage) && isset($catalog['next_page_url']) && $catalog['next_page_url'] !== null);
|
|
|
|
EcomZoneLogger::log("Finished importing products", 'INFO', [
|
|
'total_imported' => $totalImported,
|
|
'total_available' => $totalAvailable
|
|
]);
|
|
|
|
// Clear cache
|
|
Tools::clearSmartyCache();
|
|
Tools::clearXMLCache();
|
|
Media::clearCache();
|
|
PrestaShopAutoload::getInstance()->generateIndex();
|
|
|
|
return [
|
|
'success' => true,
|
|
'imported' => $totalImported,
|
|
'total' => $totalAvailable
|
|
];
|
|
|
|
} catch (Exception $e) {
|
|
EcomZoneLogger::log("Error importing products: " . $e->getMessage(), 'ERROR');
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
private function importSingleProduct($productData)
|
|
{
|
|
// Extract data from nested structure
|
|
$data = isset($productData['data']) ? $productData['data'] : $productData;
|
|
|
|
if (!isset($data['sku']) || !isset($data['product_name']) || !isset($data['description']) || !isset($data['product_price'])) {
|
|
EcomZoneLogger::log("Invalid product data", 'ERROR', ['data' => $productData]);
|
|
return false;
|
|
}
|
|
|
|
try {
|
|
// Check if product already exists by reference
|
|
$productId = Db::getInstance()->getValue('
|
|
SELECT id_product
|
|
FROM ' . _DB_PREFIX_ . 'product
|
|
WHERE reference = "' . pSQL($data['sku']) . '"
|
|
');
|
|
|
|
$product = $productId ? new Product($productId) : new Product();
|
|
|
|
$defaultLangId = (int)Configuration::get('PS_LANG_DEFAULT');
|
|
|
|
$product->reference = $data['sku'];
|
|
$product->name[$defaultLangId] = $data['product_name'];
|
|
$product->description[$defaultLangId] = $data['long_description'] ?? $data['description'];
|
|
$product->description_short[$defaultLangId] = $data['description'];
|
|
$product->price = $data['product_price'];
|
|
$product->active = true;
|
|
$product->quantity = (int)$data['stock'];
|
|
$homeCategoryId = (int)Configuration::get('PS_HOME_CATEGORY');
|
|
$product->id_category_default = $homeCategoryId;
|
|
$product->addToCategories([$homeCategoryId]);
|
|
$product->visibility = 'both'; // Ensure product is visible in both catalog and search
|
|
$product->active = true;
|
|
$product->quantity = (int)$data['stock'];
|
|
$homeCategoryId = (int)Configuration::get('PS_HOME_CATEGORY');
|
|
$product->id_category_default = $homeCategoryId;
|
|
$product->addToCategories([$homeCategoryId]);
|
|
|
|
// Save product first to get ID
|
|
if (!$product->id) {
|
|
$product->add();
|
|
} else {
|
|
$product->update();
|
|
}
|
|
StockAvailable::setQuantity($product->id, 0, (int)$data['stock']);
|
|
$product->available_for_order = true; // Ensure product is available for order
|
|
$product->show_price = true; // Ensure price is shown
|
|
|
|
// Handle image import if URL is provided
|
|
if (isset($data['image']) && !empty($data['image'])) {
|
|
$this->importProductImage($product, $data['image']);
|
|
}
|
|
|
|
StockAvailable::setQuantity($product->id, 0, (int)$data['stock']);
|
|
|
|
EcomZoneLogger::log("Imported product", 'INFO', [
|
|
'sku' => $data['sku'],
|
|
'id' => $product->id,
|
|
'name' => $data['product_name']
|
|
]);
|
|
|
|
return true;
|
|
|
|
} catch (Exception $e) {
|
|
EcomZoneLogger::log("Error importing product", 'ERROR', [
|
|
'sku' => $data['sku'],
|
|
'error' => $e->getMessage()
|
|
]);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private function importProductImage($product, $imageUrl)
|
|
{
|
|
try {
|
|
// Create temporary file
|
|
$tmpFile = tempnam(_PS_TMP_IMG_DIR_, 'ecomzone_');
|
|
|
|
// Download image
|
|
if (!copy($imageUrl, $tmpFile)) {
|
|
throw new Exception("Failed to download image from: " . $imageUrl);
|
|
}
|
|
|
|
// Get image info
|
|
$imageInfo = getimagesize($tmpFile);
|
|
if (!$imageInfo) {
|
|
unlink($tmpFile);
|
|
throw new Exception("Invalid image file");
|
|
}
|
|
|
|
// Validate image dimensions and file size
|
|
if ($imageInfo[0] > 2000 || $imageInfo[1] > 2000 || filesize($tmpFile) > 5000000) {
|
|
unlink($tmpFile);
|
|
throw new Exception("Image dimensions or file size exceed limits");
|
|
}
|
|
|
|
// Generate unique name
|
|
$imageName = $product->reference . '-' . time() . '.' . pathinfo($imageUrl, PATHINFO_EXTENSION);
|
|
|
|
// Delete existing images if any
|
|
$product->deleteImages();
|
|
|
|
// Add new image
|
|
$image = new Image();
|
|
$image->id_product = $product->id;
|
|
$image->position = 1;
|
|
$image->cover = true;
|
|
|
|
// Save the image to the correct directory
|
|
$imagePath = _PS_PROD_IMG_DIR_ . $image->getImgPath() . '.' . $image->image_format;
|
|
$this->createDirectoryIfNotExists(dirname($imagePath));
|
|
if (!copy($tmpFile, $imagePath)) {
|
|
unlink($tmpFile);
|
|
throw new Exception("Failed to save image to: " . $imagePath);
|
|
}
|
|
|
|
// Associate the image with the product
|
|
if (!$image->add()) {
|
|
unlink($tmpFile);
|
|
throw new Exception("Failed to add image to product");
|
|
}
|
|
|
|
// Manually resize the image and generate thumbnails
|
|
$this->resizeImage($imagePath, _PS_PROD_IMG_DIR_ . $image->getImgPath() . '-home_default.' . $image->image_format, 250, 250);
|
|
$this->resizeImage($imagePath, _PS_PROD_IMG_DIR_ . $image->getImgPath() . '-large_default.' . $image->image_format, 800, 800);
|
|
|
|
// Cleanup
|
|
unlink($tmpFile);
|
|
EcomZoneLogger::log("Imported product image", 'INFO', [
|
|
'sku' => $product->reference,
|
|
'image' => $imageUrl
|
|
]);
|
|
|
|
} catch (Exception $e) {
|
|
EcomZoneLogger::log("Error importing product image", 'ERROR', [
|
|
'sku' => $product->reference,
|
|
'image' => $imageUrl,
|
|
'error' => $e->getMessage()
|
|
]);
|
|
}
|
|
}
|
|
|
|
private function createDirectoryIfNotExists($directory)
|
|
{
|
|
if (!is_dir($directory)) {
|
|
mkdir($directory, 0755, true);
|
|
}
|
|
}
|
|
}
|