Как использовать beforeAction в Yii или проблемы со слагами

Йии -джедаи!

Я работаю над каким-то старым проектом Yii -и должен добавить к ним некоторые функции. Yii — довольно логичный фреймворк, но в нем есть некоторые вещи, которые я не мог понять. Возможно, я еще не разобрался с Yii -. Итак, я буду описывать свою проблему шаг -за шагом -. Для нетерпеливых -краткий вопрос в конце.

Введение:Я хочу добавить в свой проект человекочитаемые -URL-адреса.Теперь URL-адреса выглядят как:www.site.com/article/359
И я хочу, чтобы они выглядели вот так:www.site.com/article/how -–-сделать -красивые -URL-адреса
Очень важно :старые статьи должны быть доступны по URL-адресам старого формата, а новые -— по новым URL-адресам.

Шаг 1:Во-первых, я обновил правила перезаписи в config/main.php :

'/' => '/view',

. И я добавил новый столбец texturl в таблицу статей. Таким образом, мы будем хранить здесь человеческий -читаемый -часть -из -url для новых статей. Затем я обновил одну статью с texturl для тестов.

Шаг 2:Приложение показывает статьи в actionView из ArticleController , поэтому я добавил туда этот код для предварительной обработки параметра ID:

if (is_numeric($id)) {
    // User try to get /article/359
    $model = $this->loadModel($id); // Article::model()->findByPk($id);
    if ($model->text_url !== null) {
        // If article with ID=359 have text url -> redirect to /article/text-url
        $this->redirect(array('view', 'id' => $model->text_url), true, 301);
    }
} else {
    // User try to get /article/text-url
    $model = Article::model()->findByAttributes(array('text_url' => $id));
    $id = ($model !== null) ? $model->id : null ;
}

А затем начните устаревший код:

$model = $this->loadModel($id); // Load article by numeric ID
// etc

Он работает отлично! Но...

Шаг 3:Но у нас много действий с параметром ID! Что мы должны сделать? Обновить все действия с этим кодом? Я думаю, это некрасиво. Я нашел метод CController ::beforeAction . Выглядит неплохо! Поэтому я объявляю beforeAction и размещаю там препроцессинг ID:

protected function beforeAction($action) {
    $actionToRun = $action->getId(); 
    $id = Yii::app()->getRequest()->getQuery('id');
    if (is_numeric($id)) {
        $model = $this->loadModel($id);
        if ($model->text_url !== null) {
            $this->redirect(array('view', 'id' => $model->text_url), true, 301);
        } 
    } else {
        $model = Article::model()->findByAttributes(array('text_url' => $id));
        $id = ($model !== null) ? $model->id : null ;
    }
    return parent::beforeAction($action->runWithParams(array('id' => $id)));
}

Да, он работает с обоими форматами URL -, но выполняет actionView . ДВАЖДЫ и показывает страницу два раза! Что я могу сделать с этим? Я совсем запутался. Выбрал ли я правильный путь решения своей проблемы?

Кратко:Могу ли я обработать ID (GET -параметр )перед выполнением каких-либо действий, а затем выполнить запрошенное действие (один раз! )с измененным только параметром ID?

6
задан Alex Belyaev 8 August 2012 в 05:54
поделиться