Хак для роутинга

При создании собственного модуля встала задача, чтобы в URLе не присутствовало название экшена, а сразу шел параметр. В сообществе нашел пару постов которые помогли разобраться, но конечного решения так и не было. Хочу поделиться тем, что у меня получилось. Рассмотрим все на примере экшена profile. Переделываем URL страницы пользователя с
site.ru/profile/vasya/
На
site.ru/vasya/

Для этого сначала дописываем в конфиг правила роутинга:
/config/config.php
$config['router']['uri'] = array(
    '~^([a-z_\-]+)$~i' => "profile/\1",
);


Добавляем код хака в файл /engine/classes/Router.class.php переделываем функцию RewriteRequest так:
protected function RewriteRequest($aRequestUrl) {
$sReq=implode('/',$aRequestUrl);		   
if(!in_array($sReq, array_keys(Config::Get('router.page'))) && $aRewrite=Config::Get('router.uri')) {
  $sReq = preg_replace(array_keys($aRewrite), array_values($aRewrite), $sReq);
  }
  return ($sReq=='') ? array() : explode('/',$sReq);
}


Добавляем код в файл /classes/actions/Init.class.php после строки $this->Hook_Run('init_action'); так:
$this->Hook_Run('init_action');
if (preg_match('/^\/+([^\/]*)/si',str_replace(Config::Get('path.root.web'),'',Router::GetPathWebCurrent()),$aMatches)) {
 $sLogin = $aMatches[1];                         
 if ($this->User_GetUserByLogin($sLogin)) {
   return Router::Action('profile',$sLogin,array());
 }    
}


Могут возникнуть проблемы с именами пользователей совпадающих с экшенами и другими объявлениями роутинга. Как например из-за пользователя admin не будет работать админка сайта. Избавиться от этой проблемы поможет плагин Reserved Users. Данным хаком можно воспользоваться и с другими экшенами аналогично, но как это скажется на движке я гарантии дать не могу у меня вроде все нормально работает пока.

12 комментариев

avatar
можно посмотреть как перенаправление делает плагин Nice URL
  • ort
  • +2
avatar
В моём решении мне больше всего не нравиться вот этот кусок кода:
if ($this->User_GetUserByLogin($sLogin)) {
   return Router::Action('profile',$sLogin,array());
 }

Т.к. получается дублирование одного и того же запроса. С начала для проверки есть ли пользователь с таким логином, а после перенаправления для получения информации о пользователе.

Nice URL плагин я разбирал в целом все ясно, но до конца не въехал как он работает. Если можешь в двух словах объяснить буду очень благодарен. Мне на самом деле всё это нужно для своего модуля, что бы сделать URLы по городам России, а не для профилей юзеров.
avatar
В моём решении мне больше всего не нравиться вот этот кусок кода
Не в ту сторону смотришь. Больше всего тебе должно не нравиться, что ты в ядро движка лезешь.
avatar
То что в ядро лезу это конечно плохо, ну я как бы и не скрываю что это хак. В классе роутинга вызовов хуков нет и плагином это не сделаешь. Проект который я на LS пишу практически весь функционал стандартный вырезан кроме регистрации, авторизации пользователей и комментариев. Т.е. я просто LS как фреймворк использую (нравиться мне LS) и обновлять движек не собираюсь.
avatar
Если можешь в двух словах объяснить буду очень благодарен.
плагин перенаправляет необходимые запросы (подходят под регулярку) на экшен error, далее в через хук init_action они отлавливаются, обрабатываются и перенаправляются на нужные экшены

В моём решении мне больше всего не нравиться вот этот кусок кода
ниже уже ответили, нужно пробовать через плагин
avatar
А как можно через плагин перегрузить метод Router::RewriteRequest тот же?
avatar
Почему посты с хаками всегда минисуют. Если есть десятки сообщений как передавать параметр в первом сегменте URL'а без ответа, почему бы людям не рассказать как это делать. Пусть лучше они на свой страх и риск в ядро полезут, чем выберут другую систему. Или расскажите как это сделать без изменения ядра.
avatar
Возможно потому, что в таких постах стоит обязательно указывать стометровыми красными буквами на ядовито-зеленом фоне: «Внимание! Этот способ может убить ваш сайт! Поэтому он только для тех, кто понимает, что делает!»

Если человек не понимает кода, который ты привел, то, ИМХО, пусть лучше он другой движок выберет, чем в ядро лезть. Или пусть смирится с тем, что «ах, какой длинный УРЛ».

Если ты ЛС чисто как фреймворк юзаешь, то вопросов нет, для тебя, возможно, и обновлять его труда не составит. Но топик твой могут прочитать сотни неопытных новичков, которые, не догадываясь о последствиях, могут полезть править ядро, а потом этот же сайт наполнится воплями-соплями, почему у них сайт не работает. А еще хуже — начнут ломиться к авторам платных плагинов и требовать поддержки, потому что у них «плагин бажный» и не хочет запускаться на их замечательном сайте, правленном их кривыми неопытными ручками.
avatar
gv0zdik подскажи, а у тебя есть база городов мне она нужна. Ты выше написал что именно для неё тебе нужен этот хак..?
avatar
avatar
ipgeobase.ru/cgi-bin/Archive.cgi
Я вот отсюда брал базу городов + там еще таблица есть для определения города по IP
avatar
Проблема с сcылками вида site/user/page (внутренние разделы профиля). При попытке зайти на страницу (напрмер www.site/user/favourites/topics/) вместо Избранных топиков отображаются данные профиля. PS: если не понятно про какие «внутренние» страницы я говорю, то можно посмотреть пример профиля на тестовом сайте ls шаблон new. (меню под фотографией) new.livestreet.ru/profile/koptev/ (стена\публикации и т.д.)
Есть советы по решению данной проблемы? :(
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.