From b10a8b8867edf557e957079bb0f6632f2f67747a Mon Sep 17 00:00:00 2001 From: dimitar Date: Tue, 28 Jan 2025 01:43:56 +0100 Subject: [PATCH] nice starting point --- modules/ecomzone-final-28012025.zip | Bin 0 -> 8656 bytes modules/ecomzone-vancho1.zip | Bin 0 -> 7682 bytes modules/ecomzone-withsave.zip | Bin 0 -> 8193 bytes modules/ecomzone/cron.php | 8 + modules/ecomzone/ecomzone.php | 289 ++++++++++++++++++++++++---- 5 files changed, 261 insertions(+), 36 deletions(-) create mode 100644 modules/ecomzone-final-28012025.zip create mode 100644 modules/ecomzone-vancho1.zip create mode 100644 modules/ecomzone-withsave.zip create mode 100644 modules/ecomzone/cron.php diff --git a/modules/ecomzone-final-28012025.zip b/modules/ecomzone-final-28012025.zip new file mode 100644 index 0000000000000000000000000000000000000000..b3831260f567537503b22619fe24d74aebafd5c5 GIT binary patch literal 8656 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 literal 0 HcmV?d00001 diff --git a/modules/ecomzone-vancho1.zip b/modules/ecomzone-vancho1.zip new file mode 100644 index 0000000000000000000000000000000000000000..4594a1782ef0b281c029683a08b92181decf1be6 GIT binary patch literal 7682 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 E3(&_CMgRZ+ literal 0 HcmV?d00001 diff --git a/modules/ecomzone-withsave.zip b/modules/ecomzone-withsave.zip new file mode 100644 index 0000000000000000000000000000000000000000..f4935079b159c6d7267cc99565036a7a422f93ca GIT binary patch literal 8193 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 literal 0 HcmV?d00001 diff --git a/modules/ecomzone/cron.php b/modules/ecomzone/cron.php new file mode 100644 index 0000000..2b0ec32 --- /dev/null +++ b/modules/ecomzone/cron.php @@ -0,0 +1,8 @@ +hookActionCronJob(); +} \ No newline at end of file diff --git a/modules/ecomzone/ecomzone.php b/modules/ecomzone/ecomzone.php index b9f775f..d5cdfed 100644 --- a/modules/ecomzone/ecomzone.php +++ b/modules/ecomzone/ecomzone.php @@ -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' + ); + } + } } \ No newline at end of file