X   Сообщение сайта
(Сообщение закроется через 2 секунды)

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Формирование и обработка ссылок в Eleanor, Как, откуда, почему?
Гость_wizard993_*
сообщение 2012-01-29, 18:27
Сообщение #1



Гости





Интересует реализация механизма 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
сообщение 2012-01-29, 19:36
Сообщение #2
Eleanor developer
Иконка группы

Группа: Администраторы
Сообщений: 5 261
Регистрация: 2008-11-11
Из: Николаев
Версия системы: RC5

Репутация:   нет  
Всего: 67


wizard993, не коммерческая :) Все ваши предыдущие рассуждения верны.
Если Вы присмотритесь к методу Parse класса Url, то увидите, что этот метод принимает на вход массив. Значения этого массива и есть ключи, которые необходимо восстановить. Система обрабатывает аккаунт/logout следующим образом: разбивает на подстроки используя разделитель / . Далее смотрит на каждую подстроку, если в подстроке нет ключа - она берет ключ из первого аргумента функции Parse. Вот так.
Перейти в начало страницы
+Цитировать сообщение
Гость_wizard993_*
сообщение 2012-01-29, 20:09
Сообщение #3



Гости





Alexander, спасибо! :)



Сообщение отредактировал wizard993 - 2012-01-29, 20:19
Перейти в начало страницы
+Цитировать сообщение
Alexander
сообщение 2012-01-30, 5:41
Сообщение #4
Eleanor developer
Иконка группы

Группа: Администраторы
Сообщений: 5 261
Регистрация: 2008-11-11
Из: Николаев
Версия системы: RC5

Репутация:   нет  
Всего: 67


Спрашивайте. Остальным тоже будет интересно узнать как все работает.
Перейти в начало страницы
+Цитировать сообщение
Гость_wizard993_*
сообщение 2012-02-02, 22:55
Сообщение #5



Гости





Так. Вот мы нажали на ссылку. А что происходит за кулисами? Ну вот всё тот же пример. 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: , но подходы к решению задач интересные :)

Сообщение отредактировал wizard993 - 2012-02-02, 22:57
Перейти в начало страницы
+Цитировать сообщение
Alexander
сообщение 2012-02-03, 15:36
Сообщение #6
Eleanor developer
Иконка группы

Группа: Администраторы
Сообщений: 5 261
Регистрация: 2008-11-11
Из: Николаев
Версия системы: RC5

Репутация:   нет  
Всего: 67


wizard993, для начала расковыряйте файл index.php из корня, там вы найдете первую стадию обработки ссылок: а именно узнавание какой модуль загружать.
Перейти в начало страницы
+Цитировать сообщение
Гость_wizard993_*
сообщение 2012-02-03, 16:26
Сообщение #7



Гости





Alexander, это конечно сильно :) спасибо большое. я просто пока ограничивался строчкой где идёт подключение core.php и дальше смотрел его код. index.php даже не разбирал :( спасибо ещё раз, будем дальше искать и дальше тупить
Перейти в начало страницы
+Цитировать сообщение
Гость_wizard993_*
сообщение 2012-02-04, 13:50
Сообщение #8



Гости





Alexander, код ужасно сложный :crazy: в плане того, что всё настолько взаимосвязано, что просто можно потерятся. :unsure: Одна конструкция перетекает в другую, другая в третью и т.д.
По существу вопроса, нашёл в index.php (тот который в корне) функцию LangNewUrl($url,$l)
там есть кусок кода:
if(!class_exists($c,false))
		include$path.$arr['api'];

Как я понял, он вытягивает поле 'api' из таблицы 'modules' БД и подключает api.php, тот, который лежит в папке модуля. Но это не то что я искал)
Так я и не нашёл эту первую стадию обработки ссылок. :(
Перейти в начало страницы
+Цитировать сообщение
Alexander
сообщение 2012-02-05, 11:00
Сообщение #9
Eleanor developer
Иконка группы

Группа: Администраторы
Сообщений: 5 261
Регистрация: 2008-11-11
Из: Николаев
Версия системы: RC5

Репутация:   нет  
Всего: 67


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);
	...
}


А то, что вы нашли, это код, который отвечает за преобразование ссылок из одного языка в другой. Ведь для разных языковых версий сайта, ссылки на новость так же разные!
Перейти в начало страницы
+Цитировать сообщение
Гость_wizard993_*
сообщение 2012-02-05, 19:45
Сообщение #10



Гости





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

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

когда я не знал, что такое ООП, код казался вообще чудовищным :)
Перейти в начало страницы
+Цитировать сообщение
Alexander
сообщение 2012-02-06, 2:20
Сообщение #11
Eleanor developer
Иконка группы

Группа: Администраторы
Сообщений: 5 261
Регистрация: 2008-11-11
Из: Николаев
Версия системы: RC5

Репутация:   нет  
Всего: 67


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

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

Don53_Empire, ваши сообщения удалены. Для вопросов не касающихся этой темы - создавайте отдельную тему.
Перейти в начало страницы
+Цитировать сообщение
Гость_wizard993_*
сообщение 2012-02-06, 8:19
Сообщение #12



Гости





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

Спасибо. :)

Сообщение отредактировал wizard993 - 2012-02-06, 9:52
Перейти в начало страницы
+Цитировать сообщение

Ответить в данную темуНачать новую тему
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 
RSS Текстовая версия 0.0341 сек.    11 запросов    GZIP включен    Сейчас: 2024-03-29, 14:33