Как изменить идентификатор URL пользовательского модуля из бэкэнда, то есть конфигурации системы - PullRequest
3 голосов
/ 08 июля 2011

Я хочу дать администратору возможность изменить идентификатор URL-адреса MyCustomModule из внутреннего интерфейса.

Например: www.mydomain.com/identifier

Я сделал следующее:

В etc / system.xml

<identifier translate="label">
    <label>SELF URL Identifier</label>
    <frontend_type>text</frontend_type>
**<backend_model>press/config_identifier</backend_model>** // edited after answer
    <sort_order>1</sort_order>
    <show_in_default>1</show_in_default>
    <show_in_website>1</show_in_website>
    <show_in_store>1</show_in_store>
    <comment>(eg: domain.com/identifier)</comment>
</identifier>

In helper / data.php

public function getUrl($identifier = null)
{

    if (is_null($identifier)) {
        $url = Mage::getUrl('').self::getListIdentifier();
    } else {
        //$url = Mage::getUrl(self::getListIdentifier()).$identifier;
**$url = Mage::getUrl(self::getListIdentifier(), array('identifier' => $identifier,'_use_rewrites'=>true)); //edited
        }**
    return $url;
}

после этого я создал файл модели identifier.php:

class FME_Press_Model_Config_Identifier extends Mage_Core_Model_Config_Data

{

    protected function _afterSave()

    {

        if ($this->isValueChanged()) {

            $path = $this->getValue();



            // for each $store and $id combination...



            Mage::getModel('core/url_rewrite')

                ->loadByIdPath('press/'.$store.'/'.$identifier)

                ->setRequestPath($path.'/'.$identifier)

                ->save();

        }

    }

}

в config.xml я написал это:

<events>
    <controller_front_init_routers>
        <observers>
            <press>
                <type>singleton</type>
                <class>FME_Pres_Controller_Router</class>
                <method>initControllerRouters</method>
            </press>
        </observers>
    </controller_front_init_routers>
</events>

а также это присутствует в моем файле, я не уверен, что это актуально:

    <adminhtml>
        <args>
            <modules>
                <FME_Press_Override before="Mage_Adminhtml">FME_Press_Override_Admin</FME_Press_Override>
            </modules>
        </args>
    </adminhtml>

ПРИМЕЧАНИЕ. Мне сказали внести некоторые изменения в Controller/Router.php, но я не знаю, какие изменения сделать.

Если хотите, я тоже могу добавить этот код?

Теперь, что еще мне делать?

1 Ответ

7 голосов
/ 09 июля 2011

Я чувствую, что изменение маршрутизатора приложения - совершенно неправильный подход. Это грязно и может быть легко сломано, если другой модуль переопределит его для аналогичной цели. Чистый путь с перезаписью URL.

Вы хотите, чтобы оно было изменяемым, поэтому вы не можете использовать фиксированное переписывание на основе XML . Вместо этого давайте посмотрим на встроенную систему перезаписи.

Сначала в файле etc / config.xml вашего модуля установите обычный контроллер.

<frontend>
    <routers>
        <MyCustomModule>
            <use>standard</use>
            <args>
                <module>Example_MyCustomModule</module>
                <frontName>customlist</frontName>
            </args>
        </MyCustomModule>
    </routers>
</frontend>

Здесь используемое имя customlist, которое всегда будет работать и не должно конфликтовать с любым другим именем, переписанное имя должно быть в дополнение к этому. Теперь всякий раз, когда вы генерируете URL (возможно, в виде вспомогательной функции), вы делаете это для этого явно фиксированного имени.

$url = Mage::getUrl('customlist', array(
    'id' => $id,    // 'id' will get used in the "target path" later
    '_use_rewrites' => true
));

Обратите внимание, что идентификатор переменной ($id) передается в функцию getUrl, а не просто добавляется к ее результату. Если функция возвращает URL с запросом (&) или фрагментом (#), идентификатор мог быть добавлен в неправильную часть.

Следующим шагом является создание записей перезаписи для каждой возможной комбинации идентификатора и store . Вероятно, у вас есть конечное количество списков, так что это возможно, возможно, идентификаторы являются специфическими для хранилищ, поэтому их нужно определять только один раз для каждого. Либо переберите все свои списки в сценарии установки , либо попросите каждый список создавать новые записи при сохранении.

$path = Mage::getStoreConfig('custom/config/identifier', $storeId);
// Change 'custom/config/identifier' to match the path used in system.xml

$rewrite = Mage::getModel('core/url_rewrite')
               ->loadByIdPath('customlist/'.$store.'/'.$id);
if ($rewrite->getId()) {
    // A rewrite already exists, you might want to skip creating another
    continue;
}

Mage::getModel('core/url_rewrite')
    ->setStoreId($storeId)
    ->setIsSystem(true) // set to false to allow admin to edit directly
    ->setOptions('RP') // Redirect Permanent 301
    ->setIdPath('customlist/'$storeId.'/'.$id) // should never change
    ->setTargetPath('customlist/index/index/id/'.$id) // what gets used
    ->setRequestPath($path.'/'.$id) // the path used in the browser
    ->save();

Так что теперь, если администратор устанавливает путь URL-адреса «foo / bar» и запрашивает страницу «www.mydomain.com/foo/bar/3», он будет переписан в «customlist / index / index / id /» 3 ", и будет вызван метод Example_MyCustomModule_IndexController::indexAction(). Файл, содержащий это, будет, конечно, app / code / local / Example / MyCustomModule / controllers / IndexController.php , и там будет получено значение 3:

public function indexAction()
{
    $id = $this->getRequest()->getParam('id'); // 'id' was specified in getUrl()
    // use $id here...
}

Это должно сработать, но что если список будет удален? Переписанные должны быть обновлены для каждого магазина. В моделях есть метод _beforeDelete, переопределите его для объектов списка.

protected function _beforeDelete()
{
    Mage::getModel('core/url_rewrite')
        ->loadByIdPath('customlist/'.$storeId.'/'.$this->getId())
        ->delete();
    return parent::_beforeDelete();
}

Аналогичным образом их необходимо обновить, чтобы они соответствовали изменениям в конфигурации.

и т.д. / System.Xml

<identifier translate="label">
    <label>SELF URL Identifier</label>
    <frontend_type>text</frontend_type>
    <backend_model>myCustomModule/config_identifier</backend_model>
    ...
</identifier>

Модель / Config / Identifier.php

class Example_MyCustomModule_Model_Config_Identifier
    extends Mage_Core_Model_Config_Data
{
    protected function _afterSave()
    {
        if ($this->isValueChanged()) {
            $path = $this->getValue();
            // for each $store and $id combination...
            Mage::getModel('core/url_rewrite')
                ->loadByIdPath('customlist/'.$store.'/'.$id)
                ->setRequestPath($path.'/'.$id)
                ->save();
        }
    }
}
...