nice starting point
This commit is contained in:
parent
77f8d034aa
commit
b10a8b8867
BIN
modules/ecomzone-final-28012025.zip
Normal file
BIN
modules/ecomzone-final-28012025.zip
Normal file
Binary file not shown.
BIN
modules/ecomzone-vancho1.zip
Normal file
BIN
modules/ecomzone-vancho1.zip
Normal file
Binary file not shown.
BIN
modules/ecomzone-withsave.zip
Normal file
BIN
modules/ecomzone-withsave.zip
Normal file
Binary file not shown.
8
modules/ecomzone/cron.php
Normal file
8
modules/ecomzone/cron.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
include(dirname(__FILE__).'/../../config/config.inc.php');
|
||||
include(dirname(__FILE__).'/../../init.php');
|
||||
|
||||
$module = Module::getInstanceByName('ecomzone');
|
||||
if ($module) {
|
||||
$module->hookActionCronJob();
|
||||
}
|
||||
@ -39,14 +39,16 @@ class EcomZone extends Module
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->registerHook('actionProductUpdate')) {
|
||||
if (!$this->registerHook('actionProductUpdate') ||
|
||||
!$this->registerHook('actionCronJob')) {
|
||||
$this->errors[] = $this->l('Could not register hooks');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set default API key from your working configuration
|
||||
// Set default API configuration
|
||||
if (!Configuration::updateValue('ECOMZONE_API_KEY', 'klRyAdrXaxL0s6PEUp7LDlH6T8aPSCtBY8NiEHsHiWpc6646K2TZPi5KMxUg') ||
|
||||
!Configuration::updateValue('ECOMZONE_API_URL', 'https://dropship.ecomzone.eu/api')) {
|
||||
!Configuration::updateValue('ECOMZONE_API_URL', 'https://dropship.ecomzone.eu/api') ||
|
||||
!Configuration::updateValue('ECOMZONE_LAST_CRON', time())) {
|
||||
$this->errors[] = $this->l('Could not set default configuration');
|
||||
return false;
|
||||
}
|
||||
@ -60,13 +62,12 @@ class EcomZone extends Module
|
||||
$debugOutput = '';
|
||||
|
||||
if (Tools::isSubmit('submitEcomZone')) {
|
||||
$apiKey = trim(Tools::getValue('ECOMZONE_API_KEY'));
|
||||
$apiKey = Tools::getValue('ECOMZONE_API_KEY');
|
||||
|
||||
if (!$apiKey) {
|
||||
$output .= $this->displayError($this->l('API Key is required'));
|
||||
} else {
|
||||
Configuration::updateValue('ECOMZONE_API_KEY', $apiKey);
|
||||
$debugOutput .= "API Key saved: " . substr($apiKey, 0, 10) . "...\n";
|
||||
$output .= $this->displayConfirmation($this->l('Settings updated'));
|
||||
}
|
||||
}
|
||||
@ -74,40 +75,37 @@ class EcomZone extends Module
|
||||
// Handle manual fetch
|
||||
if (Tools::isSubmit('fetchProducts')) {
|
||||
try {
|
||||
$debugOutput .= "Starting product fetch...\n";
|
||||
$debugOutput .= "Starting manual product fetch...\n";
|
||||
$result = $this->cronRefreshProducts();
|
||||
|
||||
// Get all products
|
||||
$catalog = $this->api->getCatalog(1000);
|
||||
|
||||
if (isset($catalog['data']) && is_array($catalog['data'])) {
|
||||
$debugOutput .= sprintf("Fetching all products...\n");
|
||||
$totalProducts = count($catalog['data']);
|
||||
|
||||
// Show first 5 products as preview
|
||||
for ($i = 0; $i < min(5, $totalProducts); $i++) {
|
||||
$product = $catalog['data'][$i];
|
||||
$debugOutput .= sprintf(
|
||||
"Product %d/%d: %s - %s (Price: %s EUR, Stock: %s)\n",
|
||||
$i + 1,
|
||||
$totalProducts,
|
||||
$product['sku'],
|
||||
$product['product_name'],
|
||||
$product['product_price'],
|
||||
$product['stock']
|
||||
);
|
||||
if ($result['success']) {
|
||||
$catalog = $this->api->getCatalog(1000);
|
||||
if (isset($catalog['data']) && is_array($catalog['data'])) {
|
||||
$totalProducts = count($catalog['data']);
|
||||
$debugOutput .= sprintf("Found %d products\n\nPreview of first 5 products:\n", $totalProducts);
|
||||
|
||||
// Show first 5 products as preview
|
||||
for ($i = 0; $i < min(5, $totalProducts); $i++) {
|
||||
$product = $catalog['data'][$i];
|
||||
$debugOutput .= sprintf(
|
||||
"Product %d/%d: %s - %s (Price: %s EUR, Stock: %s)\n",
|
||||
$i + 1,
|
||||
$totalProducts,
|
||||
$product['sku'],
|
||||
$product['product_name'],
|
||||
$product['product_price'],
|
||||
$product['stock']
|
||||
);
|
||||
}
|
||||
|
||||
if ($totalProducts > 5) {
|
||||
$debugOutput .= "\n... and " . ($totalProducts - 5) . " more products\n";
|
||||
}
|
||||
|
||||
$debugOutput .= sprintf("\nTotal products updated: %d\n", $result['updated']);
|
||||
}
|
||||
|
||||
if ($totalProducts > 5) {
|
||||
$debugOutput .= "...\n"; // Indicate there are more products
|
||||
}
|
||||
|
||||
$debugOutput .= sprintf("\nTotal products fetched: %d\n", $totalProducts);
|
||||
} else {
|
||||
$debugOutput .= "No products found or invalid response format\n";
|
||||
$output .= $this->displayConfirmation($this->l('Products fetched successfully'));
|
||||
}
|
||||
|
||||
$output .= $this->displayConfirmation($this->l('Products fetched successfully'));
|
||||
|
||||
} catch (Exception $e) {
|
||||
$debugOutput .= "Error: " . $e->getMessage() . "\n";
|
||||
$output .= $this->displayError($this->l('Error fetching products'));
|
||||
@ -225,4 +223,223 @@ class EcomZone extends Module
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function cronRefreshProducts()
|
||||
{
|
||||
try {
|
||||
PrestaShopLogger::addLog(
|
||||
'EcomZone: Starting scheduled product refresh',
|
||||
1,
|
||||
null,
|
||||
'EcomZone'
|
||||
);
|
||||
|
||||
$catalog = $this->api->getCatalog(1000);
|
||||
|
||||
if (!isset($catalog['data']) || !is_array($catalog['data'])) {
|
||||
throw new Exception('Invalid catalog data received from API');
|
||||
}
|
||||
|
||||
$totalProducts = count($catalog['data']);
|
||||
$updatedCount = 0;
|
||||
$createdCount = 0;
|
||||
$defaultLangId = (int)Configuration::get('PS_LANG_DEFAULT');
|
||||
$defaultShopId = (int)Configuration::get('PS_SHOP_DEFAULT');
|
||||
|
||||
foreach ($catalog['data'] as $ecomZoneProduct) {
|
||||
$reference = $ecomZoneProduct['sku'];
|
||||
$productId = Product::getIdByReference($reference);
|
||||
|
||||
try {
|
||||
if (!$productId) {
|
||||
// Create new product
|
||||
$product = new Product();
|
||||
$product->reference = $reference;
|
||||
$product->name = [$defaultLangId => $ecomZoneProduct['product_name']];
|
||||
$product->description = [$defaultLangId => $ecomZoneProduct['long_description'] ?? ''];
|
||||
$product->description_short = [$defaultLangId => $ecomZoneProduct['description'] ?? ''];
|
||||
$product->price = (float)$ecomZoneProduct['product_price'];
|
||||
$product->active = true; // Make sure product is active
|
||||
$product->visibility = 'both'; // Show in catalog and search
|
||||
$product->available_for_order = true;
|
||||
$product->show_price = true;
|
||||
$product->id_shop_default = $defaultShopId;
|
||||
$product->id_category_default = 2; // Home category
|
||||
|
||||
// Add to all shops if multistore
|
||||
$product->id_shop_list = Shop::getShops(true, null, true);
|
||||
|
||||
if ($product->add()) {
|
||||
$productId = $product->id;
|
||||
|
||||
// Associate with Home category
|
||||
$product->addToCategories([2]);
|
||||
|
||||
// Set stock
|
||||
StockAvailable::setQuantity($productId, 0, (int)$ecomZoneProduct['stock']);
|
||||
|
||||
// Set stock settings
|
||||
StockAvailable::setProductOutOfStock($productId, 1); // Allow orders when out of stock
|
||||
|
||||
// Update shop association
|
||||
$product->updateCategories($product->id_shop_list);
|
||||
|
||||
// Add minimum quantity of 1
|
||||
$product->minimal_quantity = 1;
|
||||
$product->update();
|
||||
|
||||
$createdCount++;
|
||||
|
||||
// Download and set product image if available
|
||||
if (!empty($ecomZoneProduct['image'])) {
|
||||
$this->importProductImage($product, $ecomZoneProduct['image']);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Update existing product
|
||||
$product = new Product($productId);
|
||||
$product->name[$defaultLangId] = $ecomZoneProduct['product_name'];
|
||||
$product->description[$defaultLangId] = $ecomZoneProduct['long_description'] ?? '';
|
||||
$product->description_short[$defaultLangId] = $ecomZoneProduct['description'] ?? '';
|
||||
$product->price = (float)$ecomZoneProduct['product_price'];
|
||||
$product->active = true; // Make sure product is active
|
||||
$product->visibility = 'both';
|
||||
$product->available_for_order = true;
|
||||
$product->show_price = true;
|
||||
$product->update();
|
||||
|
||||
StockAvailable::setQuantity($productId, 0, (int)$ecomZoneProduct['stock']);
|
||||
$updatedCount++;
|
||||
}
|
||||
|
||||
// Clear cache for this product
|
||||
$this->clearProductCache($productId);
|
||||
|
||||
} catch (Exception $e) {
|
||||
PrestaShopLogger::addLog(
|
||||
sprintf('EcomZone: Error processing product %s: %s', $reference, $e->getMessage()),
|
||||
3,
|
||||
null,
|
||||
'Product'
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Clear cache after all products are processed
|
||||
$this->clearCache();
|
||||
|
||||
PrestaShopLogger::addLog(
|
||||
sprintf('EcomZone: Created %d new products, Updated %d existing products',
|
||||
$createdCount,
|
||||
$updatedCount
|
||||
),
|
||||
1,
|
||||
null,
|
||||
'EcomZone'
|
||||
);
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
'message' => sprintf('Created %d new products, Updated %d existing products', $createdCount, $updatedCount),
|
||||
'total' => $totalProducts,
|
||||
'created' => $createdCount,
|
||||
'updated' => $updatedCount
|
||||
];
|
||||
|
||||
} catch (Exception $e) {
|
||||
PrestaShopLogger::addLog(
|
||||
'EcomZone Error: ' . $e->getMessage(),
|
||||
3,
|
||||
null,
|
||||
'EcomZone'
|
||||
);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
private function importProductImage($product, $imageUrl)
|
||||
{
|
||||
try {
|
||||
$tempFile = tempnam(_PS_TMP_IMG_DIR_, 'import');
|
||||
if (@file_put_contents($tempFile, @file_get_contents($imageUrl))) {
|
||||
$product->deleteImages(); // Remove existing images
|
||||
$image = new Image();
|
||||
$image->id_product = $product->id;
|
||||
$image->position = 1;
|
||||
$image->cover = true;
|
||||
|
||||
if ($image->add()) {
|
||||
return (bool)@rename($tempFile, _PS_PROD_IMG_DIR_ . $image->getImgPath() . '.jpg');
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch (Exception $e) {
|
||||
PrestaShopLogger::addLog(
|
||||
sprintf('EcomZone: Error importing image for product %d: %s', $product->id, $e->getMessage()),
|
||||
3,
|
||||
null,
|
||||
'Product'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function hookActionCronJob()
|
||||
{
|
||||
$lastRun = (int)Configuration::get('ECOMZONE_LAST_CRON');
|
||||
$currentTime = time();
|
||||
|
||||
// Check if 2 hours have passed (7200 seconds)
|
||||
if (($currentTime - $lastRun) >= 7200) {
|
||||
$this->cronRefreshProducts();
|
||||
Configuration::updateValue('ECOMZONE_LAST_CRON', $currentTime);
|
||||
}
|
||||
}
|
||||
|
||||
public function uninstall()
|
||||
{
|
||||
return parent::uninstall() &&
|
||||
Configuration::deleteByName('ECOMZONE_API_KEY') &&
|
||||
Configuration::deleteByName('ECOMZONE_API_URL') &&
|
||||
Configuration::deleteByName('ECOMZONE_LAST_CRON');
|
||||
}
|
||||
|
||||
private function clearProductCache($productId)
|
||||
{
|
||||
try {
|
||||
Tools::clearSmartyCache();
|
||||
Tools::clearXMLCache();
|
||||
Media::clearCache();
|
||||
|
||||
$sql = 'DELETE FROM ' . _DB_PREFIX_ . 'smarty_cache
|
||||
WHERE template LIKE "%product%"';
|
||||
Db::getInstance()->execute($sql);
|
||||
|
||||
} catch (Exception $e) {
|
||||
PrestaShopLogger::addLog(
|
||||
sprintf('EcomZone: Error clearing cache for product %d: %s', $productId, $e->getMessage()),
|
||||
3,
|
||||
null,
|
||||
'Product'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function clearCache()
|
||||
{
|
||||
try {
|
||||
Tools::clearSmartyCache();
|
||||
Tools::clearXMLCache();
|
||||
Media::clearCache();
|
||||
Tools::generateIndex();
|
||||
} catch (Exception $e) {
|
||||
PrestaShopLogger::addLog(
|
||||
'EcomZone: Error clearing cache: ' . $e->getMessage(),
|
||||
3,
|
||||
null,
|
||||
'EcomZone'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user