CMS Eleanor - Поиск
Полная версия этой страницы: Официальный форум Eleanor CMS » Формирование и обработка ссылок в Eleanor
Официальный форум Eleanor CMS » Для вебмастеров и владельцев сайтов » Комната программистов
Интересует реализация механизма Friendly Url (ЧПУ) в Eleanor CMS.

Я новичок в PHP. Теории много, практики мало :(

Ковыряясь в очередной раз в коде Eleanor заинтересовался реализацией механизма, который работает с ссылками.
Ход моих исследований:

Запустил на денвере две копии Eleanor - одну с ЧПУ, другую с отключённым ЧПУ и начал сравнивать.
С ЧПУ: http://example.com/аккаунт/logout
Без ЧПУ: http://example.com/module=аккаунт&do=logout

Открыл .htaccess:
RewriteRule ^(.*)$ index.php?!$1&%{QUERY_STRING} [L]


Полазив около часа в рунете и почитав о работе mod rewrite строчка проянилась. Как я понял, поправьте, если ошибаюсь, эта штука заменяет строку вида http://example.com/аккаунт/logout на http://example.com/index.php?!аккаунт/logout в контексте работы сервера. Как эту строку дальше обрабатывает движок, я так и не понял. Интуиция кивает на class Url в с торону Parse(), но я не уверен. Формирование ссылки, насколько я понял происходит в классе Url функции Construct() на основании массива, переданного в параметрах, затем у этого массива "отбрасываются" ключи, а значения склеиваются слешем. (Опять же, насколько я понял) Возникает вопрос. Сформировать-то сформировали, но вот у нас есть ссылка http://example.com/аккаунт/logout, как система ключи (module и do) восставнавливает? или там какой-то другой принцип? Расскажите пожалуйста, если это, конечно, не какая-нибудь коммерческая тайна :)
Alexander
wizard993, не коммерческая :) Все ваши предыдущие рассуждения верны.
Если Вы присмотритесь к методу Parse класса Url, то увидите, что этот метод принимает на вход массив. Значения этого массива и есть ключи, которые необходимо восстановить. Система обрабатывает аккаунт/logout следующим образом: разбивает на подстроки используя разделитель / . Далее смотрит на каждую подстроку, если в подстроке нет ключа - она берет ключ из первого аргумента функции Parse. Вот так.
Alexander, спасибо! :)

Alexander
Спрашивайте. Остальным тоже будет интересно узнать как все работает.
Так. Вот мы нажали на ссылку. А что происходит за кулисами? Ну вот всё тот же пример. http://example.com/аккаунт/logout Нажали. что дальше?) как index.php (ну или core/core.php) понимает какие файлы открывать и какие классы запускать? Ведь обращение к $Url->Parse(...) происходит в файлах модулей (api.php user/index.php) , а туда надо добраться... И потом, добрались туда, там получили отпарсенный массив, и что происходит дальше? :dntknw: Поиском в Notepad++ пробил запрос switch($_GET. Он показал 21 совпадение строчки switch($_GET['do']), я сомневаюсь, что всего 21 обработка GET'а на весь движок. Так как вообще всё это отрабатывается? То есть я хочу понять, что происходит с точки зрения движка от момента нажатия по ссылке и до вывода результата в браузер. Если долго объяснять, то может просто подскажите какие файлы копать?
Заранее извините, если тупые вопросы, отчасти они возникают из-за того, что в интеренете очень мало расписано про подходы к ЧПУ, вернее мало примеров и они в основном очевидные и туповатые, а у Eleanor код сложный :unsure: , но подходы к решению задач интересные :)
Alexander
wizard993, для начала расковыряйте файл index.php из корня, там вы найдете первую стадию обработки ссылок: а именно узнавание какой модуль загружать.
Alexander, это конечно сильно :) спасибо большое. я просто пока ограничивался строчкой где идёт подключение core.php и дальше смотрел его код. index.php даже не разбирал :( спасибо ещё раз, будем дальше искать и дальше тупить
Alexander, код ужасно сложный :crazy: в плане того, что всё настолько взаимосвязано, что просто можно потерятся. :unsure: Одна конструкция перетекает в другую, другая в третью и т.д.
По существу вопроса, нашёл в index.php (тот который в корне) функцию LangNewUrl($url,$l)
там есть кусок кода:
if(!class_exists($c,false))
		include$path.$arr['api'];

Как я понял, он вытягивает поле 'api' из таблицы 'modules' БД и подключает api.php, тот, который лежит в папке модуля. Но это не то что я искал)
Так я и не нашёл эту первую стадию обработки ссылок. :(
Alexander
wizard993, код на самом деле не тяжелый. Просто он на уровень выше привычного. Для начала поясню, что вы не там смотрите. Вот участо кода, который вы ищите.

$m=isset($_REQUEST['module']) ? (string)$_REQUEST['module'] : $Eleanor->Url->ParseToValue('module');
if($m)
{
	if(!isset($Eleanor->modules['ids'][$m]))
		return MainPage($m);
	Eleanor::$Db->Query('SELECT `id`,`sections`,`title_l`,`path`,`multiservice`,`file`,`files`,`user_groups` FROM `'.P.'modules` WHERE `id`='.(int)$Eleanor->modules['ids'][$m].' AND `active`=1 LIMIT 1');
	if(!$arr=Eleanor::$Db->FetchAssoc())
		return MainPage($m);
	...
}


А то, что вы нашли, это код, который отвечает за преобразование ссылок из одного языка в другой. Ведь для разных языковых версий сайта, ссылки на новость так же разные!
Alexander, спасибо большое за ваше терпение :) , за ваши ответы и пояснения. Этот кусок кода тоже видел, но смутила функция ParseToValue(). Я искал из тех соображений, что где-то в индексе должен быть include либо require, который подключает какой-нибудь из файлов модуля.

