Line # Revision Author
1 3 ahitrov@rambler.ru package Contenido::MVC::Dispatcher;
2
3 use strict;
4 use Utils;
5 use Data::Dumper;
6
7 # ���� ����������� (��������� ����, ������� ����)
8 my @DISPATCH_TYPES = qw(Path Regex);
9
10 sub init {
11 my $proto = shift;
12 my %opts = @_;
13 my $class = ref($proto) || $proto;
14
15 my $self = {};
16 bless $self, $class;
17
18 $self->load_dispatch_types( %opts );
19 $self->load_actions( %opts );
20
21 return $self;
22 }
23
24 # ������ ��������� �����������
25 sub get_dispatch_types {
26 return @DISPATCH_TYPES;
27 }
28
29 # �������� ����� �����������
30 sub load_dispatch_types {
31 my $self = shift;
32
33 foreach my $typename ( $self->get_dispatch_types() ) {
34
35 my $class = 'Contenido::MVC::DispatchType::'.$typename;
36 Utils::load_modules( [ $class ] );
37 $self->{dispatch_types}->{ $typename } = new $class;
38
39 }
40
41 }
42
43 # �������� actions �����������
44 sub load_actions {
45 my $self = shift;
46 my %opts = @_;
47
48 my $controller_class = $opts{controller_class};
49 $controller_class = [ $controller_class ] unless ref($opts{controller_class}) eq 'ARRAY';
50
51 Utils::load_modules( $controller_class );
52
53 foreach my $class (@$controller_class) {
54
55 # ���������� �����������
56 my $controller = $class->init();
57 $self->register_controller( $controller );
58
59 foreach my $typename ( $self->get_dispatch_types() ) {
60
61 my $dispatch_type = $self->{dispatch_types}->{ $typename };
62
63 my $method = 'get_'.lc($typename).'_actions';
64 my $actions = $controller->$method;
65
66 next unless $actions && ref($actions) eq 'ARRAY';
67
68 foreach my $action (@$actions) {
69 next unless $action && ref($action) eq 'HASH';
70
71 # ���������� ������ �� ������������ ����������� ������ action
72 $action->{'controller_class'} = $class;
73
74 # �������� �� ��, ����� �� ���� �������� �����
75 next unless $controller->can( $action->{'sub'} );
76
77 # ����������� ������
78 $dispatch_type->register( $action );
79 }
80
81 }
82 }
83
84 # ���� ��������� (������ ����������� ��� ���������� ������� � ����������)
85 # � �������: ���� �� �������� ����������� ���� ������� � 10 ���,
86 # ��� ����� � �������������� ��������� sorder ����� ������� ��������� ���������
87 # ����������, ������� � 0 - ������������
88
89 foreach my $typename ( $self->get_dispatch_types() ) {
90 my $dispatch_type = $self->{dispatch_types}->{ $typename };
91 $dispatch_type->after_register();
92 }
93
94 return 1;
95 }
96
97 # ����������� �����������
98 sub register_controller {
99 my $self = shift;
100 my $controller = shift;
101
102 my $class = ref($controller);
103 $self->{controllers}->{$class} = $controller;
104 }
105
106 # ��������� ����������� � ����������� �� action
107 sub get_controller {
108 my $self = shift;
109 my $action = shift;
110
111 my $controller = $self->{controllers}->{ $action->{'controller_class'} };
112 $controller->set_action( $action );
113 return $controller;
114 }
115
116
117 # ��������� �������� ����������
118 sub get_main_controller {
119 my $self = shift;
120 return $self->{controllers}->{'main'};
121 }
122
123 # ��������� �������� �����������
124 sub set_main_controller {
125 my $self = shift;
126 my %opts = @_;
127 my $controller = $opts{controller_class}->init();
128 $self->{controllers}->{'main'} = $controller;
129 }
130
131 # ���������� action
132 sub get_action {
133 my $self = shift;
134 my $r = shift;
135
136 my $path = $r->uri();
137 $path =~ s/\/+/\//;
138 $path =~ s/index\.\w+$//i;
139
140 my $action = undef;
141
142 # �������� �� ���� ����� �����������
143 DP: foreach my $typename ( $self->get_dispatch_types() ) {
144
145 my $dispatch_type = $self->{dispatch_types}->{ $typename };
146 if ($action = $dispatch_type->match( $path )) {
147 last DP;
148 }
149 }
150 return $action;
151 }
152
153 1;
154