language->id; $idShop = (int) Context::getContext()->shop->id; $parsedURL = self::parseURL($uri, $idLang, $idShop); if (empty($parsedURL['controller'])) { return $fallbackController; // No route to add if controller is not determined } $_GET['id_product'] = $parsedURL['id_product']; $_GET['id_product_attribute'] = $parsedURL['id_product_attribute']; $_GET['id_category'] = $parsedURL['id_category']; return $parsedURL['controller']; } public static function parseURL(string $url, int $idLang, int $idShop): array { $path = urldecode(parse_url($url, PHP_URL_PATH)); $result = ['id_product' => null, 'id_category' => null, 'id_product_attribute' => null, 'path' => $path, 'rewrite' => null, 'rule' => null, 'controller' => null]; if (!$path) { return $result; } $parts = explode('/', trim($path, '/')); // $result['path'] = $parts; $lastPart = end($parts); // Check if last part is a product link rewrite $productId = self::getProductIdByLinkRewrite($lastPart, $idLang, $idShop); if ($productId !== null) { $result['id_product'] = $productId; $result['rule'] = '{categories}/{rewrite}'; $result['rewrite'] = $lastPart; $result['controller'] = 'product'; return $result; } // Check if last part is a category link rewrite $categoryId = self::getCategoryIdByLinkRewrite($parts, $idLang, $idShop); if ($categoryId !== null) { $result['id_category'] = $categoryId; $result['rule'] = '{rewrite}'; $result['rewrite'] = $lastPart; $result['controller'] = 'category'; return $result; } return $result; } /** * Simulates a function to get product ID by link rewrite. * Replace with your actual implementation. */ public static function getProductIdByLinkRewrite(string $linkRewrite, int $idLang, int $idShop): ?int { $sql = new DbQuery(); $sql->select('pl.id_product'); $sql->from('product_lang', 'pl'); $sql->where('pl.link_rewrite = "' . pSQL($linkRewrite) . '"'); $sql->where('pl.id_lang = ' . $idLang); $sql->where('pl.id_shop = ' . $idShop); $productId = Db::getInstance()->getValue($sql); if ($productId) { return (int) $productId; } else { return null; } } /* public static function getCategoryIdByLinkRewrite(string $linkRewrite, int $idLang, int $idShop): ?int { $sql = new DbQuery(); $sql->select('cl.id_category'); $sql->from('category_lang', 'cl'); $sql->where('cl.link_rewrite = "' . pSQL($linkRewrite) . '"'); $sql->where('cl.id_lang = ' . $idLang); $sql->where('cl.id_shop = ' . $idShop); $categoryId = Db::getInstance()->getValue($sql); if ($categoryId) { return (int) $categoryId; } else { return null; } } */ ////////////// public static function getCategoryIdByLinkRewrite(array $parts, int $idLang, int $idShop): ?int { $linkRewrite = end($parts); $sql = new DbQuery(); $sql->select('cl.id_category'); $sql->from('category_lang', 'cl'); $sql->where('cl.link_rewrite = "' . pSQL($linkRewrite) . '"'); $sql->where('cl.id_lang = ' . $idLang); $sql->where('cl.id_shop = ' . $idShop); $categoryIds = Db::getInstance()->executeS($sql); if (!$categoryIds) { return null; } if (count($categoryIds) === 1) { return (int) $categoryIds[0]['id_category']; } // Multiple categories with the same link_rewrite, resolve by parent categories return self::resolveCategoryIdByParentCategories($categoryIds, $parts, $idLang, $idShop); } private static function resolveCategoryIdByParentCategories(array $categoryIds, array $parts, int $idLang, int $idShop): ?int { // Remove the last part (current category link_rewrite) array_pop($parts); $idCategory = null; foreach ($categoryIds as $categoryData) { $categoryId = (int) $categoryData['id_category']; if (self::checkCategoryPath($categoryId, $parts, $idLang, $idShop)) { $idCategory = $categoryId; break; } } return $idCategory; } private static function checkCategoryPath(int $categoryId, array $parts, int $idLang, int $idShop): bool { $currentCategoryId = $categoryId; $parts = array_reverse($parts); // Reverse parts to iterate from parent to child foreach ($parts as $linkRewrite) { $sql = new DbQuery(); $sql->select('c.id_parent'); $sql->from('category', 'c'); $sql->leftJoin('category_lang', 'cl', 'c.id_category = cl.id_category AND cl.id_lang = ' . (int)$idLang . ' AND cl.id_shop = '.(int)$idShop); $sql->where('c.id_category = ' . (int)$currentCategoryId); $sql->where('cl.link_rewrite = "' . pSQL($linkRewrite) . '"'); $parentId = (int) Db::getInstance()->getValue($sql); if (!$parentId) { return false; } $currentCategoryId = $parentId; // Move to the parent category } // If we reached the top of the path without failing, it's a match return true; } }