在SHELL目录下新建立一文件命名为rewrites_doctor.php
<?php require_once 'abstract.php'; class Atwix_Shell_Rewrites_Doctor extends Mage_Shell_Abstract { const PAGE_SIZE = 1000; const LOG_MESSAGE_ROWS = 100; public function run() { if($left = $this->getArg('remove_rewrites')){ $this->clearExtraRewrites($left); } elseif($this->getArg('update_keys')) { $this->updateDuplicatedKeys(); } elseif($this->getArg('remove_sku_spaces')) { $this->removeSkuSpaces(); } else { echo $this->usageHelp(); } } /** * Update duplicated url keys by adding product SKU to the duplicated key */ public function updateDuplicatedKeys() { try { $counter = 0; $logMessage = ''; $start = time(); $storeId = Mage::app()->getStore()->getId() . PHP_EOL; //url key attriubte load for further use $entityType = Mage::getModel('eav/entity_type')->loadByCode('catalog_product'); $attributes = $entityType->getAttributeCollection() ->addFieldToFilter('attribute_code', array('eq' => 'url_key')) ; $urlKeyAttribute = $attributes->getFirstItem(); $urlKeyAttributeTable = $attributes->getTable($entityType->getEntityTable()); //loading collection with number of duplicated url keys $duplicatesCollection = Mage::getModel('catalog/product')->getCollection(); $duplicatesCollection->getSelect() ->joinLeft( array('url_key' => $urlKeyAttributeTable . '_' . $urlKeyAttribute->getBackendType()), 'e.entity_id' . ' = url_key.entity_id AND url_key.attribute_id = ' . $urlKeyAttribute->getAttributeId() . ' AND url_key.store_id = ' . $storeId, array($urlKeyAttribute->getAttributeCode() => 'url_key.value') ) ->columns(array('duplicates_calculated' => new Zend_Db_Expr ('COUNT(`url_key`.`value`)'))) ->group('url_key.value') ->order('duplicates_calculated DESC') ; foreach($duplicatesCollection as $item) { if($item->getData('duplicates_calculated') > 1) { //loading product ids with duplicated url keys $duplicatedUrlKey = $item->getData('url_key'); $productCollection = Mage::getModel('catalog/product')->getCollection() ->addAttributeToSelect('url_key') ->addAttributeToFilter('url_key', array('eq' => $duplicatedUrlKey)) ; $ids = $productCollection->getAllIds(); foreach($ids as $id){ try { //update product url key $product = Mage::getModel('catalog/product')->load($id); $sku = $product->getData('sku'); $urlKey = $product->getData('url_key'); $product->setData('url_key', $urlKey . '-' . strtolower(str_replace(' ', '-', $sku))); $product->save(); $counter++; $message = 'Product id# ' . $product->getId() . ' "' . $product->getName() . '" ' . ' url key was changed from "' . $urlKey . '" to "' . $product->getData('url_key') . '"' . PHP_EOL; $logMessage .= $message; //log will be update with the packs of messages if($counter % self::LOG_MESSAGE_ROWS == 0) { Mage::log($logMessage, null, 'atwix_rewrites_doctor.log', true); $logMessage = ''; } echo $message; } catch (Exception $e) { echo $e->getMessage() . PHP_EOL; Mage::log($e->getMessage(), null, 'atwix_rewrites_doctor.log', true); } } } else { //we will break the cycle after all duplicates in query were processed break; } } if($counter % self::LOG_MESSAGE_ROWS != 0) { Mage::log($logMessage, null, 'atwix_rewrites_doctor.log', true); } $end = time(); $message = $counter . ' products were updated, time spent: ' . $this->timeSpent($start, $end); Mage::log($message, null, 'atwix_rewrites_doctor.log', true); echo $message . PHP_EOL; } catch (Exception $e) { echo $e->getMessage() . PHP_EOL; Mage::log($e->getMessage(), null, 'atwix_rewrites_doctor.log', true); } } /** * Remove extra product url rewrites leaving $left of last * * @var $left */ public function clearExtraRewrites($left) { try { $start = time(); //Get product collection $productCollection = Mage::getModel('catalog/product')->getCollection(); $productCollection->setPageSize(self::PAGE_SIZE); $pages = $productCollection->getLastPageNumber(); $currentPage = 1; $counter = 0; while($currentPage <= $pages) { $productCollection->setCurPage($currentPage); $productCollection->load(); $ids = $productCollection->getAllIds(); foreach($ids as $id) { //get rewrites collection for current product id $urlRewritesCollection = Mage::getModel('core/url_rewrite')->getCollection() ->addFieldToFilter('product_id', array('eq' => $id)) ->addFieldToFilter('is_system', array('eq' => '0')) ->setOrder('url_rewrite_id', 'DESC') ; $urlRewritesCollection->getSelect()->limit(null, $left); foreach($urlRewritesCollection as $urlRewrite) { try { $urlRewrite->delete(); $counter++; } catch(Exception $e) { echo "An error was occurred: " . $e->getMessage() . PHP_EOL; Mage::log($e->getMessage(), null, 'atwix_rewrites_doctor.log', true); } } } echo $counter . " URL rewrites were deleted" . PHP_EOL; $currentPage++; $productCollection->clear(); } $end = time(); $message = 'Total URL rewrites deleted: ' . $counter . ', time spent: ' . $this->timeSpent($start, $end); Mage::log($message, null, 'atwix_rewrites_doctor.log', true); echo $message . PHP_EOL; } catch (Exception $e) { echo "An error was occurred: " . $e->getMessage() . PHP_EOL; Mage::log($e->getMessage(), null, 'atwix_rewrites_doctor.log', true); } } public function timeSpent($start, $end) { $seconds = $end - $start; $hours = floor($seconds / 3600); $mins = floor(($seconds - ($hours*3600)) / 60); $secs = floor($seconds % 60); return $hours . ' hours ' . $mins . ' minutes ' . $secs . ' seconds'; } /** * Retrieve Usage Help Message * */ public function usageHelp() { return " \n \n Usage: php -f fix_attributes -- [options] \n \n --remove_rewrites number Remove old product rewrites, leaving the 'number' of last ones \n update_keys Update duplicated product keys \n remove_sku_spaces Remove space from all product SKU's if they are present \n \n help This help \n "; } } $shell = new Atwix_Shell_Rewrites_Doctor(); $shell->run();
只需将包含上述代码的脚本放入 your_magento_root/shell/rewrites_doctor.php 即可。此外,如果您尝试运行该脚本,则可以看到“使用帮助”。首先,您需要更新重复的 URL 键。如果您已位于 Magento 安装根文件夹中,请在 shell 中输入以下命令:
php shell/rewrites_doctor.php update_keys
php shell/rewrites_doctor.php 更新密钥
脚本完成其任务后,执行重新索引以创建修改后的产品 URL 键的新 URL:
php shell/indexer.php --reindex url_redirect
此外,完成后,您可以使用此 shell 命令删除不必要的 URL 重写,保留指定数量的最新 URL 重写:
php shell/rewrites_doctor.php --remove_rewrites 4
如果我们每周执行一次重新索引,那么最后 4 次重写将为我们节省上个月的 URL,这对于爬虫来说应该足够了。
请登录已经激活账号继续浏此文章所有内容!