Line # Revision Author
1 3 ahitrov@rambler.ru <& "/contenido/components/header.msn" &>
2 <& "/contenido/components/naviline.msn", sect_id => $owner->id &>
3
4 <script type="text/javascript">
5 <!--
6 function set_create_button( oSelect, sBtnID ) {
7 if ( oSelect.value == '' ) {
8 $('#'+sBtnID).attr('disabled','disabled');
9 } else {
10 $('#'+sBtnID).removeAttr('disabled');
11 }
12 }
13 //-->
14 </script>
15
16 <table width="100%" cellspacing="0" cellpadding="0" border="0">
17 <tr valign="top">
18 <td width="35%">
19
20 <& "/contenido/components/subsection.msn", section => $owner &>
21 <& "/contenido/components/class_filter.msn", class=> $class, section => $owner &>
22
23 % if (( $owner->id ) && ($owner->id > 0) )
24 % {
25 <& "/contenido/components/section_info.msn", section => $owner &>
26 % }
27
28 % my @LEFT = $m->comp('components/tasks.msn');
29 % my %LEFTh = map { $_->{attr} => $_ } (@LEFT);
30 % if (ref($request->{tab}->{lefts}))
31 % {
32 % for my $left (@{ $request->{tab}->{lefts} })
33 % {
34 % next if (! exists($LEFTh{$left}));
35 <& '/contenido/components/'.$LEFTh{$left}->{component}, %ARGS &>
36 % }
37 % }
38
39 <!-- ���������� -->
40 <fieldset>
41 <legend>����������</legend>
42 <table width="100%" cellspacing="5" cellpadding="0" class="tform">
43
44 <tr>
45 <th valign=top>1)</th>
46 <td width="100%">
47 ���� � ����� ��������� - ����, ������� �� ������ �������������.<br><br>
48 ����� ����� � ������� ��������� ���������� ��� ��� ��������� ������� - ���� �������� (ctime) � ���� ����������� (mtime).
49 ��� ��������� ���� � �� �� ������ �� �������� (��� �������� ������ ��� ������).
50 </td>
51 </tr>
52
53 </table>
54 </fieldset>
55
56 </td>
57 <td width="2%">&nbsp;</td>
58 <td width="65%">
59
60 % if($owner->id) {
61
62 <fieldset>
63 <legend>���������\
64 % if ($class) {
65 ������ <% $class %>\
66 % if ($use_section) {
67 c ������ ������� ������\
68 % }
69 % } else {
70 � �������\
71 % }
72 % if (!$owner->no_count && $total > 0) {
73 (�����: <% $total %>, �������� � <% $first + 1 %> �� <% ($first + $n > $total) ? $total : $first + $n %>)
74 % } elsif ( $owner->no_count ) {
75 (<span style="color:yellow">��� ���������</span>, �������� � <% $first + 1 %> �� <% $first + scalar @documents %>)
76 % }
77 </legend>
78
79 % if ($total || scalar @documents || defined($alpha) || defined($search) ) {
80 % if ($section_access == 2) {
81 <& "/contenido/components/new_objects_form.msn", proto => 'documents',
82 sect_id => $owner->id,
83 default => ($owner->default_document_class ? $owner->default_document_class : undef) &>
84 % }
85 121 ahitrov <div style="font-size:12px; font-family:Arial;">
86 3 ahitrov@rambler.ru <table border="0" cellspacing="0" cellpadding="2" width="100%" style="margin:4px 0 0; border:1px solid gray;">
87 <tr bgcolor="#e0e0e0"><th colspan="4">����� �� �����:&nbsp;&nbsp;[<a href="?id=<% $id %>" style="font-weight:normal;">����� �������</a>]</th></tr>
88 121 ahitrov <tr><td style="font-size:12px; font-family:Arial; padding:2px 4px;">
89 3 ahitrov@rambler.ru <& /inc/alpha.msn, alpha=>$alpha, params=>\%ARGS, &>
90 </td></tr></table>
91 % ## ����� ������. �������� ��� ���������� ������� ������
92 % ## � ��������� ��� ������ ������� search_fields
93 % ########################################################
94 % if ( $filter{class} ) {
95 % my $document = $filter{class}->new ($keeper);
96 % my @fields = $document->search_fields;
97 % if ( @fields ) {
98 % my @props = $document->required_properties;
99 <form action="sections.html">
100 <table border="0" cellspacing="0" cellpadding="2" width="100%" style="margin:4px 0; border:1px solid gray;">
101 <tr bgcolor="#e0e0e0"><th colspan="4">����� �� ����:&nbsp;&nbsp;[<a href="?id=<% $id %>" style="font-weight:normal;">����� �������</a>]</th></tr><tr>
102 <td width="1%" nowrap style="padding:2px 0 2px 4px;"><select name="search_by">
103 % foreach my $field ( @fields ) {
104 % my ($prop) = grep { $_->{'attr'} eq $field } @props;
105 % my $selected = $field eq $search_by ? ' selected' : '';
106 <option value="<% $field %>"<% $selected %>><% ref $prop ? $prop->{'shortname'} || $prop->{'rusname'} : $field %>
107 % }
108 </td><td width="0">:</td>
109 <td width="98%"><input type="text" name="search" value="<% $search %>" style="width:100%"></td>
110 <td width="1%" style="padding:2px 4px 2px 0;"><input type="submit" value=" &raquo; " style="border:1px solid gray;"></td>
111 </tr></table>
112 % if ( $id ) {
113 <input type="hidden" name="id" value="<% $id %>">
114 % }
115 % if ( $class ) {
116 <input type="hidden" name="class" value="<% $class %>">
117 % }
118 % if ( $use_section ) {
119 <input type="hidden" name="use_section" value="<% $use_section %>">
120 % }
121 </form>
122 % }
123 % }
124
125 <div style="height:5px"><spacer type="block" height="5"></div>
126 % if ( $owner->no_count ) {
127 <& /inc/pages_nocount.msn, p=>$p, n=>$n, found=> scalar @documents, href=>'sections.html', params=>\%ARGS, size => 15 &>
128 % } else {
129 <& /inc/pages_.msn, p=>$p, n=>$n, total=>$total, href=>'sections.html', params=>\%ARGS, &>
130 % }
131 </div>
132
133 <& /contenido/components/section_browse.msn, documents => \@documents, columns => \@columns, section => $owner, filter => \%filter_params, %ARGS &>
134
135 121 ahitrov <div style="font-size:12px; font-family:Arial;">
136 3 ahitrov@rambler.ru % if ( $owner->no_count ) {
137 <& /inc/pages_nocount.msn, p=>$p, n=>$n, found=> scalar @documents, href=>'sections.html', params=>\%ARGS, size => 15 &>
138 % } else {
139 <& /inc/pages_.msn, p=>$p, n=>$n, total=>$total, href=>'sections.html', params=>\%ARGS, &>
140 % }
141 <div style="height:5px"><spacer type="block" height="5"></div>
142 </div>
143
144 % } else {
145 <h4 align="center"><i>---- ��� ���������� -----</i></h4>
146 % }
147 %
148 % if ($section_access == 2) {
149 <& "/contenido/components/new_objects_form.msn", proto => 'documents',
150 sect_id => $owner->id,
151 default => ($owner->default_document_class ? $owner->default_document_class : undef) &>
152 % }
153
154 </fieldset>
155 </td>
156 </tr>
157 </table>
158
159 % }
160
161 </body>
162 </html>
163 <%args>
164
165 $id => undef
166 $p => 1
167 $class => undef
168 $use_section => undef
169 $alpha => undef
170 $alpha_search => undef
171 $search_by => undef
172 $search => undef
173 $update => undef
174 $delete => undef
175
176 </%args>
177 <%init>
178
179 $id = 0 if $id =~ /\D/;
180 my $owner;
181
182 # ��������...
183 if ($id && ($id > 0))
184 {
185 $owner = $keeper->get_section_by_id($id);
186 }
187 if (! ref($owner))
188 {
189 return undef;
190 }
191
192 my %filter_params;
193 $filter_params{use_section} = $use_section if $use_section;
194 $filter_params{class} = $class if $class;
195 $filter_params{alpha} = $alpha if $alpha;
196 $filter_params{alpha_search} = $alpha_search if $alpha_search;
197 $filter_params{search_by} = $search_by if $search_by;
198 $filter_params{search} = $search if $search;
199 $filter_params{p} = $p if $p > 1;
200 $filter_params{s} = $id if $id;
201
202 # ������� �������� � ����� ������...
203 my $filter = $m->comp('/contenido/components/context.msn', name => 'filter');
204 my $profile = $m->comp('/contenido/components/context.msn', name => 'profile');
205
206 unless (defined $request->{section_accesses}->{$id})
207 {
208 $request->{section_accesses}->{$id} = $user->get_section_access($id);
209 }
210 my $section_access = $request->{section_accesses}->{$id};
211
212 my (@documents, $total);
213
214 my $s = $owner->id;
215 my $sorted = $owner->_sorted();
216 $s .= ",$filter" if ($filter > 0);
217
218 if ($update) {
219 my $return_params = join ('&', map { $_.'='.$filter_params{$_} } grep { $_ ne 's' } keys %filter_params );
220 my %updated;
221 while ( my ($field, $value) = each %ARGS ) {
222 if ( $field =~ /^update_(\d+)_(\w+)$/ ) {
223 my $oid = $1;
224 my $attr = $2;
225 $updated{$oid}{$attr} = $value;
226 }
227 }
228 my %classes = map { $_->{class} => 1 } values %updated;
229 foreach my $update_class ( keys %classes ) {
230 my @ids;
231 while ( my ($oid, $attr) = each %updated) {
232 push @ids, $oid if $attr->{class} eq $update_class;
233 }
234 my @objects = $keeper->get_documents (
235 id => \@ids,
236 class => $update_class
237 ) if @ids;
238 foreach my $object ( @objects ) {
239 my $document_access = $user->section_accesses($user, $object->section);
240 next unless $document_access == 2;
241 my $fields = $updated{$object->id};
242 my @props = grep { exists $_->{inline} && $_->{inline} } $object->structure;
243 if ( ref $fields eq 'HASH' ) {
244 foreach my $prop ( @props ) {
245 my $attr = $prop->{attr};
246 my $value = ref $fields && exists $fields->{$attr} ? $fields->{$attr} : undef;
247 if ( $prop->{db_type} eq 'float' ) {
248 for ( $value ) {
249 s/\,/\./;
250 s/^\s+//;
251 s/\s+$//;
252 }
253 }
254 if ( $prop->{type} eq 'checkbox' ) {
255 $value = $value ? 1 : undef;
256 }
257
258 $object->$attr($value);
259 }
260 $object->store;
261 }
262 }
263 }
264 $m->redirect("sections.html?id=".$id.($return_params ? '&'.$return_params : ''));
265 }
266 if ( $delete ) {
267 my $return_params = join ('&', map { $_.'='.$filter_params{$_} } grep { $_ ne 's' } keys %filter_params );
268 my %deleted;
269 while ( my ($field, $value) = each %ARGS ) {
270 if ( $field =~ /^delete_(\d+)_(\w+)$/ ) {
271 my $oid = $1;
272 my $attr = $2;
273 $deleted{$oid}{$attr} = $value;
274 }
275 }
276 my %classes = map { $_->{class} => 1 } values %deleted;
277 foreach my $delete_class ( keys %classes ) {
278 my @ids;
279 while ( my ($oid, $attr) = each %deleted) {
280 push @ids, $oid if exists $attr->{id} && $attr->{id} && ($attr->{class} eq $delete_class);
281 }
282 my @objects = $keeper->get_documents (
283 id => \@ids,
284 class => $delete_class
285 ) if @ids;
286 foreach my $object ( @objects ) {
287 my $document_access = $user->section_accesses($user, $object->section);
288 next unless $document_access == 2;
289 $object->delete;
290 }
291 }
292 $m->redirect("sections.html?id=".$id.($return_params ? '&'.$return_params : ''));
293 }
294
295 my %filter=();
296 132 ahitrov my $nothing_found = 0;
297 3 ahitrov@rambler.ru my %order = (not $class and $owner->order_by) ? (order_by => $owner->order_by) : (order => ['date','direct']);
298 if (defined $alpha and $alpha ne '') {
299 $filter{ilike}=1;
300 $filter{ $alpha_search || 'name' }="$alpha%";
301 $order{order}=['name','reverse'];
302 delete $order{order_by};
303 }
304 if ( $class ) {
305 $filter{class} = $class;
306 } elsif ( $owner->default_document_class ) {
307 $filter{class} = $owner->default_document_class;
308 } elsif ( $owner->default_table_class ) {
309 $filter{table} = $owner->default_table_class;
310 }
311 $filter{s}=$s unless ($class && !$use_section);
312 if ( $search_by && defined $search ) {
313 my $doc_class = $class || $owner->default_document_class;
314 if ( $doc_class ) {
315 my @props = $doc_class->new( $keeper )->structure();
316 my ($prop) = grep { $_->{attr} eq $search_by } @props if @props;
317 132 ahitrov if ( ref $prop && ($prop->{type} eq 'integer' || $prop->{type} eq 'checkbox' ||
318 (($prop->{type} eq 'pickup' || $prop->{type} eq 'lookup') && $search =~ /^\d+$/) ) ) {
319 3 ahitrov@rambler.ru $filter{$search_by} = int($search);
320 132 ahitrov } elsif ( ref $prop && ($prop->{type} eq 'pickup' || $prop->{type} eq 'lookup') && $search =~ /\D/ ) {
321 my $lookup_opts = $prop->{lookup_opts};
322 if ( ref $lookup_opts && exists $lookup_opts->{class} ) {
323 my $search_field = exists $lookup_opts->{search_by} ? $lookup_opts->{search_by} : 'name';
324 my @ids = $keeper->get_documents (
325 ids => 1,
326 class => $lookup_opts->{class},
327 ilike => 1,
328 $search_field => '%'.$search.'%',
329 );
330 if ( @ids ) {
331 $filter{$search_by} = \@ids;
332 } else {
333 $nothing_found = 1;
334 }
335 }
336 3 ahitrov@rambler.ru } else {
337 $filter{$search_by}='%'.$search.'%';
338 $filter{ilike} = 1;
339 }
340 } else {
341 $filter{$search_by}='%'.$search.'%';
342 $filter{ilike} = 1;
343 }
344 }
345
346 132 ahitrov # �������������� ������� �������
347 if ($owner->filters) {
348 no strict 'vars';
349 my $filters = eval($owner->filters);
350 if ($@) {
351 warn "Bad filter: " . $owner->filters . " in section " . $owner->id;
352 } elsif (ref $filters eq 'HASH') {
353 while ( my ($key, $val) = each %$filters ) {
354 $filter{$key} = $val;
355 }
356 }
357 }
358 3 ahitrov@rambler.ru
359 $total = $keeper->get_documents(%filter, count=>1) unless $owner->no_count;
360
361 my $n = 40;
362 my $first = $n * ($p - 1);
363 ($first,$p)=(0,0) if (!$owner->no_count && $first>$total);
364
365 132 ahitrov unless ( $nothing_found ) {
366 if ($class && !$use_section) {
367 @documents = $keeper->get_documents(%filter, %order, limit=>$n, offset=>$first);
368 } elsif ($sorted) {
369 @documents = $keeper->get_sorted_documents(%filter, limit=>$n, offset=>$first);
370 } else {
371 @documents = $keeper->get_documents(%filter, %order, limit=>$n, offset=>$first);
372 }
373 3 ahitrov@rambler.ru }
374
375 # ����� ������� ������� ����������...
376 132 ahitrov my @columns = $sorted ? ({attr => '_sort_', name => 'N'}) : ();
377 3 ahitrov@rambler.ru
378 132 ahitrov # �������� ����� �������, ������� �������� ��� ������� �������� (required_properties -> column)...
379 if ($filter{class} or @documents and $documents[0]) {
380 push @columns,
381 sort {$a->{column} <=> $b->{column}}
382 grep {$_->{column}} ($filter{class} ? $filter{class}->new($keeper)->structure : $documents[0]->structure);
383 }
384 3 ahitrov@rambler.ru
385 132 ahitrov # ����������� ����� �������...
386 @columns = (@columns,
387 {attr => '_act_', rusname => '��������'},
388 );
389
390 3 ahitrov@rambler.ru </%init>

Небольшая справка по веткам

cnddist – контейнер, в котором хранятся все дистрибутивы всех библиотек и программных пакетов, которые использовались при построении различных версий Contenido. Если какой-то библиотеки в данном хранилище нет, инсталлятор сделает попытку "подтянуть" ее с веба (например, с CPAN). Если библиотека слишком старая, есть очень большая вероятность, что ее там уже нет. Поэтому мы храним весь хлам от всех сборок. Если какой-то дистрибутив вдруг отсутствует в cnddist - напишите нам, мы положим его туда.

koi8 – отмирающая ветка, чей код, выдача и все внутренние библиотеки заточены на кодировку KOI8-R. Вносятся только те дополнения, которые касаются внешнего вида и функционала админки, баги ядра, обязательные обновления портов и мелочи, которые легко скопипастить. В дальнейшем планируется полная остановка поддержки по данной ветке.

utf8 – актуальная ветка, заточенная под UTF-8.

Внутри каждой ветки: core – исходники ядра; install – скрипт установки инсталляции; plugins – плагины; samples – "готовые к употреблению" проекты, которые можно поставить, запустить и посмотреть, как они работают.