Возвращение к теме о роутинге (для профилей)

Данная конструкция преобразует url вида /profile/{USERNAME} в url вида /{USERNAME}

$config['router']['uri'] = array(
    '~^([a-z_\-]+)$~i' => "profile/\1",
);


Но главной проблемой является то, что таким образом переписываются все url сайта, и мы уже не сможем попасть ни на страницу регистрации, ни входа(ни блогов и проч.).

Какой хак в данном случае использовать для класса Router?

Я думаю многим будет интересна эта тема с точки зрения создателей социальных сетей на фреймворке LiveStreet.

Спасибо за внимание!

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

avatar
Кто прокомментирует данную ситуацию?
avatar
А вы подумайте над действием
Данная конструкция преобразует url вида /profile/{USERNAME} в url вида /{USERNAME}
а как же другие урлы? /blog, /people?
(наводящая мысль)
avatar
Понимаете, после этого правила все переписывается, если я после него создам еще правило, то те url'ы все будут являться фактически профилями, и будет просто очередно редирект для определенных профилей.

Корневое переписывание URL увы переписывает все значения без исключений.
Если я не понял вашей сути, поясните подробнее пожалуйста.
avatar
т.е. я думаю что у вас не получится сделать для профилей пользователей урлы такими чтобы от корня и сразу никнейм. а что будет если зарегистрируется пользователь blog, login и register?
avatar
Так вопрос в том и стоит, что нужно эти системные url'ы зарезервировать каким либо образом
avatar
у меня есть плагин зарезервированных пользователей. внесите все таки урлы в список неразрешенных пользователей для регистрации.
avatar
Можно ссылочку?
avatar
Огромное спасибо! А как быть с роутингом? Есть какие варианты?
avatar
в былые времена использовали префикс "~" :)
тобишь получалось /~username/
avatar
это были адреса домашних страничек на серверах провайдеров
avatar
Давно это было)) Но тут нужен конкретно корневой вариант.
У меня была мысль прямо в классе Router заранее предписать все значения под условием, но пока не до конца предумал как это грамотно сделать
avatar
глянь CUrlMamager в Yii, там преобразование url -> controller/action и обратноное. регулярки работают с минимальными ограничениями
avatar
avatar
Разумеется тут логично применять регулярные выражения, но я в них не очень разбираюсь, можно пример?
avatar
??
avatar
что "??"? :)

$config['router']['uri'] = array(
    '~^\x7e([a-z_\-]+)$~i' => "profile/\1",
);

вот с префиксом
avatar
вы имеете ввиду логин будет с префиксом x7e?
avatar
$ php -r "echo preg_match('#\x7e#', '~');"
1

это эскейпинг хексадецимальный :) страшно?

префикс будет "~"
avatar
теперь не страшно. В общем я все-таки сделал небольшой хак для роутера:

if ($sReq == "login" || $sReq == "registration" и прочие... ) {return $sReq;} else {
		if($aRewrite=Config::Get('router.uri')) {
			$sReq = preg_replace(array_keys($aRewrite), array_values($aRewrite), $sReq);
		}
		
		return $sReq;
		}
avatar
Вы проверяли? У меня почему-то не работает.
avatar
уииииии, chat.ru!
avatar
Совсем никто не знает как сделать?
avatar
Есть вариант вырезать все возможные урлы в регулярке, либо проверять на существование имя пользователя, а потом редиректить например хуком на engine_init_complete:

$oEngine=Engine::getInstance();
$sLogin = Router::GetAction();
if ($oEngine->User_GetUserByLogin($sLogin)) {
   return Router::Action('profile',$sLogin,array());
}
avatar
только каюсь,
return Router::Action('profile',$sLogin,array());

будет работать вроде только в экшене.
Надо просто редирект:
header ('Location: '.Router::GetPath('profile').$sLogin);
avatar
Куда применять этот код?
avatar
можно вставить в classes/actions/Init.class.php

после

$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());
}
avatar
так лучше, наверное

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());
	}
}
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.