view Lib/IMPL/Web/Application/ControllerUnit.pm @ 111:6c25ea91c985

ControllerUnit concept
author wizard
date Tue, 18 May 2010 01:33:37 +0400
parents c13a215508ca
children 0ed8e2541b1c
line wrap: on
line source

package IMPL::Web::Application::ControllerUnit;

use base qw(IMPL::Object);

use IMPL::Class::Property;

BEGIN {
	public property action => prop_get | owner_set;
	public property application => prop_get | owner_set;
	public property query => prop_get | owner_set;
	public property formData => prop_get | owner_set;
	public property formSchema => prop_get | owner_set;
	public property formErrors => prop_get | owner_set;
}

sub CTOR {
	my ($this,$action) = @_;
	
	$this->action($action);
	$this->application($action->application);
	$this->query($action->query);
}

sub InvokeAction {
	my ($self,$method,$action) = @_;
	
	if ($self->can($method)) {
		my $unit = $self->new($action);
		$unit->$method();
	} else {
		die new IMPL::InvalidOperationException("Invalid method call",$self,$method);
	}
}

1;

__END__

=pod

=head1 NAME

C<IMPL::Web::Application::ControllerUnit> - базовый класс для обработчика транзакций в модели контроллера.

=head1 DESCRIPTION

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

Перед выполнением транзакции создается экземпляр объекта, в рамках которого будет выполнена транзакция.
Для этого вызывается метод C<InvokeAction($method,$action)>, который создает/восстанавливает контекст
транзакции.

Транзакции на данный момент делятся на простые и формы.

=head2 Простые транзакции

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

=head2 Формы

При использовании форм запрос предварительно обрабатывается, для получения DOM документа с данными формы.
Для постороенния DOM документа используется схема. При этом становятся доступны дополнительные свойства
C<formData>, C<formSchema>, C<formErrors>.

Результат выполнения транзакции не возвращается напрямую пользователю, а включается в общий ответ, который
выглядит следующим образом

=begin code

{
	state => '{ new | correct | invalid }',
	result => $transactionResult,
	formData => $formDOM,
	formSchema => $formSchema,
	formErrors => @errors
}

=end code

=over

=item C<state>

Состояние верификации формы.

=over

=item C<new>

Первоначальное содержимое формы, оно может быть некорректным, но это нормально.
В данном состоянии транзакция обычно не выполняется.

=item C<correct>

Данные формы корректны, транзакция выполнена, и ее результат доступен через поле C<result>

=item C<invalid>

Содержимое формы не прошло верификацию, ошибки доступны через поле C<formErrors>. Транзакция
не выполнялась.

=back

=item C<result>

Результат выполнения транзакции, если конечно таковая выполнялась.

=item C<formData>

ДОМ документ с данными формами. Документ существует всегда, не зависимо от его корректности,
может быть использован для построения формы, уже заполненную параметрами.

=item C<formSchema>

Схема данных формы, может использоваться для построения динамических форм.

=item C<formErrors>

Ошибки верификации данных, если таковые были

=back

=head1 MEMBERS

=over

=item C<[get] application>

=item C<[get] query>

=item C<[get] response>

=item C<[get] formData>

=item C<[get] formSchema>

=item C<[get] formErrors>

=item C<InvokeAction($method,$action)>

Конструирует контекст выполнения транзакции, может быть переопределен для конструирования контекста по
своимправилам. 

=back

=head1 EXAMPLE

=begin code

package MyBooksUnit;
use strict;
use base qw(IMPL::Web::Application::ControllerUnit);

__PACKAGE__->PassThroughArgs;

__PACKAGE__->transactions(qw(
	find 
	info
));
__PACKAGE__->forms(
	create => 'books.create.xml'
);

sub find {
	my ($this) = @_;
	
	return $this->application->dataSource->resultset('Books')->find({author => $this->query->param('author')});
}

sub info {
	my ($this) = @_;
	
	return $this->application->dataSource->resultset('Books')->find({id => $this->query->param('id')});
}

sub create {
	my ($this) = @_;
	
	my %book = map {
		$_ => $this->formData->selectSingleNode($_)->nodeValue
	} qw(author_id title year ISBN);
	
	return $this->application->datasource->resultset('Books')->create(\%book);
}

=end code

=cut