Revision 3 (by ahitrov@rambler.ru, 2010/03/24 15:19:32) |
The CORE
|
package Contenido::MVC::MasonHandler;
use strict;
use base 'HTML::Mason::ApacheHandler';
use Contenido::Globals;
use Data::Dumper;
use Contenido::MVC::Dispatcher;
use HTTP::Status;
use Apache::Request;
sub new {
my $proto = shift;
my %opts = @_;
my $class = ref($proto) || $proto;
my $dispatcher_class = $opts{controller_dispatcher_class} || 'Contenido::MVC::Dispatcher';
my $controller_class = $opts{controller_class} || 'Contenido::MVC::Controller';
my $controller_main_class = $opts{controller_main_class} || 'Contenido::MVC::Controller';
# �������� ����� �����������
foreach (keys %opts) {
delete $opts{$_} if $_ =~ /^controller/i;
}
my $self = $proto->SUPER::new( %opts );
$self->set_dispatcher( $dispatcher_class->init( controller_class => $controller_class ) );
$self->get_dispatcher()->set_main_controller( controller_class => $controller_main_class );
return $self;
}
sub request_args {
my $self = shift;
my %args = $request->get_args();
if ($request->{'_mason_request_args_'} && ref $request->{'_mason_request_args_'} eq 'HASH') {
map { $args{ $_ } = $request->{'_mason_request_args_'}{$_} } keys %{ $request->{'_mason_request_args_'} };
}
return (\%args, $request->r(), undef);
}
sub get_dispatcher {
my $self = shift;
return $self->{dispatcher};
}
sub set_dispatcher {
my $self = shift;
$self->{dispatcher} = shift;
}
# ���������� �������
sub handle_request {
my $self = shift;
my $r = shift;
my $apr = $request->r();
my ($comp, $response);
# ���������� action
my $action = $self->get_dispatcher()->get_action( $apr );
# TODO: ������-�� ��� ������� ��������� ��� -
# $self->get_dispatcher()->get_main_controller()->prepare_request( $apr ) if $apr->is_initial_req();
# ��� �������� ��������� 504 ������ ��� ��������� � http://planeta.rambler.ru/
# ��� ������ index.html �������� ������ �� ����������...
$self->get_dispatcher()->get_main_controller()->prepare_request( $apr );
# ���������� begin
$self->get_dispatcher()->get_main_controller()->begin( $action );
if ($self->get_dispatcher()->get_main_controller()->is_response()) {
$comp = $self->get_dispatcher()->get_main_controller()->{comp};
$response = $self->get_dispatcher()->get_main_controller()->get_response();
return $self->mason_handle_request( $apr, $response, $comp );
}
if ($action) {
# ��������� request
$self->get_dispatcher()->get_controller( $action )->prepare_request( $apr );
# ����������
$self->execute($action);
# ��������� mason %ARGS
$self->get_dispatcher()->get_controller( $action )->set_mason_args();
$comp = $self->get_dispatcher()->get_controller( $action )->{comp};
$response = $self->get_dispatcher()->get_controller( $action )->get_response();
}
# ���������� end
$self->get_dispatcher()->get_main_controller()->end( $action );
if ($self->get_dispatcher()->get_main_controller()->is_response()) {
$comp = $self->get_dispatcher()->get_main_controller()->{comp};
$response = $self->get_dispatcher()->get_main_controller()->get_response();
return $self->mason_handle_request( $apr , $response, $comp );
}
if ($action && $self->get_dispatcher()->get_controller( $action )->is_response()) {
$comp = $self->get_dispatcher()->get_controller( $action )->{comp};
$response = $self->get_dispatcher()->get_controller( $action )->get_response();
return $self->mason_handle_request( $apr , $response, $comp );
}
return $self->mason_handle_request( $apr, $response, $comp );
}
# mason handle_request
sub mason_handle_request {
my $self = shift;
my $apr = shift;
my $status = shift;
my $comp = shift;
if (defined $status) {
return $status;
}
# ��������� ����������� ����������
if ($comp) {
my $interp = $self->interp;
foreach (map $_->[1], $interp->comp_root_array) {
if (-e $_.$comp) {
$apr->filename($_.$comp);
last;
}
}
}
return $self->SUPER::handle_request( $apr );
}
# ���������� ��������� �����������, ����������� �� ������ ����
sub execute {
my $self = shift;
my $action = shift;
return undef unless $action && ref($action) && $action->{'sub'};
my $method = $action->{'sub'};
my $begin_method = exists $action->{'begin'} ? $action->{'begin'} : 'begin';
my $end_method = exists $action->{'end'} ? $action->{'end'} : 'end';
if ($begin_method) {
$self->get_dispatcher()->get_controller( $action )->$begin_method( $action );
}
if ($self->get_dispatcher()->get_controller( $action )->is_response()) {
return undef;
}
$self->get_dispatcher()->get_controller( $action )->$method( $action );
if ($end_method) {
$self->get_dispatcher()->get_controller( $action )->$end_method( $action );
}
return undef;
}
1;