私のソリューションが最もエレガントだとは思いませんが、うまくいったので投稿します。基本的には指定店舗のみではなく、探しているパスを全店舗で検索しています。どんな提案でも大歓迎です。
私のconfig.xml
<?xml version="1.0"?>
<config>
<global>
<modules>
<Soipo_UrlRewrite>
<version>0.1</version>
</Soipo_UrlRewrite>
</modules>
<models>
<soipo_urlrewrite>
<class>Soipo_UrlRewrite_Model</class>
</soipo_urlrewrite>
<core_mysql4>
<rewrite>
<url_rewrite>Soipo_UrlRewrite_Model_Mage_Core_Model_Mysql4_Url_Rewrite</url_rewrite>
</rewrite>
</core_mysql4>
</models>
</global>
</config>
Rewrite.php
<?php
class Soipo_UrlRewrite_Model_Mage_Core_Model_Mysql4_Url_Rewrite extends Mage_Core_Model_Mysql4_Url_Rewrite{
/**
* This function get an array of store ids, containing the Admin store.
* @return array
*/
public function getStoreIds(){
$allStores = Mage::app()->getStores();
$storeIds = array();
$storeIds[] = Mage_Core_Model_App::ADMIN_STORE_ID;
foreach ($allStores as $_eachStoreId => $val)
{
$_storeId = Mage::app()->getStore($_eachStoreId)->getId();
$storeIds[] = $_storeId;
}
return $storeIds;
}
/**
* Load rewrite information for request
* If $path is array - we must load all possible records and choose one matching earlier record in array
*
* @param Mage_Core_Model_Url_Rewrite $object
* @param array|string $path
* @return Mage_Core_Model_Resource_Url_Rewrite
*/
public function loadByRequestPath(Mage_Core_Model_Url_Rewrite $object, $path)
{
if (!is_array($path)) {
$path = array($path);
}
$pathBind = array();
foreach ($path as $key => $url) {
$pathBind['path' . $key] = $url;
}
$storeIds = $this->getStoreIds();
// Form select
$adapter = $this->_getReadAdapter();
$select = $adapter->select()
->from($this->getMainTable())
->where('request_path IN (:' . implode(', :', array_flip($pathBind)) . ')')
->where('store_id IN(?)', $storeIds);
$items = $adapter->fetchAll($select, $pathBind);
// Go through all found records and choose one with lowest penalty - earlier path in array, concrete store
$mapPenalty = array_flip(array_values($path)); // we got mapping array(path => index), lower index - better
$currentPenalty = null;
$foundItem = null;
foreach ($items as $item) {
if (!array_key_exists($item['request_path'], $mapPenalty)) {
continue;
}
$penalty = $mapPenalty[$item['request_path']] << 1 + ($item['store_id'] ? 0 : 1);
if (!$foundItem || $currentPenalty > $penalty) {
$foundItem = $item;
$currentPenalty = $penalty;
if (!$currentPenalty) {
break; // Found best matching item with zero penalty, no reason to continue
}
}
}
// Set data and finish loading
if ($foundItem) {
$object->setData($foundItem);
}
// Finish
$this->unserializeFields($object);
$this->_afterLoad($object);
return $this;
}
}