workingCopy/ecomzone/classes/EcomZoneCategoryHandler.php

216 lines
6.6 KiB
PHP

<?php
if (!defined("_PS_VERSION_")) {
exit();
}
class EcomZoneCategoryHandler implements ICategory
{
private int $defaultLangId;
private array $categoryCache = [];
private array $categoryLinkRewriteCache = [];
private int $defaultShopId;
public function __construct()
{
$this->defaultLangId = (int) Configuration::get("PS_LANG_DEFAULT");
$this->defaultShopId = (int) Context::getContext()->shop->id;
EcomZoneLogger::log("Category Handler initialized", "INFO", [
"default_lang" => $this->defaultLangId,
"shop_id" => $this->defaultShopId,
]);
}
public function createCategory(string $name, ?int $parentId = null): int
{
try {
if (isset($this->categoryCache[$name])) {
return $this->categoryCache[$name];
}
$parentId =
$parentId ?: (int) Configuration::get("PS_HOME_CATEGORY");
$category = new Category();
$category->name = [$this->defaultLangId => trim($name)];
$category->link_rewrite = [
$this->defaultLangId => $this->generateLinkRewrite($name),
];
$category->id_parent = $parentId;
$category->active = true;
$category->id_shop_default = $this->defaultShopId;
// Set shop association for multistore
if (Shop::isFeatureActive()) {
$category->id_shop_list = [$this->defaultShopId];
}
if (!$category->add()) {
throw new EcomZoneException(
"Failed to create category: $name",
EcomZoneException::CATEGORY_CREATE_ERROR
);
}
$this->categoryCache[$name] = (int) $category->id;
EcomZoneLogger::log("Category created", "INFO", [
"name" => $name,
"id" => $category->id,
"parent_id" => $parentId,
]);
return $this->categoryCache[$name];
} catch (Exception $e) {
EcomZoneLogger::log("Category creation failed", "ERROR", [
"name" => $name,
"error" => $e->getMessage(),
]);
throw new EcomZoneException(
"Category creation failed: " . $e->getMessage(),
EcomZoneException::CATEGORY_CREATE_ERROR,
$e
);
}
}
public function getCategoryIdByName(string $name, ?int $parentId = null): ?int
{
try {
if (isset($this->categoryCache[$name])) {
return $this->categoryCache[$name];
}
$name = trim($name);
$sql = 'SELECT c.id_category
FROM `' .
_DB_PREFIX_ .
'category_lang` cl
JOIN `' .
_DB_PREFIX_ .
'category` c ON c.id_category = cl.id_category
WHERE cl.name = "' .
pSQL($name) .
'"
AND cl.id_lang = ' .
(int) $this->defaultLangId .
'
AND c.active = 1';
if ($parentId !== null) {
$sql .= ' AND c.id_parent = ' . (int) $parentId;
}
$categoryId = (int) Db::getInstance()->getValue($sql);
if ($categoryId) {
$this->categoryCache[$name] = $categoryId;
return $categoryId;
}
return null;
} catch (Exception $e) {
EcomZoneLogger::log("Category lookup failed", "ERROR", [
"name" => $name,
"error" => $e->getMessage(),
]);
return null;
}
}
public function processCategoriesFromString(string $categories): array
{
$categoryNames = array_map('trim', explode('>', $categories));
$categoryIds = [];
$parentId = null;
foreach ($categoryNames as $name) {
$categoryId = $this->getCategoryIdByName($name, $parentId);
if (!$categoryId) {
$categoryId = $this->createCategory($name, $parentId);
}
if ($categoryId) {
$categoryIds[] = $categoryId;
$parentId = $categoryId;
}
}
return $categoryIds;
}
private function generateLinkRewrite(string $name): string
{
if (isset($this->categoryLinkRewriteCache[$name])) {
return $this->categoryLinkRewriteCache[$name];
}
$linkRewrite = Tools::str2url($name);
// Ensure uniqueness
$suffix = 1;
$originalLinkRewrite = $linkRewrite;
while ($this->linkRewriteExists($linkRewrite)) {
$linkRewrite = $originalLinkRewrite . "-" . $suffix++;
}
$this->categoryLinkRewriteCache[$name] = $linkRewrite;
return $linkRewrite;
}
private function linkRewriteExists(string $linkRewrite): bool
{
return (bool) Db::getInstance()->getValue(
'SELECT COUNT(*)
FROM `' .
_DB_PREFIX_ .
'category_lang` cl
JOIN `' .
_DB_PREFIX_ .
'category_shop` cs
ON cl.id_category = cs.id_category
WHERE cl.link_rewrite = "' .
pSQL($linkRewrite) .
'"
AND cl.id_lang = ' .
(int) $this->defaultLangId .
'
AND cs.id_shop = ' .
(int) $this->defaultShopId
);
}
public function createCategoryPath(array $categoryNames): int
{
$parentId = (int) Configuration::get("PS_HOME_CATEGORY");
$lastCategoryId = $parentId;
foreach ($categoryNames as $categoryName) {
$categoryName = trim($categoryName);
if (empty($categoryName)) {
continue;
}
try {
$categoryId = $this->getCategoryIdByName($categoryName);
if (!$categoryId) {
$categoryId = $this->createCategory(
$categoryName,
$parentId
);
}
$lastCategoryId = $categoryId;
$parentId = $categoryId;
} catch (Exception $e) {
EcomZoneLogger::log("Category path creation failed", "ERROR", [
"category" => $categoryName,
"error" => $e->getMessage(),
]);
break;
}
}
return $lastCategoryId;
}
}