/** * Generate either id path, request path or target path for product and/or category * * For generating id or system path, either product or category is required * For generating request path - category is required * $parentPath used only for generating category path * * @param string $type * @param Varien_Object $product * @param Varien_Object $category * @param string $parentPath * @return string * @throws Mage_Core_Exception */ public function generatePath($type = 'target', $product = null, $category = null, $parentPath = null) { if (!$product && !$category) { Mage::throwException(Mage::helper('core')->__('Please specify either a category or a product, or both.')); } // generate id_path if ('id' === $type) { if (!$product) { return 'category/' . $category->getId(); } if ($category && $category->getLevel() > 1) { return 'product/' . $product->getId() . '/' . $category->getId(); } return 'product/' . $product->getId(); } // generate request_path if ('request' === $type) { // for category if (!$product) { if ($category->getUrlKey() == '') { $urlKey = $this->getCategoryModel()->formatUrlKey($category->getName()); } else { $urlKey = $this->getCategoryModel()->formatUrlKey($category->getUrlKey()); } $categoryUrlSuffix = $this->getCategoryUrlSuffix($category->getStoreId()); if (null === $parentPath) { $parentPath = $this->getResource()->getCategoryParentPath($category); } elseif ($parentPath == '/') { $parentPath = ''; } $parentPath = Mage::helper('catalog/category')->getCategoryUrlPath($parentPath, true, $category->getStoreId()); return $this->getUnusedPath($category->getStoreId(), $parentPath . $urlKey . $categoryUrlSuffix, $this->generatePath('id', null, $category)); } // for product & category if (!$category) { Mage::throwException(Mage::helper('core')->__('A category object is required for determining the product request path.')); // why? } if ($product->getUrlKey() == '') { $urlKey = $this->getProductModel()->formatUrlKey($product->getName()); } else { $urlKey = $this->getProductModel()->formatUrlKey($product->getUrlKey()); } $productUrlSuffix = $this->getProductUrlSuffix($category->getStoreId()); if ($category->getLevel() > 1) { // To ensure, that category has url path either from attribute or generated now $this->_addCategoryUrlPath($category); $categoryUrl = Mage::helper('catalog/category')->getCategoryUrlPath($category->getUrlPath(), false, $category->getStoreId()); return $this->getUnusedPath($category->getStoreId(), $categoryUrl . '/' . $urlKey . $productUrlSuffix, $this->generatePath('id', $product, $category)); } // for product only return $this->getUnusedPath($category->getStoreId(), $urlKey . $productUrlSuffix, $this->generatePath('id', $product)); } // generate target_path if (!$product) { return 'catalog/category/view/id/' . $category->getId(); } if ($category && $category->getLevel() > 1) { return 'catalog/product/view/id/' . $product->getId() . '/category/' . $category->getId(); } return 'catalog/product/view/id/' . $product->getId(); }
/** * Get unique product request path * * @param Varien_Object $product * @param Varien_Object $category * @return string */ public function getProductRequestPath($product, $category) { if ($product->getUrlKey() == '') { $urlKey = $this->getProductModel()->formatUrlKey($product->getName()); } else { $urlKey = $this->getProductModel()->formatUrlKey($product->getUrlKey()); } $storeId = $category->getStoreId(); $suffix = $this->getProductUrlSuffix($storeId); $idPath = $this->generatePath('id', $product, $category); /** * Prepare product base request path */ if ($category->getLevel() > 1) { // To ensure, that category has path either from attribute or generated now $this->_addCategoryUrlPath($category); $categoryUrl = Mage::helper('catalog/category')->getCategoryUrlPath($category->getUrlPath(), false, $storeId); $requestPath = $categoryUrl . '/' . $urlKey; } else { $requestPath = $urlKey; } if (strlen($requestPath) > self::MAX_REQUEST_PATH_LENGTH + self::ALLOWED_REQUEST_PATH_OVERFLOW) { $requestPath = substr($requestPath, 0, self::MAX_REQUEST_PATH_LENGTH); } $this->_rewrite = null; /** * Check $requestPath should be unique */ if (isset($this->_rewrites[$idPath])) { $this->_rewrite = $this->_rewrites[$idPath]; $existingRequestPath = $this->_rewrites[$idPath]->getRequestPath(); $existingRequestPath = str_replace($suffix, '', $existingRequestPath); if ($existingRequestPath == $requestPath) { return $requestPath . $suffix; } /** * Check if existing request past can be used */ if (!empty($requestPath) && strpos($existingRequestPath, $requestPath) !== false) { $existingRequestPath = str_replace($requestPath, '', $existingRequestPath); if (preg_match('#^-([0-9]+)$#i', $existingRequestPath)) { return $this->_rewrites[$idPath]->getRequestPath(); } } /** * check if current generated request path is one of the old paths */ $fullPath = $requestPath . $suffix; $finalOldTargetPath = $this->getResource()->findFinalTargetPath($fullPath, $storeId); if ($finalOldTargetPath && $finalOldTargetPath == $idPath) { $this->getResource()->deleteRewrite($fullPath, $storeId); return $fullPath; } } /** * Check 2 variants: $requestPath and $requestPath . '-' . $productId */ $validatedPath = $this->getResource()->checkRequestPaths(array($requestPath . $suffix, $requestPath . '-' . $product->getId() . $suffix), $storeId); if ($validatedPath) { return $validatedPath; } /** * Use unique path generator */ return $this->getUnusedPath($storeId, $requestPath . $suffix, $idPath); }
/** * Generate either id path, request path or target path for product review * * @param string $type * @param Varien_Object $product * @return string * @throws Mage_Core_Exception */ public function generateSinglePath($type = 'target', $review, $product) { // generate id_path if ('id' === $type) { return 'review/' . $review->getId(); } // generate request_path if ('request' === $type) { if ($product->getUrlKey() == '') { $pUrlKey = $this->getProductModel()->formatUrlKey($product->getName()); } else { $pUrlKey = $this->getProductModel()->formatUrlKey($product->getUrlKey()); } $urlKey = $this->getProductModel()->formatUrlKey($review->getTitle()); if (!$urlKey) { $urlKey = 'review'; } $productUrlSuffix = $this->getProductUrlSuffix($review->getStoreId()); return $this->getUnusedPath($review->getStoreId(), 'reviews/' . $pUrlKey . '/' . $urlKey . $productUrlSuffix, $this->generateSinglePath('id', $review, $product)); } return 'review/product/view/id/' . $review->getId(); }
/** * Get unique product request path * * @param Varien_Object $product * @param Varien_Object $category * @return string */ public function getProductRequestPath($product, $category) { if ($product->getUrlKey() == '') { $urlKey = $this->getProductModel()->formatUrlKey($product->getName()); } else { $urlKey = $this->getProductModel()->formatUrlKey($product->getUrlKey()); } $storeId = $category->getStoreId(); $suffix = $this->getProductUrlSuffix($storeId); $idPath = $this->generatePath('id', $product, $category); /** * Prepare product base request path */ if ($category->getLevel() > 1) { // To ensure, that category has path either from attribute or generated now $this->_addCategoryUrlPath($category); $categoryUrl = Mage::helper('catalog/category')->getCategoryUrlPath($category->getUrlPath(), false, $storeId); $requestPath = $categoryUrl . '/' . $urlKey; } else { $requestPath = $urlKey; } if (strlen($requestPath) > self::MAX_REQUEST_PATH_LENGTH + self::ALLOWED_REQUEST_PATH_OVERFLOW) { $requestPath = substr($requestPath, 0, self::MAX_REQUEST_PATH_LENGTH); } $this->_rewrite = null; /** * Check $requestPath should be unique */ if (isset($this->_rewrites[$idPath])) { $this->_rewrite = $this->_rewrites[$idPath]; $existingRequestPath = $this->_rewrites[$idPath]->getRequestPath(); if ($existingRequestPath == $requestPath . $suffix) { return $existingRequestPath; } $existingRequestPath = preg_replace('/' . preg_quote($suffix, '/') . '$/', '', $existingRequestPath); /** * Check if existing request past can be used */ if ($product->getUrlKey() == '' && !empty($requestPath) && strpos($existingRequestPath, $requestPath) === 0) { $existingRequestPath = preg_replace('/^' . preg_quote($requestPath, '/') . '/', '', $existingRequestPath); if (preg_match('#^-([0-9]+)$#i', $existingRequestPath)) { return $this->_rewrites[$idPath]->getRequestPath(); } } $fullPath = $requestPath . $suffix; // PATCH TO FIX MAGENTO BUG THAT DUPLICATES REWRITES WHEN URL_KEY IS EQUAL BETWEEN PRODUCTS $pattern = '/^' . preg_quote($requestPath, '/') . '-\\d{1,}$/'; if (preg_match($pattern, $existingRequestPath)) { $fullPath = $existingRequestPath . $suffix; } // END OF PATCH // @TODO This function _deleteOldTargetPath does not seem to exist in Magento 1.6.2.0 if ($this->_deleteOldTargetPath($fullPath, $idPath, $storeId)) { return $fullPath; } } /** * Check 2 variants: $requestPath and $requestPath . '-' . $productId */ $validatedPath = $this->getResource()->checkRequestPaths(array($requestPath . $suffix, $requestPath . '-' . $product->getId() . $suffix), $storeId); if ($validatedPath) { return $validatedPath; } /** * Use unique path generator */ return $this->getUnusedPath($storeId, $requestPath . $suffix, $idPath); }