Line # Revision Author
1 3 ahitrov@rambler.ru package Contenido::Init;
2
3 # ----------------------------------------------------------------------------
4 # ����� ����� ��������� ��� ���������������� ������ Contenido...
5 # ��� �� ������, ��� ������ ����� � �����������...
6 # ----------------------------------------------------------------------------
7
8 use strict;
9 use warnings;
10 use locale;
11
12 use vars qw($VERSION);
13 $VERSION = '4.1';
14
15 # ����������� �������... �����...
16 use Utils;
17 use IO::File;
18 use Image::Size;
19 use Data::Dumper;
20 use Convert::Cyrillic;
21 use POSIX qw(:locale_h);
22
23
24 # ����������� ������� Contenido...
25 use Contenido::Globals;
26 use Contenido::Logger;
27 use Contenido::User;
28 use Contenido::Project;
29 use Contenido::Request;
30 use Contenido::State;
31 use Contenido::Document;
32 use Contenido::Link;
33 use Contenido::Section;
34 use Contenido::Keeper;
35 use Contenido::Image;
36 # ���� ������
37 use Contenido::Type::File;
38
39 # ��������� ���������� ��������� ��������� Contenido/ElTexto/Arte
40 # �� ���� ������ ��� ������ ���������, ���� ����� �������������� �������������� ����������.
41 sub module_structure {
42 return (
43 ['documents', '������ ����������', 'Contenido::Document'],
44 ['sections', '������ ������', 'Contenido::Section'],
45 ['users', '������ �������������', 'Contenido::User'],
46 ['links', '������ ������', 'Contenido::Link'],
47 );
48 }
49
50
51 sub init {
52 warn "Contenido Init: ������������� Contenido\n" if $DEBUG;
53
54 my $R = contenido_init();
55
56 if ($state->locale) {
57 setlocale(LC_COLLATE, $state->locale);
58 setlocale(LC_CTYPE, $state->locale);
59 }
60
61 $keeper = Contenido::Keeper->new($state);
62 # ���� �� ����� keepalive ����� ����� ����������� � �����, ���� ��� ������������ ��������
63 unless ($state->db_type eq 'none') {
64 $keeper->db_connect unless $keeper->is_connected;
65 }
66
67 $log->info("�������� ������� Contenido::Project") if $DEBUG;
68 $project = Contenido::Project->new($state);
69
70 $R += plugins_load();
71 $R += modules_load();
72 utils_load();
73
74 init_classes();
75 clear_not_available();
76
77 # PREAMBLE_HANDLER stuff - load and initialize
78 #
79 if ( $state->{preamble_handler} ) {
80 my $module = $state->{preamble_handler}; # main preamble hanler
81 my $path = $state->{preamble_handler_path}; # extra preamble handlers relative path
82 eval "use $module";
83 if ( $@ ) {
84 $R++; $log->error("Cannot load module $module because of '$@'");
85 }
86 $state->{preamble_handler_obj} = $module->new( $path ? (load_modules => $path) : () );
87 }
88
89 unless ($state->db_type eq 'none') {
90 $keeper->shutdown;
91 }
92
93 if ($R) {
94 $log->error("��� ������������� Contenido ��������� ������ (���������� - $R)") if $DEBUG;
95 } else {
96 $log->info("������������� Contenido ������ �������") if $DEBUG;
97 }
98
99 return ($R ? 1 : 0);
100 }
101
102 sub init_classes {
103 foreach (&module_structure, ['locals', '��������� ������', $keeper->state()->project() ]) {
104 my $tag = $_->[0];
105 $state->{'available_'.$tag} ||= [];
106 if (ref($state->{'available_'.$tag}) eq 'ARRAY') {
107 foreach my $class (@{$state->{'available_'.$tag}}) {
108 $class->class_init;
109 }
110 } else {
111 $log->error("Wrong structure in \$state->{available_$tag} (".$state->{'available_'.$tag}."), must be ARRAY REF");
112 die;
113 }
114 }
115 }
116
117 sub clear_not_available {
118 foreach (&module_structure, ['locals', '��������� ������', $keeper->state()->project() ]) {
119 my $tag = $_->[0];
120 next unless ref $state->{'available_'.$tag} eq 'ARRAY';
121 for (my $i = 0; $i <= $#{$state->{'available_'.$tag}} ; $i++) {
122 my $class = $state->{'available_'.$tag}->[$i];
123 unless ($class->contenido_is_available) {
124 splice(@{$state->{'available_'.$tag}}, $i--, 1);
125 $log->debug('������ ����� ' . $class . ' �� $state->{available_' . $tag . '}') if $DEBUG;
126 }
127 }
128 }
129 }
130
131 sub load_classes {
132 shift;
133 for (@_) {
134 eval "use $_";
135 #����� ������ eval ���� �� ��������� ����� $@ ?
136 $log->error("Cannot load class $_ because of $@") if ($@);
137 if ($_->can('class_init')) {
138 eval {$_->class_init};
139 $log->error("Error on class_init for class $_ because of $@") if ($@);
140 }
141 $log->info("�������� ����� $_") if $DEBUG;
142 }
143 }
144
145 sub plugins_load {
146 my $LR = 0;
147
148 # ----------------------------------------------------------------------------
149 # ������ ��� ���� ���������� ��� ��������� ������...
150 for my $plugin ($state->project, split(/\s+/, $state->plugins)) {
151 my $class = $plugin.'::Init';
152 eval ("use $class");
153 $log->error("������ ��� �������� ������.\n$@!") if $@;
154
155 {
156 package HTML::Mason::Commands;
157 eval ("use $class");
158 }
159
160
161 if ( $@ ) {
162 $log->error("�� ���� ���������� ������ $plugin (������������� $class) �� ������� '$@'");
163 $LR++;
164 } else {
165 $log->info("�������� ����� $class ��� ������� $plugin") if $DEBUG;
166 eval {
167 $LR += $class->init( $keeper );
168 };
169 if ( $@ ) {
170 $log->error("�� ���� ��������� ������������� ������� $plugin (������������� $class) �� ������� '$@'");
171 $LR++;
172 }
173 }
174 }
175
176 return $LR;
177 }
178
179 sub utils_load {
180 Utils::load_modules( ['Utils::HTML'] );
181 }
182
183
184 sub modules_load {
185 my $path = __FILE__;
186 $path =~ s|/[^/]*$||;
187 $path =~ s|/Contenido$||;
188
189 my $LR = 0;
190
191 my @ms = ();
192
193 # ��������� �������� ��������� �������...
194 push (@ms, ['locals', '��������� ������', $keeper->state()->project() ] );
195
196
197 foreach my $ms (@ms) {
198 $log->info("���������� ".$ms->[1]) if $DEBUG;
199
200 my $pathlib = $path.'/'.$ms->[2];
201 $pathlib =~ s|::|/|gi;
202 if (! -s $pathlib) {
203 $log->warning("���������� ${pathlib} �� ����������. ���������!");
204 } else {
205 opendir(DIR, $pathlib) || do { $log->error("�� ���� ������� ���������� ${pathlib} ��� ����������� �������"); die };
206 my @modules = grep {/\.pm$/} readdir(DIR);
207 closedir(DIR);
208
209 foreach my $module (@modules) {
210 $module =~ s/\.pm$//;
211
212 my $class = $ms->[2]."::".$module;
213
214 eval("
215 package TestPackage::$class;
216 use $class;
217 1;
218 ");
219
220 if ( $@ ) {
221 $log->error("�� ���� ���������� ������ $module (����� $class) �� ������� '$@'");
222 $LR++;
223 } else {
224 $log->info("�������� ����� $class") if $DEBUG;
225 next unless $class->isa('Contenido::Object');
226 foreach (&module_structure()) {
227 my ($tag, $name, $proto) = @$_;
228 if ($class->isa($proto)) {
229 push (@{ $state->{'available_'.$tag} }, $class);
230 $log->info("����� $class ���� $name '".$class->class_name()."' (�������� $proto)") if $DEBUG;
231 }
232 }
233 }
234 }
235 }
236 }
237
238 # ��� �������� ���������� ��� ������� - Contenido::User, Contenido::Section... ������ ������� �� � ������ ������������
239 push (@{ $state->{'available_sections'} }, 'Contenido::Section');
240 push (@{ $state->{'available_users'} }, 'Contenido::User');
241 push (@{ $state->{'available_links'} }, 'Contenido::Link');
242
243 return $LR;
244 }
245
246 # �������� �������� Contenido...
247 sub contenido_init {
248 warn "Contenido Init: �������� ������� Contenido::State\n" if $DEBUG;
249 $state = Contenido::State->new();
250 $log = Contenido::Logger->new(
251 log_format => $state->{__debug_format__} || '%d %C:%L (%P) [%l]: "%m"%n',
252 max_level => $state->{__debug_max_level__} || 'emergency',
253 min_level => $state->{__debug_min_level__} || 'debug',
254 stack_trace => $state->{__debug_stack_trace__} || 0,
255 );
256
257 return 1 unless ref $state && ref $log;
258 $log->info("������ ������ Contenido::Logger") if $DEBUG;
259
260 $state->debug($DEBUG);
261 $state->info() if $DEBUG;
262
263 return 0;
264 }
265
266 1;
267