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;