Handler

Материал из Eludia
Перейти к: навигация, поиск

Содержание

Ответ на любой запрос к Eludia-приложению всегда вычисляется одной и той же функцией handler, определённой в ядре. Собственно говоря, ядро Eludia в основном состоит из этой единственной функции + API для разработки callback-процедур, которые она вызывает. Совокупность этих процедур составляет код приложения. В настоящем разделе описывается ход исполнения функции handler и, соответственно, правила написания процедур приложения.

Инициализация

Обработка запроса начинается с создания глобальных переменной %_REQUEST и резервной копии её значения %_REQUEST_VERBATIM.

Далее производится проверка того, загружена ли в память последняя версия файлов приложения и соответствует ли описание схемы данных текущей структуре БД. Если обнаруживается расхождение, версия обновляется и БД приводится в соответствие.

Аутентификация

На данном этапе либо устанавливается глобальная переменная $_USER, которая в дальнейшем служит источником данных о текущем пользователе, либо обработка запроса заканчивается с некоторым специфическим ответом (например, перенаправлением на форму аутентификации).

Всюду ниже предполагается, что пользователь опознан успешно, и, соответственно, $_USER -> {id} — его id в таблице users, $_USER -> {label} — ФИО, прочие поля — соответственно.

Определение раздела приложения

Далее handler вызывает функцию приложения "select_subset_for_$_USER->{role}" или, если таковая не определна, то select_subset. Функция должна быть определена в файле Content/subset.pm.

На выходе ожидается список разделов системы вида

[
 {name => 'admin', label => 'Администрирование'},
 {name => 'docs',  label => 'Документооборот'},
 ...
],

Этот список используется в дальнейшем для формирования одного из элементов интерфейса пользователя: меню нулевого уровня.

Предполагается, что пользователь в каждый момент времени работает в рамках одного из разделов системы. Он может переключать текущий раздел при помощи меню, его выбор записывается в учётной записи и остаётся актуальным в следующей сессии.

А во время первого запроса, когда выбор ещё не может быть сделан, в качестве текущего раздела устанавливается первый из списка.

В дальнейшем символическое имя раздела доступно в качестве значения $_SUBSET -> {name}.

Главное меню и уточнение типа экрана

На следующем шаге handler вызывает функцию приложения "select_menu_for_$_USER->{role}" или, если таковая не определна, то select_menu. Функция должна быть определена в файле Content/menu.pm.

Если система состоит из нескольких разделов, то, как правило, при этом используется $_SUBSET -> {name}. Нередко в таком случае select_menu передаёт вызов "_$_SUBSET->{name}_menu" (_admin_menu, _docs_menu), но это уже компетенция приложения.

На выходе ожидается иерархическое меню раздела, имеющее вид

[
 {name => '_info', label => 'Системная информация'},
 {name => '_',  label => 'Настройка', no_page => 1, items => [
  {name => 'users', label => 'Пользователи'},
  {href => '/?type=roles', label => 'Роли'}, # href может содержать и другие параметры
  ...
 ]},
 ...
],

Этот список используется в дальнейшем для формирования меню. Кроме того, если в запросе не указан параметр $_REQUEST {type}, то в качестве его значения принимается первое по порядку, имеющееся в меню (за исключением фрагментов с опцией no_page). Тип экрана может быть переопределить и явно. В любом случае после вызова select_menu и обработки её результата ядром тип экрана становится определённым.

Выполнение действия

Если запрос содержит параметр $_REQUEST {action}, то система выполняет действие.

Порядок исполнения описан в соответствующем разделе, нижеописанные стадии в этом случае не затрагиваются.

Извлечение данных

Итак, на данном этапе определены переменные $_USER и $_REQUEST {type}, а $_REQUEST {action} имеет пустое значение. Теперь handler извлекает из БД всю информацию, необходимую для отображения на экране запрошенного типа.

При программировании простых справочников (города, типы документов и т. п.) удобно делить экраны на формы (карточки) и списки (реестры, журналы), в то же время относя их к одному типу. Поэтому презентационные (не связанные с действиями) запросы в Eludia делятся на "экраны-формы" и "зкраны-списки" в зависимости от значения параметра $_REQUEST {id} (номер объекта):

  • при пустом $_REQUEST {id} для извлечения данных вызывается процедура "select_$_REQUEST{type}" (например, select_users);
  • при непустом $_REQUEST {id} — вызывается процедура "get_item_of_$_REQUEST{type}" (например, get_item_of_users).

В любом случае процедура должна быть определена в файле Content/$_REQUEST{type}.pm.

Content-процедура обращается к БД и формирует на выходе структуру данных, соответствующую запрошенному экрану, используя при этом Content- и SQL-API. Детали презентации (например, CSS-стили) в этой процедуре вычисляться не должны.

Формирование HTML

Теперь данные полностью подготовлены, осталось только отобразить их. Для этого:

  • при пустом $_REQUEST {id} вызывается процедура "draw_$_REQUEST{type}_for_$_USER->{role}" или, если таковая не определена, то "draw_$_REQUEST{type}" (например, draw_users);
  • при непустом $_REQUEST {id} — соответственно, "draw_item_of_$_REQUEST{type}_for_$_USER->{role}" или, если таковая не определена, то "draw_item_of_$_REQUEST{type}" (например, draw_item_of_users).

В любом случае процедура должна быть определена в файле Presentation/$_REQUEST{type}.pm.

Presentation-процедура получает на выходе в качестве единственного параметра ранее вычисленную структуру данных и возвращает HTML, формируемый, как правило, тремя API-процедурами: draw_table, draw_form и draw_tree. Обращаться к БД и производить какие-либо побочные действия в Presentation-процедурах нельзя.

Завершающая фаза

На этом этапе HTTP-ответ уже отослан и с точки зрения клиента запрос полностью обработан. Однако на стороне сервера, помимо отладочной печати, может произойти ещё одно событие: принудительное завершение текущего процесса. Обычно это имеет смысл в том случае, когда при обработке запроса задействован слишком большой объём памяти, который невозможно вернуть системе иным способом.

В последних версиях Eludia.pm контроль памяти можно вести автоматически, для этого предусмотрен параметр $preconf -> {core_memory_limit}.

Если вам необходима проверка более сложного условия, нежели сравнение результата memory_usage с предельным значением или завершение процесса вообще не связано с объёмом ОЗУ, можно поступить по-старинке: присвоить истинное значение $_REQUEST {__suicide}.

Персональные инструменты
Пространства имён

Варианты
Действия
Навигация
Разработчику
Администратору
Инструменты