Цитата
код на самом деле не тяжелый

когда я не знал, что такое ООП, код казался вообще чудовищным :)
Alexander
wizard993, окей. Поясняю, что это за функция. Дело в том, что получая ссылку, система понятия не имеет о чем эта ссылка вообще (все параметры определяет только модуль). И вот, чтобы разобраться куда хотя бы ведет эта ссылка, система вызывает функцию ParseToValue, которая пытается вытащить первый параметр из ссылки. А это в 99.999% имя модуля. Остальную часть ссылки функция ParseToValue оставляет без изменений давая модулю возможность самостоятельно решить что с ней делать дальше.

Добавлено через 2 минут, 18 секунд:

Don53_Empire, ваши сообщения удалены. Для вопросов не касающихся этой темы - создавайте отдельную тему.
Alexander, спасибо за пояснения.
т.е. функция Parse() применяется уже непосредственно в модуле?
Хотел ещё спросить. Вот в index.php есть такая строка
$Eleanor->Url->special=$Eleanor->Url->furl ? '' : Eleanor::$filename.'?';

само свойство special не внесено в список свойств класса Url, но из этой строки понятно, что всё завязано на Eleanor::$filename, в core.php следующее описание:
$filename,#Ч. Название файла-сервиса, запускающего весь движок. Используется чаще всего для генерирования УРЛов


что это за зверь? :) ну вообще в общих чертах, что такое файл-сервис? я предполагаю, что если ЧПУ включено, то special='', иначе special='index.php' (ну почему-то мне так кажется)

ещё вопрос, косвенно касающийся этой темы, вот
$m=isset($_REQUEST['module']) ? (string)$_REQUEST['module'] : $Eleanor->Url->ParseToValue('module');
if($m)
{
	if(!isset($Eleanor->modules['ids'][$m]))
		return MainPage($m);
	Eleanor::$Db->Query('SELECT `id`,`sections`,`title_l`,`path`,`multiservice`,`file`,`files`,`user_groups` FROM `'.P.'modules` WHERE `id`='.(int)$Eleanor->modules['ids'][$m].' AND `active`=1 LIMIT 1');
	if(!$arr=Eleanor::$Db->FetchAssoc())
		return MainPage($m);
	...
}

приводит нас к таблице modules, посмотрел на структуру таблицы - там есть два поля: active и protected, почему они обозначены как TinyInt, хотя по идее принимают либо 0 либо 1 (что есть BOOLEAN), или на это есть причины?
Ну даже если рассматривать как TinyInt, тогда непонятно, почему поле active помечено как TinyInt(4), ведь TinyInt охватывает промежуток от -128 до 127 (либо беззнаковое от 0 до 255) , что является в любом случае числом, длиной 3, но никак не 4.

И ещё вопросик, сейчас, как я понял, нету интерфейса, который бы устанавливал модули, т.е. установка происходит вручную (ну pm например устанавливаются с помощью импорта SQL запроса). Есть какие-нибудь планы на этот счёт, в плане реализации такого механизма?

P.S.
Как я уже говорил, поставил на Denwer параллельно два дистрибутива Eleanor CMS - один с включённым ЧПУ, а другой с выключенным.
Так вот. Если в системе без ЧПУ ввести ЧПУ-шный URL, CMS всё равно откроет правильную страницу, но адрес оставит тем же.
То есть в системе без ЧПУ вводим: http://example.com/новости.html и она открывает модуль новости. URL в адресной строке остаётся ЧПУ-шным.
А если в системе с включённым ЧПУ вводим http://example.com/index.php?module=новости то она тоже открывает модуль новости. URL в адресной строке остаётся обыкновенным.

Собственно вопрос: можно ли сделать (как один из вариантов), так, чтобы при использовании системы без ЧПУ, CMS-ка меняла введённые в адресной строке ЧПУ урлы на нормальные и наоборот - при использовании системы с ЧПУ, CMS-ка меняла введённые в адресной строке обычные урлы на ЧПУ?

Как я себе это представляю. Вот мы вводим в системе с выключенным ЧПУ Friendly URL. Apache возвращает нам строку, содержащую на первой позиции !. А дпльше мы вытаскиваем из класса Url свойство $furl и смотрим, если в QUERY_STRING присутствует ! и !$furl значит как-то подменяем Friendly URL на обычный :)
Надеюсь я адекватно выразил свою мысль :D

Спасибо. :)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.