Проект ACIS: содержание, old manual.
Частичное описание незаконченых или только запланированных изменений. Документ не полный и не окончательный.
Реформа охватывает или затрагивает:
presenter-data
)Реформа будет сделана в два этапа. Первый этап: в пределах пространства имён ACIS::Web и будет включать в себя реформу структуры user-data, структуры данных, передаваемых презентеру, и элементы работы с сессиями и аутентификации. Второй этап: дальнейшая абстракция и перенос кода в Web::Skeleton (черновое название).
Две основные ветки: owner и records. owner описывает владельца данных, пользователя ACIS. records содержит список записей, принадлежащих пользователю.
Всякая запись представляет собой хэш, и имеет по крайней мере:
Основные ветки: system, request, response. В квадратных скобках - названия соответствующих XSLT переменных. Они должны быть определены в general/pages.xsl и использоваться всеми экранами вместо абсолютных XPath путей.
Добавляем несколько методов для удобства обработчиков. Эти методы
позволят обработчикам писать в соответствующие части
presenter-data
.
Кроме того, что все XSLT презентеры должны быть адаптированы к описанным выше изменениям, есть ещё кое-что:
Сессия содержит всего три стандартных элемента:
Точки добавлены для того, чтобы уменьшить вероятность столкновения имён частных элементов, добавляемых обработчиками, со стандартными.
Каждому из этих элементов соответствует одноимённый read-accessor-метод (но без точки):
my $sid = $session->id;
my $type = $session->type;
my $owner = $session->owner;
my $session = $acis -> create_session( $owner, $type );
$owner
- здесь это ссылка на хэш, содержащий ключи:
name, login, type.
my $session = $acis -> load_session();
или
обработчик ACIS::Web::load_session
В случае, если сессию невозможно загрузить, обработчик сделает
$acis -> clear_process_queue
, и, при необходимости, выставит
соответствующий код ошибки: session-failure.
Как и раньше: my $session = $acis -> session();
$acis -> save_session();
my $userdata = $acis -> authenticate();
или
обработчик ACIS::Web::authenticate
Аутентификация не имеет смысла, если существует и загружена сессия. Функция имеет соответствующую проверку и вернёт 0 в таком случае.
В случае, если аутентификация невозможна, обработчик сделает clear_process_queue, установит ошибку, запустит презентер экрана login или sorry (в зависимости от конкретной ситуации).
Все обработчики получают в качестве параметра главный объект (ACIS::Web) и почти все они используют одни и те же его компоненты. Однако при этом они часто используют разные имена переменных для их обозначения.
Все обработчики должны начинаться именно так:
sub обработчик {
my $app = shift;
my $session = $app -> session;
my $vars = $app -> variables;
my $record = $session -> current_record;
my $config = $app -> config;
my $request = $app -> request;
my $cgi = $request -> {CGI};
Конечно, если какие-то из этих переменных обработчику не нужны, то соответствующие переменные можно опустить.
Ed.Note: дополнения принимаются
Места для дальнейшего развития, абстрактизации — навалом. Главное в нём - не потеряться.
Например, когда понимаешь, что сессии бывают разных типов. В случае ACIS (на текущий момент) сессии бывают двух типов: сессия нового, незарегистрированного пользователя, и сессия известного, зарегистрированного пользователя.
Почему это важно? Потому что некоторые экраны (и обработчики, и презентеры) имеют смысл только в контексте сессии определённого типа. Далее: обработка закрытия сессии полностью зависит от её типа.
Можно сессии разных типов реализовывать разными классами. Создание и закрытие сессии тогда превратились бы в методы класса. Осталось определить интерфейс, и сделать два соответствующих воплощения: ACIS::Web::Session::NewUser, ACIS::Web::Session::User.
Большой смысл есть в том, чтобы основать их на общем классе ACIS::Web::Session, который будучи вполне работоспособным, содержал бы только абстрактную часть работы с сессией. Его, в принципе, можно было бы использовать в случаях, когда экрану нужна сессия, но не важен её тип. (Хотя пока такой экран я даже придумать не могу.)
Основные методы класса (и интерфейса) ACIS::Web::Session: (черновой черновик)
Тогда экраны нового пользователя (кроме new-user/initial) могли бы иметь в своей конфигурации обработчик ACIS::Web::Session::NewUser::load, а экраны зарегистрированного, соответственно, ACIS::Web::Session::User::load.
Однако, на самом деле тогда функция load() перестаёт быть методом класса, так как вызываться она будет вне объектно-ориентированного контекста (то есть просто как функция с одним параметром).
Поэтому полноценного, автоматического наследования от класса ACIS::Web::Session всё-равно не получается. Хотя его можно заменить ручными вызывами.
На самом деле эти факторы важны и для user-data: можно предположить, что они тоже могут быть разных типов. По-крайней мере, если мы хотим разделить общее и ACIS-специфичное, то нужно разделить общее и специфичное в структуре user-data.