Revision 195
Date:
2012/03/15 18:26:13
Author:
ahitrov
Revision Log:
Users plugin
Files:
Legend:
Added
Removed
Modified
koi8/plugins/users/comps/contenido/users/autohandler
1
<%init>
2
3
$r->content_type('text/html');
4
$m->call_next();
5
6
</%init>
koi8/plugins/users/comps/contenido/users/components/__section_tree__.msn
1
%# vim:syn=mason:
2
% users_index_tree( $sect, 0, \$line, $level, $mode, $profile, $width_limit, $root );
3
<%args>
4
5
$root => 1
6
$level => 3
7
$mode => 1
8
$width_limit => undef
9
10
</%args>
11
<%init>
12
my $profile = $m->comp('/contenido/components/context.msn', name => 'profile');
13
14
sub users_index_tree
15
{
16
my ($sect, $offset, $line_ref, $count_offset, $viewmode, $profile, $width_limit, $root) = @_;
17
my $section_access = $user->section_accesses($user, $sect->{id});
18
19
my $spacer = '';
20
for(my $c=1; $c<$offset; $c++)
21
{
22
$spacer = $spacer.(($c == $offset-1) ? ' » ' : ' ');
23
}
24
if( $sect->{id} && ($sect->{id} != 1) && ($offset != 0) && $section_access > 0)
25
{
26
$$line_ref++;
27
28
my $href = 'sections.html?id='.$sect->id;
29
30
my $sname = $sect->name();
31
$sname = substr($sname, 0, $width_limit - $offset).' ...' if defined $width_limit && $offset + length($sname) > $width_limit;
32
my $html_sect = (!$sect->status ? '<span class="hiddensect">' : '').($section_access ? '<a href="'.$href.'">' : '').$sname.' ' . ($section_access ? '</a>' : '') . ' '.(!$sect->status ? ' (�������)</span>' : $sect->status == 3 ? ' (��������)' : '');
33
my $style = ($offset == 1) ? ($viewmode ? ' style="font-size:110%;"':' style="font-size:95%;"') : '';
34
35
$m->out(<<EOT);
36
<tr>
37
<td align="right"> ${$line_ref} <a href="section.html?id=$sect->{id}&move=up&ret=$root"><img src="/contenido/i/ico-up-9x10.gif" border=0 alt="����������� ������ �� ��� �����"></a> <a href="section.html?id=$sect->{id}&move=down&ret=$root"><img src="/contenido/i/ico-down-9x10.gif" border=0 alt="����������� ������ �� ��� ����"></a></td>
38
<td><table cellpadding="0" cellspacing="0" border="0">
39
<tr valign="top">
40
<td width="10"> </td>
41
<td>$spacer</td>
42
<td nowrap $style>$html_sect</td>
43
</tr>
44
</table>
45
</td>
46
EOT
47
48
if ($viewmode)
49
{
50
my $fhref = '/contenido/?set_context=filter-'.$sect->id();
51
$m->out(qq^\n<td align="center" nowrap><a href="$fhref">���.������</a>^);
52
$m->out(qq^ <a href="document.html?sect_id=$sect->{id}">���.�����</a>^) if $section_access == 2;
53
$m->out("</td>");
54
}
55
56
$m->out('</tr>');
57
}
58
59
my $childs = $sect->{childs} || [];
60
if( ref($childs) && @$childs && $offset < $count_offset )
61
{
62
$offset++;
63
foreach my $child (@$childs)
64
{
65
next if ( $child->class() ne 'users::Section' );
66
next if (! $request->{cCLASSES}->{$child->class()});
67
users_index_tree( $child, $offset, $line_ref, $count_offset, $viewmode, $profile, $width_limit, $root );
68
}
69
$offset--;
70
}
71
}
72
73
my $sect = $keeper->get_tree(light=>1, root=>$root);
74
return undef unless ref $sect;
75
76
$user->get_accesses();
77
78
my $line = 0;
79
$request->{cCLASSES} = {};
80
$request->{cCLASSES}->{'users::Section'} = 1;
81
if (ref($request->{tab}->{sections}))
82
{
83
map { $request->{cCLASSES}->{$_} = 1 } (@{ $request->{tab}->{sections} });
84
}
85
return undef if (scalar(keys(%{ $request->{cCLASSES} })) == 0);
86
87
</%init>
koi8/plugins/users/comps/contenido/users/components/find_user.msn
1
<script type="text/javascript">
2
<!--
3
function StartSearch () {
4
var oForm = document.forms['user_search'];
5
var oFormStart = document.forms['start_search'];
6
% my $i = 0;
7
% foreach my $field ( @fields ) {
8
<% $i++ ? '} else if' : 'if' %> ( oForm.<% $field %>.value ) {
9
oFormStart.search.value = oForm.<% $field %>.value;
10
oFormStart.search_by.value = oForm.<% $field %>.name;
11
% }
12
% if ($i) {
13
}
14
% }
15
if ( oFormStart.search.value && oFormStart.search_by.value ) {
16
oFormStart.submit();
17
}
18
}
19
//-->
20
</script>
21
<fieldset>
22
<legend>����� ������������</legend>
23
<form id="start_search" name="start_search" action="<% $url %>" method="get">
24
<input type="hidden" name="search" value="">
25
<input type="hidden" name="search_by" value="">
26
</form>
27
<form id="user_search" name="user_search" action="<% $url %>" method="get">
28
<table cellspacing="2" cellpadding="0" border="0" class="tform">
29
<tr><td height="3"></td></tr>
30
% foreach my $field ( @fields ) {
31
<tr><td align="right"><b><% $props{$field} %>: </b></td>
32
<td><input type="text" name="<% $field %>" size="40" value="<% $search_by && $search_by eq $field ? $search : '' %>"></td></tr>
33
% }
34
35
<tr><td align="right"> </td>
36
<td align="right"><input type="button" size="40" value="������" onclick="StartSearch();">
37
<a href="<% $url %>">�������� ������</a>
38
</td></tr>
39
<tr><td height="5"></td></tr>
40
</table>
41
</form>
42
</fieldset>
43
<%args>
44
45
$url => 'index.html'
46
$search => undef
47
$search_by => undef
48
49
</%args>
50
<%init>
51
52
my @fields;
53
my @properties;
54
my %props;
55
my $class = $state->{users}->profile_document_class;
56
my $object = $class->new ($keeper);
57
if ( ref $object ) {
58
@fields = $object->search_fields;
59
@fields = qw( login email nickname name ) unless @fields;
60
@properties = $object->structure();
61
%props = map { $_->{attr} => $_->{rusname} } @properties;
62
} else {
63
@fields = qw( login email nickname name );
64
%props = (
65
'login' => { '�����' },
66
'email' => { 'E-mail' },
67
'nickname' => { '���' },
68
'name' => { '�.�.�.' },
69
);
70
}
71
72
</%init>
koi8/plugins/users/comps/contenido/users/components/subsection.msn
1
<fieldset>
2
<legend>����������</legend>
3
4
<table width="100%" border="0" cellpadding="3" cellspacing="0" class="tlistdocs">
5
<tr bgcolor="#efefef">
6
<th align="center" width="1%">N</th>
7
<th>��������</th>
8
9
<& "/contenido/users/components/__section_tree__.msn", root=>$section->id, level=>3, mode=>0, width_limit => 30 &>
10
11
</table>
12
% if ($section_access == 2)
13
% {
14
<div style="font-size:70%;font-family:Tahoma;margin:5px 4px 10px 4px;"><b><a href="section.html?sect_id=<% $section->id %>">������� ��������� »</a></b></div>
15
% }
16
<div style="font-size:70%;font-family:Tahoma;margin:5px 4px 10px 4px;"><b><a href="./?set_context=filter-<% $section->id %>">���������� � �������� ������� »</a></b></div>
17
</fieldset>
18
19
20
<%ARGS>
21
22
$section => undef
23
24
</%ARGS>
25
<%INIT>
26
return undef if (! ref($section));
27
my $section_access = $user->section_accesses($user, $section->id);
28
</%INIT>
koi8/plugins/users/comps/contenido/users/components/tasks.msn
1
<%init>
2
3
return (
4
{
5
'attr' => 'structure',
6
'rusname' => '�������������� ���������� �����',
7
'component' => 'structure.msn',
8
},
9
{
10
'attr' => 'project',
11
'rusname' => '�������������� ���������� ��������',
12
'component' => 'project.msn',
13
},
14
{
15
'attr' => 'finder',
16
'rusname' => '����� ����������',
17
'component' => 'finder.msn',
18
},
19
{
20
'attr' => 'users',
21
'rusname' => '������ ������������� �������',
22
'component' => 'users.msn',
23
},
24
{
25
'attr' => 'cache',
26
'rusname' => '�������� ��� �����',
27
'component' => 'cache.msn',
28
},
29
);
30
31
</%init>
koi8/plugins/users/comps/contenido/users/dhandler
1
%#<pre><% Dumper ($m->dhandler_arg) %></pre>
2
<& $call, %ARGS &>
3
<%init>
4
5
my $call;
6
if ( $m->dhandler_arg =~ /section.html/ ) {
7
$call = '../section.html';
8
} elsif ( $m->dhandler_arg =~ /confirm.html/ ) {
9
$call = '../confirm.html';
10
} elsif ( $r->uri eq '/contenido/users/' ) {
11
$call = '/contenido/users/index.html';
12
} else {
13
&abort404;
14
}
15
16
</%init>
koi8/plugins/users/comps/contenido/users/document.html
1
%# vim:syn=mason
2
<& "/contenido/components/header.msn" &>
3
4
<& "/contenido/components/naviline.msn", sect_id => $owner->id &>
5
6
% if ($error) {
7
<div align="center" style="font-size:110%; color:red;">
8
<% $error %>
9
</div>
10
<br><br>
11
% }
12
13
% if (!ref($document)) {
14
% if ($id) {
15
<div align="center" style="font-size:110%; color:red;">
16
�������� � ��������������� <% $id %> �� ������
17
</div>
18
<br><br>
19
% } elsif ($class) {
20
<!-- ���� � ������� ������ ��������� ��� �������� -->
21
<table width="50%" border="0"><tr><td>
22
<fieldset>
23
<legend>�������� ��� ��������� ��� ��������</legend>
24
<& "/contenido/components/new_objects_form.msn", proto => 'documents', sect_id => $owner->id &>
25
</fieldset>
26
</td></tr></table>
27
% } else {
28
<div align="center" style="font-size:110%; color:red;">
29
�� ������ ����� ���������!!! (����������� id � class ������������)
30
</div>
31
<br><br>
32
% }
33
34
% } else {
35
36
<& "/contenido/components/obj_list_js.msn", object => $document &>
37
<& "/contenido/components/object_form.msn",
38
object => $document,
39
proto => 'documents',
40
sect_id => $owner->id,
41
clone => $clone &>
42
% if (ref($document) && ($document->id))
43
% {
44
45
<!-- ����� � �������� � �������� -->
46
47
<br>
48
49
<table width="100%" cellspacing="5" cellpadding="0" border="0">
50
<tr>
51
<td width=50% valign=top>\
52
<& "/contenido/components/document_sections.msn", document => $document &>\
53
<& "/contenido/components/user_sections.msn", luser => $document &>\
54
% if ( $m->comp_exists ("/contenido/components/pbase_rubrics.msn") ) {
55
<& "/contenido/components/pbase_rubrics.msn", document => $document &>\
56
% }
57
</td>
58
<td width=50% valign=top>
59
% if ( $m->comp_exists ("/contenido/components/pbase_links.msn") ) {
60
<& "/contenido/components/pbase_links.msn", document => $document &>\
61
% }
62
<iframe id="links" src="document_links.html?id=<% $document->id() %>&class=<% $document->class() %>" width="100%" height="700" frameborder="0"></iframe>
63
64
</td>
65
</tr>
66
</table>
67
68
<!-- / ����� � �������� � �������� -->
69
70
% }
71
% }
72
73
</body>
74
</html>
75
<%ARGS>
76
$class => undef
77
$sect_id => undef
78
$s_alias => undef
79
$id => undef
80
$delete => undef
81
$save => undef
82
$clone => undef
83
$activate => undef
84
$deactivate => undef
85
</%ARGS>
86
<%INIT>
87
my $error='';
88
89
my $filter = $m->comp('/contenido/components/context.msn', name => 'filter');
90
91
my $document;
92
my $new;
93
94
if ($id && ($id !~ /\D/) && ($id > 0)) {
95
$document = $keeper->get_document_by_id($id, class=>$class);
96
if ( $clone && exists $document->{'attributes'}->{'dtime'} ) {
97
$document->dtime(undef);
98
}
99
} elsif ( ($class) && (length($class)>0) && (! ref($document)) ) {
100
$document = new $class ($keeper);
101
$new = 1;
102
my @properties = $document->structure();
103
foreach my $prop ( @properties ) {
104
my $attr = $prop->{attr};
105
### !!! ���� �� ����������� ����������, �� ����� ����������������
106
if ( exists $ARGS{$attr} && ! grep { $prop->{attr} eq $_ } qw( class sect_id id delete save clone s_alias activate deactivate ) ) {
107
$document->$attr($ARGS{$attr});
108
}
109
}
110
}
111
112
if (ref($document) && $document->id() && $document->section()) {
113
my $document_access = $user->section_accesses($user, $document->section);
114
if ($document_access != 2) {
115
$m->clear_buffer;
116
$m->abort(403);
117
}
118
}
119
120
if ($s_alias) {
121
$sect_id = $project->s_alias->{$s_alias};
122
}
123
124
if ( (! $sect_id) && (ref($document)) && ($document->id) ) {
125
$sect_id = $document->section();
126
}
127
my $owner = $keeper->get_section_by_id ($sect_id || $Contenido::Section::ROOT || 1);
128
129
if (! ref($owner)) {
130
$owner = $keeper->get_section_by_id ($Contenido::Section::ROOT || 1);
131
}
132
if (! ref($owner)) {
133
warn "Contenido Die: �� ���� ����� �������� ������\n";
134
return undef;
135
}
136
137
138
# ��������...
139
if (defined($id) && ($id > 0) && ($delete == 1)) {
140
$document->delete();
141
142
$r->header_out("Location", "sections.html?id=".$owner->id);
143
$r->status(302);
144
$r->send_http_header();
145
$m->abort();
146
}
147
148
# ���������...
149
if (defined($id) && ($id > 0) && ($activate == 1)) {
150
$document->status(1);
151
$document->store;
152
153
$r->header_out("Location", "sections.html?id=".$owner->id);
154
$r->status(302);
155
$r->send_http_header();
156
$m->abort();
157
}
158
159
# ����������...
160
if (defined($id) && ($id > 0) && ($deactivate == 1)) {
161
$document->status(0);
162
$document->store;
163
164
$r->header_out("Location", "sections.html?id=".$owner->id);
165
$r->status(302);
166
$r->send_http_header();
167
$m->abort();
168
}
169
170
# ���������� ������������� ��������� ��� �������� ������...
171
# ������, ���� ����� �� �������������� �����...
172
elsif ( $save == 1 )
173
{
174
my $clonesource;
175
if ( $clone ) {
176
$clonesource = $keeper->get_document_by_id ($clone,
177
class => $document->class,
178
);
179
}
180
if ($m->comp('/contenido/components/set_properties.msn', object => $document, SETS => \%ARGS) != 1)
181
{
182
# ������, ���� �� ����������...
183
warn "Contenido Warning: �� ���� ���������� �������� �����!\n";
184
}
185
if ( $clone ) {
186
$m->comp('/contenido/components/clone_attachments.msn', object => $document, source => $clonesource );
187
}
188
189
$document->sections( $owner->id, $filter > 0 ? ($filter) : ()) if $new;
190
191
unless ($document->store()) {
192
# ������, ���� �� ����������...
193
$error="������ ���������� ($keeper->{last_error})";
194
} else {
195
196
if ($ARGS{_save_and_leave})
197
{
198
$r->header_out("Location", "sections.html?id=".$owner->id);
199
$r->status(302);
200
$r->send_http_header();
201
$m->abort();
202
}
203
elsif ($ARGS{_save_and_again})
204
{
205
$r->header_out("Location", "document.html?class=".$document->class()."§_id=".$owner->id);
206
$r->status(302);
207
$r->send_http_header();
208
$m->abort();
209
}
210
211
212
$r->header_out("Location", "document.html?id=".$document->id()."&class=".$document->class());
213
$r->status(302);
214
$r->send_http_header();
215
$m->abort();
216
}
217
}
218
219
</%INIT>
220
koi8/plugins/users/comps/contenido/users/document_filter_list.html
1
<& "/contenido/components/title.msn" &>
2
<div style="font:bold 13px Verdana; margin:4px;">�����: <span style="color:teal;"><% $class %></span>
3
<span style="font:11px Verdana;">(<a href="document.html?class=<% $class %>&<% $field %>=<% $id %>" target="_blank">������� �����</a>)</span></div>
4
% if ( ref $docs eq 'ARRAY' && @$docs ) {
5
% if ($total > $size) {
6
<div style="font-size:75%; font-family:Arial; text-align:center;">
7
<& /inc/pages_.msn, p => $p, n => $size, total => $total, params => {%ARGS} &></div>
8
% }
9
% my @props = sort { $a->{column} <=> $b->{column} } grep { exists $_->{column} } $docs->[0]->required_properties;
10
<table width="100%" border="0" cellpadding="4" cellspacing="0" class="tlistdocs">
11
<tr bgcolor="#efefef">
12
% foreach my $prop (@props) {
13
<th><% $prop->{rusname} %></th>
14
% }
15
</tr>
16
% foreach my $doc (@$docs) {
17
% my $color = $doc->contenido_status_style ? $doc->contenido_status_style :
18
% $doc->status == 1 ? 'blue' :
19
% $doc->status == 0 ? 'gray' : 'blue';
20
21
%# my ($stat) = grep { $_->{attr} eq 'status' } @props;
22
%# my ($case) = grep { $_->[0] == $banner->status } @{ $stat->{cases} } if ref $stat eq 'HASH' && exists $stat->{cases};
23
<tr>
24
% foreach my $prop (@props) {
25
% my $attr = $prop->{attr};
26
% if ( $attr =~ /dtime/ ) {
27
<td><a href="document.html?id=<% $doc->id %>&class=<% $doc->class %>"
28
style="<% $color %>" target="_blank"><& "/contenido/components/show_dtime.msn", dtime => $doc->$attr &></a></td>
29
% }else{
30
<td><a href="document.html?id=<% $doc->id %>&class=<% $doc->class %>"
31
style="<% $color %>" target="_blank"><% $doc->$attr %></a></td>
32
% }
33
% }
34
</tr>
35
% }
36
</table>
37
% }
38
%#<pre><% Dumper($docs->[0]->required_properties) %></pre>
39
<%args>
40
$id => undef
41
$filter => undef
42
$field => undef
43
$class => undef
44
$order_by => undef
45
$p => 1
46
</%args>
47
<%init>
48
49
my ($docs, $total);
50
my $size = 15;
51
if ( $id && $filter && $class ) {
52
my %opts = ();
53
$opts{$filter} = $id;
54
$opts{order_by} = $order_by if $order_by;
55
$docs = $keeper->get_documents (
56
class => $class,
57
return_mode => 'array_ref',
58
offset => ($p-1)*$size,
59
limit => $size,
60
%opts,
61
);
62
$total = $keeper->get_documents (
63
class => $class,
64
count => 1,
65
%opts,
66
);
67
} else {
68
return;
69
}
70
71
</%init>
koi8/plugins/users/comps/contenido/users/document_links.html
1
<& "/contenido/components/title.msn" &>
2
% if ($document) {
3
<& "/contenido/components/document_links.msn", document => $document &>
4
% } else {
5
<p><font color="red">�� ���� �������� �������� �� ������ id=<% $id %> � class=<% $class %></font></p>
6
% }
7
</body>
8
</html>
9
10
<%ARGS>
11
$class => undef
12
$id => undef
13
</%ARGS>
14
15
<%INIT>
16
return unless ($state->{available_links} and @{$state->{available_links}});
17
my $document;
18
if ($id && ($id !~ /\D/) && ($id > 0)) {
19
$document = $keeper->get_document_by_id($id, class=>$class);
20
}
21
</%INIT>
22
koi8/plugins/users/comps/contenido/users/index.html
1
<& "/contenido/components/header.msn" &>
2
<& "/contenido/components/naviline.msn", sect_id => $owner->id &>
3
4
<table width="100%" cellspacing="0" cellpadding="0" border="0">
5
<tr valign="top">
6
<td width="35%">
7
8
<& /contenido/users/components/find_user.msn,
9
search => $search, search_by => $search_by,
10
url=>'sections.html' &>
11
12
<& "/contenido/users/components/subsection.msn", section => $owner &>
13
<& "/contenido/components/class_filter.msn", class=> $class, section => $owner &>
14
15
% if (( $owner->id ) && ($owner->id > 0) && $owner->id != 1 )
16
% {
17
<& "/contenido/components/section_info.msn", section => $owner &>
18
% }
19
20
</td>
21
<td width="2%"> </td>
22
<td width="65%">
23
24
% if($owner->id) {
25
26
<fieldset>
27
<legend>���������\
28
% if ($class) {
29
������ <% $class %>\
30
% if ($use_section) {
31
c ������ ������� ������\
32
% }
33
% } else {
34
� �������\
35
% }
36
% if ($total > 0) {
37
(�����: <% $total %>, �������� � <% $first + 1 %> �� <% ($first + $n > $total) ? $total : $first + $n %>)
38
% }
39
</legend>
40
41
% if ($total or defined($alpha) or defined($search) ) {
42
% if ($section_access == 2) {
43
<& "/contenido/components/new_objects_form.msn", proto => 'documents',
44
sect_id => $owner->id,
45
default => ($owner->default_document_class ? $owner->default_document_class : $class) &>
46
% }
47
<div style="font-size:75%; font-family:Arial;">
48
<table border="0" cellspacing="0" cellpadding="2" width="100%" style="margin:4px 0 0; border:1px solid gray;">
49
<tr bgcolor="#e0e0e0"><th colspan="4">����� �� �����: [<a href="?id=<% $id %>" style="font-weight:normal;">����� �������</a>]</th></tr>
50
<tr><td style="font-size:75%; font-family:Arial; padding:2px 4px;">
51
<& /inc/alpha.msn, alpha=>$alpha, params=>\%ARGS, &>
52
</td></tr></table>
53
% ## ����� ������. �������� ��� ���������� ������� ������
54
% ## � ��������� ��� ������ ������� search_fields
55
% ########################################################
56
%
57
% if ( $filter{class} ) {
58
% my $document = $filter{class}->new ($keeper);
59
% my @fields = $document->search_fields;
60
% if ( @fields ) {
61
% my @props = $document->required_properties;
62
<form action="sections.html">
63
<table border="0" cellspacing="0" cellpadding="2" width="100%" style="margin:4px 0; border:1px solid gray;">
64
<tr bgcolor="#e0e0e0"><th colspan="4">����� �� ����: [<a href="?id=<% $id %>" style="font-weight:normal;">����� �������</a>]</th></tr><tr>
65
<td width="1%" nowrap style="padding:2px 0 2px 4px;"><select name="search_by">
66
% foreach my $field ( @fields ) {
67
% my ($prop) = grep { $_->{'attr'} eq $field } @props;
68
% my $selected = $field eq $search_by ? ' selected' : '';
69
<option value="<% $field %>"<% $selected %>><% $prop->{'rusname'} %>
70
% }
71
</td><td width="0">:</td>
72
<td width="98%"><input type="text" name="search" value="<% $search %>" style="width:100%"></td>
73
<td width="1%" style="padding:2px 4px 2px 0;"><input type="submit" value=" » " style="border:1px solid gray;"></td>
74
</tr></table>
75
% if ( $id ) {
76
<input type="hidden" name="id" value="<% $id %>">
77
% }
78
% if ( $class ) {
79
<input type="hidden" name="class" value="<% $class %>">
80
% }
81
% if ( $use_section ) {
82
<input type="hidden" name="use_section" value="<% $use_section %>">
83
% }
84
</form>
85
% }
86
% }
87
88
<& /inc/pages_.msn, p=>$p, n=>$n, total=>$total, href=>'sections.html', params=>\%ARGS, &>
89
</div>
90
91
<table width="100%" border="0" cellpadding="4" cellspacing="0" class="tlistdocs">
92
<tr bgcolor="#efefef">
93
%
94
% foreach (@columns) {
95
%
96
<th><% $_->{rusname} %></th>
97
%
98
% }
99
%
100
</tr>
101
%
102
% unless (@documents) {
103
<tr><td align="center" colspan="<% scalar @columns %>">��������� �� �������</td></tr>
104
% }
105
% foreach my $document (@documents) {
106
%
107
% next unless ref($document);
108
% my $document_access = $user->section_accesses($user, $document->section);
109
%
110
<tr valign="top">
111
%
112
% for my $col (@columns) {
113
%
114
% if ($col->{attr} eq '_sort_') {
115
%
116
<td width="20px"><% $document->{sorder} %> <a href="document_move.html?id=<% $document->{id} %>&move=up&s=<% $id %>&p=<% $p %>"><img src="/contenido/i/ico-up-9x10.gif" border=0 alt="����������� �������� �� ��� �����"></a> <a href="document_move.html?id=<% $document->{id} %>&move=down&s=<% $id %>&p=<% $p %>"><img src="/contenido/i/ico-down-9x10.gif" border=0 alt="����������� �������� �� ��� ����"></a>\
117
%
118
% } elsif ($col->{attr} eq 'dtime') {
119
%
120
<td nowrap><& "/contenido/components/show_dtime.msn", dtime=>$document->{dtime} &>\
121
%
122
% if ($document->{ctime} ne $document->{mtime}) {
123
%
124
% my $colortime = '#c66';
125
%
126
<div style="color:<% $colortime %>;"><& "/contenido/components/show_dtime.msn", dtime=>$document->{mtime} &></div>\
127
%
128
% }
129
%
130
% } elsif ($col->{attr} eq 'name') {
131
%
132
<td><span<% $document->contenido_status_style ? ' style="' . $document->contenido_status_style . '"' : '' %> class="<% $document->status ? '':'hiddensect' %>">\
133
%
134
% my $name=$document->name ? $document->name : '���������� �������� N'.$document->id;
135
% if ($document_access == 2) {
136
%
137
<a<% $document->contenido_status_style ? ' style="' . $document->contenido_status_style . '"' : '' %> href="document.html?id=<% $document->id %>&class=<% $document->class %>"><% $name | h %> </a>\
138
%
139
% } else {
140
%
141
<% $name | h %> \
142
%
143
% }
144
%
145
</span>\
146
%
147
% } elsif ($col->{attr} eq 'id') {
148
%
149
<td><span class="<% $document->status ? '':'hiddensect' %>">\
150
%
151
% if ($document_access == 2) {
152
%
153
<a href="document.html?id=<% $document->id %>&class=<% $document->class %>"><% $document->id %> </a>\
154
%
155
% } else {
156
%
157
<% $document->id %> \
158
%
159
% }
160
%
161
</span>\
162
%
163
% } elsif ($col->{attr} eq 'class') {
164
%
165
<td><% $document->class_name %> <font color="#999999">(<% $document->class %>)</font>\
166
%
167
% } elsif ($col->{type} eq 'datetime') {
168
%
169
<td nowrap><& "/contenido/components/show_dtime.msn", dtime=>$document->{$col->{attr}} &>\
170
%
171
% } elsif ($col->{attr} eq '_act_') {
172
%
173
<td>\
174
% if ($document_access == 2) {
175
%
176
<a href="document.html?id=<% $document->id %>&class=<% $document->class %>" title="������������� ��������"><img
177
src="/contenido/i/actions/edit.gif" width="15" height="17" alt="������������� ��������" align="absmiddle" border="0" hspace="1"></a>\
178
<a href="document.html?clone=1&id=<% $document->id %>&class=<% $document->class %>" title="���������� ��������"><img
179
src="/contenido/i/actions/copy.gif" width="15" height="17" alt="���������� ��������" align="absmiddle" border="0" hspace="1"></a>\
180
<a href="confirm.html?id=<% $document->id %>&action=documents_deletion&from=<% $owner->id %>&class=<% $document->class %>" title="������� ��������"><img
181
src="/contenido/i/actions/delete.gif" width="14" height="17" alt="������� ��������" align="absmiddle" border="0" hspace="1"></a>\
182
% if ( $document->status != 0 ) {
183
<a href="document.html?deactivate=1&id=<% $document->id %>&class=<% $document->class %>" title="�������������� ������������"><img
184
src="/contenido/i/actions/deactivate.gif" width="14" height="17" alt="�������������� ������������" align="absmiddle" border="0" hspace="1"></a>\
185
% }
186
% if ( $document->status != 1 ) {
187
<a href="document.html?activate=1&id=<% $document->id %>&class=<% $document->class %>" title="��������� ������������ ������=1"><img
188
src="/contenido/i/actions/activate.gif" width="14" height="17" alt="��������� ������������ ������=1" align="absmiddle" border="0" hspace="1"></a>\
189
% }
190
<br>\
191
%#<a href="document.html?id=<% $document->id %>&class=<% $document->class %>">�������������</a><br/>\
192
%#<a href="confirm.html?id=<% $document->id %>&action=documents_deletion&from=<% $owner->id %>&class=<% $document->class %>">�������</a>\
193
%
194
% } else {
195
\
196
% }
197
%
198
% } else {
199
%
200
% if ($col->{type} eq 'date') {
201
% my $date=$document->{$col->{attr}};
202
% $date=~/(\d{4}-\d{2}-\d{2})/;
203
<td nowrap align="right"><% $1 || ' ' %>\
204
% } elsif ($col->{type} eq 'datetime') {
205
<td nowrap align="right"><% $document->{$col->{attr}} || ' ' %>\
206
% } elsif ($col->{type} eq 'integer') {
207
<td align="right"><% $document->{$col->{attr}} %> \
208
% } elsif ($col->{type} eq 'lookup') {
209
<td align="left">\
210
% my $id = $document->{$col->{attr}};
211
% if ($id) {
212
% my ($doc)=$keeper->get_documents( ( ref($col->{lookup_opts}) ? %{$col->{lookup_opts}} : () ), id=>$id);
213
% if ($doc) {
214
<a href="document.html?id=<% $doc->id %>&class=<% $doc->class %>"><% $doc->name || $doc->id %></a> \
215
% } else {
216
<span class="hiddensect"><% $document->{$col->{attr}} %>???</span>\
217
% }
218
% } else {
219
<span class="hiddensect">NULL</span>\
220
% }
221
% } elsif ($col->{type} eq 'status') {
222
% my $status_map = ref $col->{cases} eq 'ARRAY' ? $col->{cases} : $keeper->default_status();
223
% my ($doc_status) = grep { $_->[0] eq $document->{$col->{attr}} } @$status_map;
224
% $doc_status ||= [$document->{$col->{attr}}, '�����������'];
225
<td nowrap><% $doc_status->[1].'('.$doc_status->[0].')' %>\
226
% } else {
227
<td><% defined($document->{$col->{attr}}) ? $document->{$col->{attr}} : ' ' %>\
228
% }
229
% }
230
%
231
</td>
232
%
233
% } #- for @columns
234
%
235
</tr>
236
% } #- foreach @documents
237
</table>
238
239
<div style="font-size:75%; font-family:Arial;">
240
<& /inc/pages_.msn, p=>$p, n=>$n, total=>$total, href=>'sections.html', params=>\%ARGS, &>
241
</div>
242
% } else {
243
<h4 align="center"><i>---- ��� ���������� -----</i></h4>
244
% }
245
%
246
% if ($section_access == 2) {
247
<& "/contenido/components/new_objects_form.msn", proto => 'documents',
248
sect_id => $owner->id,
249
default => ($owner->default_document_class ? $owner->default_document_class : $class) &>
250
% }
251
252
</fieldset>
253
</td>
254
</tr>
255
</table>
256
257
% }
258
259
</body>
260
</html>
261
<%args>
262
263
$id => 1
264
$p => 1
265
$class => undef
266
$use_section => undef
267
$alpha => undef
268
$alpha_search => undef
269
$search_by => undef
270
$search => undef
271
272
</%args>
273
<%init>
274
275
$id = 0 if $id =~ /\D/;
276
my $owner;
277
278
# ��������...
279
if ($id && ($id > 0))
280
{
281
$owner = $keeper->get_section_by_id($id);
282
}
283
if (! ref($owner))
284
{
285
return undef;
286
}
287
288
$class = $state->{users}->profile_document_class;
289
# ������� �������� � ����� ������...
290
my $filter = $m->comp('/contenido/components/context.msn', name => 'filter');
291
my $profile = $m->comp('/contenido/components/context.msn', name => 'profile');
292
293
unless (defined $request->{section_accesses}->{$id})
294
{
295
$request->{section_accesses}->{$id} = $user->get_section_access($id);
296
}
297
my $section_access = $request->{section_accesses}->{$id};
298
299
my (@documents, $total);
300
301
my $s = $owner->id;
302
my $sorted = $owner->_sorted();
303
$s .= ",$filter" if ($filter > 0);
304
305
my %filter=();
306
my %order = (not $class and $owner->order_by) ? (order_by => $owner->order_by) : (order => ['date','direct']);
307
if (defined $alpha and $alpha ne '') {
308
$filter{ilike}=1;
309
$filter{ $alpha_search || 'name' }="$alpha%";
310
$order{order}=['name','reverse'];
311
delete $order{order_by};
312
}
313
314
$filter{class} = $owner->default_document_class if $owner->default_document_class;
315
$filter{class}=$class if ($class);
316
$filter{s}=$s unless ($class && !$use_section);
317
if ( $search_by && $search ) {
318
$filter{$search_by}='%'.$search.'%';
319
$filter{ilike} = 1;
320
}
321
322
# �������������� ������� �������
323
if ($owner->filters) {
324
no strict 'vars';
325
my $filters = eval($owner->filters);
326
if ($@) {
327
warn "Bad filter: " . $owner->filters . " in section " . $owner->id;
328
} elsif (ref $filters eq 'HASH') {
329
map { $filter{$_} = $filters->{$_} } keys %$filters;
330
}
331
}
332
333
$total = $keeper->get_documents(%filter, count=>1);
334
335
my $n = 40;
336
my $first = $n * ($p - 1);
337
($first,$p)=(0,0) if ($first>$total);
338
339
if ($class && !$use_section) {
340
@documents = $keeper->get_documents(%filter, %order, limit=>$n, offset=>$first, light=>1);
341
} elsif ($sorted) {
342
@documents = $keeper->get_sorted_documents(%filter, limit=>$n, offset=>$first, light=>1);
343
} else {
344
@documents = $keeper->get_documents(%filter, %order, limit=>$n, offset=>$first, light=>1);
345
}
346
347
# ����� ������� ������� ����������...
348
my @columns = $sorted ? ({attr => '_sort_', name => 'N'}) : ();
349
350
# �������� ����� �������, ������� �������� ��� ������� �������� (required_properties -> column)...
351
if ($filter{class} or @documents and $documents[0]) {
352
push @columns,
353
sort {$a->{column} <=> $b->{column}}
354
grep {$_->{column}} ($filter{class} ? $filter{class}->new($keeper)->structure : $documents[0]->structure);
355
}
356
357
# ����������� ����� �������...
358
@columns = (@columns,
359
{attr => '_act_', rusname => '��������'},
360
);
361
</%init>
koi8/plugins/users/comps/contenido/users/link_frame.html
1
<frameset border="0" bordercolor="black" rows="40,*" frameborder="1">
2
<frame src="links/title.html?class=<% $class %>" bordercolor="black" marginheight="2" marginwidth="2"
3
name="linktitle" noresize scrolling="no" height="30">
4
<frameset border="0" bordercolor="black" cols="50%,50%" frameborder="1">
5
<frame src="links/source.html<% $sargs %>" bordercolor="gray" marginheight="2" marginwidth="2" name="sourcefrm" noresize scrolling="yes">
6
<frame src="links/destination.html<% $dargs %>" bordercolor="black" marginheight="2" marginwidth="2" name="destfrm" noresize scrolling="yes">
7
</frameset>
8
</frameset>
9
10
<%args>
11
$class => ''
12
$source_class => ''
13
$source_id => ''
14
$dest_class => ''
15
$dest_id => ''
16
$save => 0
17
$status => 0
18
</%args>
19
<%init>
20
21
my (@source_args, $sargs, @dest_args, $dargs);
22
push @source_args, 'class='.$class if $class;
23
push @source_args, 'source_class='.$source_class if $source_class;
24
push @source_args, 'source_id='.$source_id if $source_id;
25
push @dest_args, 'class='.$class if $class;
26
push @dest_args, 'dest_class='.$dest_class if $dest_class;
27
push @dest_args, 'dest_id='.$dest_id if $dest_id;
28
29
$sargs = @source_args ? '?'.join('&', @source_args) : undef;
30
$dargs = @dest_args ? '?'.join('&', @dest_args) : undef;
31
32
</%init>
koi8/plugins/users/comps/contenido/users/links/destination.html
1
<& "/contenido/components/title.msn", title=>'�������� ������' &>
2
<style>
3
<!--
4
body {margin:5px;}
5
-->
6
</style>
7
8
9
% if (ref $document) {
10
% ### Destination is available
11
% ######################################################
12
13
<script language="JavaScript">
14
<!--
15
function DeleteSource ()
16
{
17
oSelect = document.forms['sourceform'].elements[0];
18
for (j = 0; j < oSelect.options.length; j++) {
19
if (!oSelect.options[j].selected) {
20
oSelect.options[j] = null;
21
}
22
}
23
return true;
24
}
25
26
function SelectAllSources ()
27
{
28
oSelect = document.forms['sourceform'].elements[0];
29
// oSelect.setExpression('multiple', true);
30
// document.recalc(true);
31
for (j = 0; j < oSelect.options.length; j++) {
32
oSelect.options[j].selected = true;
33
}
34
return true;
35
}
36
37
function CheckSource ()
38
{
39
oSelect = document.forms['sourceform'].elements[0];
40
if ( oSelect.options.length ) {
41
return true;
42
} else {
43
alert ('�� ������ �� ���� ��������');
44
return false;
45
}
46
}
47
48
//-->
49
</script>
50
51
%
52
% my @properties = $document->structure();
53
% my ($prop) = grep { $_->{'attr'} eq 'status' } @properties;
54
% my ($status) = grep { $_->[0] == $document->status } @{ $m->comp( '/contenido/components/inputs/status.msn', prop => $prop, object=>$document, name => $prop->{attr}, mode => 'get') };
55
% $status = $status->[1];
56
<table width="100%" border="0" align="center"><tr><td>
57
<fieldset>
58
<legend>����</legend>
59
<table class="tform" width="100%">
60
<tr valign="top"><td><b>��������:</b>
61
</td><td><a href="/contenido/document.html?id=<% $document->id %>&class=<% $document->class %>" target="_top"><% $document->name %></a>
62
</td></tr>
63
<tr valign="top"><td><b>�����:</b>
64
</td><td><% $document->class %>
65
</td></tr>
66
<tr valign="top"><td><b>������:</b>
67
</td><td><% $status %>
68
</td></tr>
69
</table>
70
</fieldset>
71
72
<fieldset>
73
<legend>������ ������</legend>
74
<table class="tform" width="100%">
75
<tr><td>
76
<form action="link_add.html" name="sourceform" target="_top" method="post" onsubmit="return CheckSource();">
77
<select multiple name="sources" size="20" style="width:100%">
78
</select>
79
<p>� ������ ���� ����� ��������� ������ ���������� ���������.</p>
80
<input type="hidden" name="class" value="<% $class %>">
81
<input type="hidden" name="dest_id" value="<% $dest_id %>">
82
<input type="hidden" name="dest_class" value="<% $dest_class %>">
83
<input type="button" value="�������� ���" onclick="SelectAllSources();">
84
<input type="button" value="������� ������" onclick="DeleteSource();">
85
<input type="submit" value="������� ���������">
86
</form>
87
</td></tr>
88
</table>
89
</fieldset>
90
91
</td></tr></table>
92
93
94
% }else{
95
% ### Destination is not available
96
% ######################################################
97
%
98
99
<script language="JavaScript">
100
<!--
101
function AddDest (Value, Name)
102
{
103
// alert (Name);
104
105
var oSelect = parent.frames.sourcefrm.document.forms['destform'].elements[0];
106
var Found = 0;
107
for(j=0; j < oSelect.options.length; j++) {
108
if (oSelect.options[j].value == Value) {
109
Found = 1;
110
}
111
}
112
if (!Found) {
113
var oOption = document.createElement("OPTION");
114
oOption.text=Name;
115
oOption.value=Value;
116
oOption.selected=true;
117
oSelect.options.add(oOption);
118
}
119
return false;
120
}
121
//-->
122
</script>
123
124
<& /contenido/components/link_browse.msn,
125
class => $class,
126
dest_class => $dest_class,
127
p => $p,
128
use_section => $use_section,
129
alpha => $alpha,
130
alpha_search => $alpha_search,
131
search => $search,
132
search_by => $search_by,
133
restrict_class => $restrict_class,
134
&>
135
136
% }
137
138
</body>
139
</html>
140
<%args>
141
142
$class => ''
143
$source_class => ''
144
$source_id => ''
145
$dest_class => ''
146
$dest_id => ''
147
$save => 0
148
$status => 0
149
150
$p => 1
151
$restrict_class => undef
152
$use_section => undef
153
$alpha => undef
154
$alpha_search => undef
155
$search_by => undef
156
$search => undef
157
158
</%args>
159
<%init>
160
161
my $document;
162
163
if ($dest_id) {
164
$document = $keeper->get_document_by_id ($dest_id,
165
class => $dest_class,
166
);
167
} else {
168
$dest_class = $class->available_destinations;
169
}
170
171
</%init>
koi8/plugins/users/comps/contenido/users/links/link_add.html
1
%#<pre><% Dumper(\%ARGS) %></pre>
2
<%args>
3
4
$class => undef
5
$source_id => undef
6
$source_class => undef
7
$dest_id => undef
8
$dest_class => undef
9
$sources => undef
10
$destinations => undef
11
12
</%args>
13
<%init>
14
15
abort404 unless $class;
16
17
my @documents;
18
my $ret_params;
19
if ( $source_id && $source_class && ($destinations || (ref $destinations eq 'ARRAY' && @$destinations)) ) {
20
@documents = $keeper->get_documents (
21
in_id => $destinations,
22
);
23
foreach my $doc (@documents) {
24
my $link = $class->new ($keeper);
25
$link->source_id ($source_id);
26
$link->source_class ($source_class);
27
$link->dest_id ($doc->id);
28
$link->dest_class ($doc->class);
29
$link->store;
30
}
31
$ret_params = "id=$source_id&class=$source_class";
32
} elsif ( $dest_id && $dest_class && ($sources || (ref $sources eq 'ARRAY' && @$sources)) ) {
33
@documents = $keeper->get_documents (
34
in_id => $sources,
35
);
36
foreach my $doc (@documents) {
37
my $link = $class->new ($keeper);
38
$link->dest_id ($dest_id);
39
$link->dest_class ($dest_class);
40
$link->source_id ($doc->id);
41
$link->source_class ($doc->class);
42
$link->store;
43
}
44
$ret_params = "id=$dest_id&class=$dest_class";
45
}
46
if ($ret_params) {
47
$m->redirect("Location", "/contenido/users/document.html?".$ret_params);
48
}else{
49
&abort404;
50
}
51
52
</%init>
koi8/plugins/users/comps/contenido/users/links/source.html
1
<& "/contenido/components/title.msn", title=>'�������� ������' &>
2
<style>
3
<!--
4
body {margin:5px;}
5
-->
6
</style>
7
8
% if (ref $document) {
9
% ### Source is available
10
% ######################################################
11
12
<script language="JavaScript">
13
<!--
14
function DeleteDest ()
15
{
16
oSelect = document.forms['destform'].elements[0];
17
for (j = 0; j < oSelect.options.length; j++) {
18
if (!oSelect.options[j].selected) {
19
oSelect.options[j] = null;
20
}
21
}
22
return true;
23
}
24
25
function SelectAllDest ()
26
{
27
oSelect = document.forms['destform'].elements[0];
28
// oSelect.setExpression('multiple', true);
29
// document.recalc(true);
30
for (j = 0; j < oSelect.options.length; j++) {
31
oSelect.options[j].selected = true;
32
}
33
return true;
34
}
35
36
function CheckDest ()
37
{
38
oSelect = document.forms['destform'].elements[0];
39
if ( oSelect.options.length ) {
40
return true;
41
} else {
42
alert ('�� ������ �� ���� ��������');
43
return false;
44
}
45
}
46
47
//-->
48
</script>
49
50
%
51
% my @properties = $document->structure();
52
% my ($prop) = grep { $_->{'attr'} eq 'status' } @properties;
53
% my ($status) = grep { $_->[0] == $document->status } @{ $m->comp( '/contenido/components/inputs/status.msn', prop => $prop, object=>$document, name => $prop->{attr}, mode => 'get') };
54
% $status = $status->[1];
55
<table width="100%" border="0" align="center"><tr><td>
56
<fieldset>
57
<legend>��������</legend>
58
<table class="tform" width="100%">
59
<tr valign="top"><td><b>��������:</b>
60
</td><td><a href="/contenido/document.html?id=<% $document->id %>&class=<% $document->class %>" target="_top"><% $document->name %></a>
61
</td></tr>
62
<tr valign="top"><td><b>�����:</b>
63
</td><td><% $document->class %>
64
</td></tr>
65
<tr valign="top"><td><b>������:</b>
66
</td><td><% $status %>
67
</td></tr>
68
</table>
69
</fieldset>
70
71
<fieldset>
72
<legend>������ ������</legend>
73
<table class="tform" width="100%">
74
<tr><td>
75
<form action="link_add.html" name="destform" target="_top" method="post" onsubmit="return CheckDest();">
76
<select multiple name="destinations" size="20" style="width:100%">
77
</select>
78
<p>� ��������� ����� ��������� ������ ���������� ���������.</p>
79
<input type="hidden" name="class" value="<% $class %>">
80
<input type="hidden" name="source_id" value="<% $source_id %>">
81
<input type="hidden" name="source_class" value="<% $source_class %>">
82
<input type="button" value="�������� ���" onclick="SelectAllDest();">
83
<input type="button" value="������� ������" onclick="DeleteDest();">
84
<input type="submit" value="������� ���������">
85
</form>
86
</td></tr>
87
</table>
88
</fieldset>
89
90
</td></tr></table>
91
92
%#<pre><% Dumper(\@properties) %></pre>
93
94
% }else{
95
% ### Source is not available
96
% ######################################################
97
%
98
99
<script language="JavaScript">
100
<!--
101
function AddSource (Value, Name)
102
{
103
// alert (Name);
104
105
var oSelect = parent.frames.destfrm.document.forms['sourceform'].elements[0];
106
var Found = 0;
107
for(j=0; j < oSelect.options.length; j++) {
108
if (oSelect.options[j].value == Value) {
109
Found = 1;
110
}
111
}
112
if (!Found) {
113
var oOption = document.createElement("OPTION");
114
oOption.text=Name;
115
oOption.value=Value;
116
oOption.selected=true;
117
oSelect.options.add(oOption);
118
}
119
return false;
120
}
121
//-->
122
</script>
123
124
<& /contenido/components/link_browse.msn,
125
class => $class,
126
source_class => $source_class,
127
p => $p,
128
use_section => $use_section,
129
alpha => $alpha,
130
alpha_search => $alpha_search,
131
search => $search,
132
search_by => $search_by,
133
restrict_class => $restrict_class,
134
&>
135
136
% }
137
138
</body>
139
</html>
140
<%args>
141
$class => ''
142
$source_class => ''
143
$source_id => ''
144
$dest_class => ''
145
$dest_id => ''
146
$save => 0
147
$status => 0
148
149
$p => 1
150
$restrict_class => undef
151
$use_section => undef
152
$alpha => undef
153
$alpha_search => undef
154
$search_by => undef
155
$search => undef
156
157
</%args>
158
<%init>
159
160
my $document;
161
162
if ($source_id) {
163
$document = $keeper->get_document_by_id ($source_id,
164
class => $source_class,
165
);
166
} else {
167
$source_class = $class->available_sources;
168
}
169
170
</%init>
koi8/plugins/users/comps/contenido/users/links/title.html
1
<& "/contenido/components/title.msn", title=>'�������� ������' &>
2
<table width="100%" cellspacing="5" cellpadding="0" border="0">
3
<tr><td style="font-size:110%;">
4
<div><b>�������� ������. ��� ����� —
5
<% $class->class_name %> (<span style="color:olive;"><% $class %></span>)</b></div>
6
</td></tr>
7
</table>
8
</body>
9
</html>
10
<%args>
11
$class => ''
12
$source_class => ''
13
$source_id => ''
14
$dest_class => ''
15
$dest_id => ''
16
$save => 0
17
$status => 0
18
</%args>
koi8/plugins/users/comps/contenido/users/sections.html
1
<& "/contenido/components/header.msn" &>
2
<& "/contenido/components/naviline.msn", sect_id => $owner->id &>
3
4
<table width="100%" cellspacing="0" cellpadding="0" border="0">
5
<tr valign="top">
6
<td width="35%">
7
8
<& /contenido/users/components/find_user.msn,
9
search => $search, search_by => $search_by,
10
url=>'sections.html' &>
11
12
<& "/contenido/users/components/subsection.msn", section => $owner &>
13
<& "/contenido/components/class_filter.msn", class=> $class, section => $owner &>
14
15
% if (( $owner->id ) && ($owner->id > 0) && $owner->id != 1 )
16
% {
17
<& "/contenido/components/section_info.msn", section => $owner &>
18
% }
19
20
</td>
21
<td width="2%"> </td>
22
<td width="65%">
23
24
% if($owner->id) {
25
26
<fieldset>
27
<legend>���������\
28
% if ($class) {
29
������ <% $class %>\
30
% if ($use_section) {
31
c ������ ������� ������\
32
% }
33
% } else {
34
� �������\
35
% }
36
% if ($total > 0) {
37
(�����: <% $total %>, �������� � <% $first + 1 %> �� <% ($first + $n > $total) ? $total : $first + $n %>)
38
% }
39
</legend>
40
41
% if ($total or defined($alpha) or defined($search) ) {
42
% if ($section_access == 2) {
43
<& "/contenido/components/new_objects_form.msn", proto => 'documents',
44
sect_id => $owner->id,
45
default => ($owner->default_document_class ? $owner->default_document_class : $class) &>
46
% }
47
<div style="font-size:75%; font-family:Arial;">
48
<table border="0" cellspacing="0" cellpadding="2" width="100%" style="margin:4px 0 0; border:1px solid gray;">
49
<tr bgcolor="#e0e0e0"><th colspan="4">����� �� �����: [<a href="?id=<% $id %>" style="font-weight:normal;">����� �������</a>]</th></tr>
50
<tr><td style="font-size:75%; font-family:Arial; padding:2px 4px;">
51
<& /inc/alpha.msn, alpha=>$alpha, params=>\%ARGS, &>
52
</td></tr></table>
53
% ## ����� ������. �������� ��� ���������� ������� ������
54
% ## � ��������� ��� ������ ������� search_fields
55
% ########################################################
56
%
57
% if ( $filter{class} ) {
58
% my $document = $filter{class}->new ($keeper);
59
% my @fields = $document->search_fields;
60
% if ( @fields ) {
61
% my @props = $document->required_properties;
62
<form action="sections.html">
63
<table border="0" cellspacing="0" cellpadding="2" width="100%" style="margin:4px 0; border:1px solid gray;">
64
<tr bgcolor="#e0e0e0"><th colspan="4">����� �� ����: [<a href="?id=<% $id %>" style="font-weight:normal;">����� �������</a>]</th></tr><tr>
65
<td width="1%" nowrap style="padding:2px 0 2px 4px;"><select name="search_by">
66
% foreach my $field ( @fields ) {
67
% my ($prop) = grep { $_->{'attr'} eq $field } @props;
68
% my $selected = $field eq $search_by ? ' selected' : '';
69
<option value="<% $field %>"<% $selected %>><% $prop->{'rusname'} %>
70
% }
71
</td><td width="0">:</td>
72
<td width="98%"><input type="text" name="search" value="<% $search %>" style="width:100%"></td>
73
<td width="1%" style="padding:2px 4px 2px 0;"><input type="submit" value=" » " style="border:1px solid gray;"></td>
74
</tr></table>
75
% if ( $id ) {
76
<input type="hidden" name="id" value="<% $id %>">
77
% }
78
% if ( $class ) {
79
<input type="hidden" name="class" value="<% $class %>">
80
% }
81
% if ( $use_section ) {
82
<input type="hidden" name="use_section" value="<% $use_section %>">
83
% }
84
</form>
85
% }
86
% }
87
88
<& /inc/pages_.msn, p=>$p, n=>$n, total=>$total, href=>'sections.html', params=>\%ARGS, &>
89
</div>
90
91
<table width="100%" border="0" cellpadding="4" cellspacing="0" class="tlistdocs">
92
<tr bgcolor="#efefef">
93
%
94
% foreach (@columns) {
95
%
96
<th><% $_->{rusname} %></th>
97
%
98
% }
99
%
100
</tr>
101
%
102
% unless (@documents) {
103
<tr><td align="center" colspan="<% scalar @columns %>">��������� �� �������</td></tr>
104
% }
105
% foreach my $document (@documents) {
106
%
107
% next unless ref($document);
108
% my $document_access = $user->section_accesses($user, $document->section);
109
%
110
<tr valign="top">
111
%
112
% for my $col (@columns) {
113
%
114
% if ($col->{attr} eq '_sort_') {
115
%
116
<td width="20px"><% $document->{sorder} %> <a href="document_move.html?id=<% $document->{id} %>&move=up&s=<% $id %>&p=<% $p %>"><img src="/contenido/i/ico-up-9x10.gif" border=0 alt="����������� �������� �� ��� �����"></a> <a href="document_move.html?id=<% $document->{id} %>&move=down&s=<% $id %>&p=<% $p %>"><img src="/contenido/i/ico-down-9x10.gif" border=0 alt="����������� �������� �� ��� ����"></a>\
117
%
118
% } elsif ($col->{attr} eq 'dtime') {
119
%
120
<td nowrap><& "/contenido/components/show_dtime.msn", dtime=>$document->{dtime} &>\
121
%
122
% if ($document->{ctime} ne $document->{mtime}) {
123
%
124
% my $colortime = '#c66';
125
%
126
<div style="color:<% $colortime %>;"><& "/contenido/components/show_dtime.msn", dtime=>$document->{mtime} &></div>\
127
%
128
% }
129
%
130
% } elsif ($col->{attr} eq 'name') {
131
%
132
<td><span<% $document->contenido_status_style ? ' style="' . $document->contenido_status_style . '"' : '' %> class="<% $document->status ? '':'hiddensect' %>">\
133
%
134
% my $name=$document->name ? $document->name : '���������� �������� N'.$document->id;
135
% if ($document_access == 2) {
136
%
137
<a<% $document->contenido_status_style ? ' style="' . $document->contenido_status_style . '"' : '' %> href="document.html?id=<% $document->id %>&class=<% $document->class %>"><% $name | h %> </a>\
138
%
139
% } else {
140
%
141
<% $name | h %> \
142
%
143
% }
144
%
145
</span>\
146
%
147
% } elsif ($col->{attr} eq 'id') {
148
%
149
<td><span class="<% $document->status ? '':'hiddensect' %>">\
150
%
151
% if ($document_access == 2) {
152
%
153
<a href="document.html?id=<% $document->id %>&class=<% $document->class %>"><% $document->id %> </a>\
154
%
155
% } else {
156
%
157
<% $document->id %> \
158
%
159
% }
160
%
161
</span>\
162
%
163
% } elsif ($col->{attr} eq 'class') {
164
%
165
<td><% $document->class_name %> <font color="#999999">(<% $document->class %>)</font>\
166
%
167
% } elsif ($col->{type} eq 'datetime') {
168
%
169
<td nowrap><& "/contenido/components/show_dtime.msn", dtime=>$document->{$col->{attr}} &>\
170
%
171
% } elsif ($col->{attr} eq '_act_') {
172
%
173
<td>\
174
% if ($document_access == 2) {
175
%
176
<a href="document.html?id=<% $document->id %>&class=<% $document->class %>" title="������������� ��������"><img
177
src="/contenido/i/actions/edit.gif" width="15" height="17" alt="������������� ��������" align="absmiddle" border="0" hspace="1"></a>\
178
<a href="document.html?clone=1&id=<% $document->id %>&class=<% $document->class %>" title="���������� ��������"><img
179
src="/contenido/i/actions/copy.gif" width="15" height="17" alt="���������� ��������" align="absmiddle" border="0" hspace="1"></a>\
180
<a href="confirm.html?id=<% $document->id %>&action=documents_deletion&from=<% $owner->id %>&class=<% $document->class %>" title="������� ��������"><img
181
src="/contenido/i/actions/delete.gif" width="14" height="17" alt="������� ��������" align="absmiddle" border="0" hspace="1"></a>\
182
% if ( $document->status != 0 ) {
183
<a href="document.html?deactivate=1&id=<% $document->id %>&class=<% $document->class %>" title="�������������� ������������"><img
184
src="/contenido/i/actions/deactivate.gif" width="14" height="17" alt="�������������� ������������" align="absmiddle" border="0" hspa
185
% }
186
% if ( $document->status != 1 ) {
187
<a href="document.html?activate=1&id=<% $document->id %>&class=<% $document->class %>" title="��������� ������������ ������=1"><img
188
src="/contenido/i/actions/activate.gif" width="14" height="17" alt="��������� ������������ ������=1" align="absmiddle" border="0" hspace="1"></a>\
189
% }
190
<br>\
191
%#<a href="document.html?id=<% $document->id %>&class=<% $document->class %>">�������������</a><br/>\
192
%#<a href="confirm.html?id=<% $document->id %>&action=documents_deletion&from=<% $owner->id %>&class=<% $document->class %>">�������</a>\
193
%
194
% } else {
195
\
196
% }
197
%
198
% } else {
199
%
200
% if ($col->{type} eq 'date') {
201
% my $date=$document->{$col->{attr}};
202
% $date=~/(\d{4}-\d{2}-\d{2})/;
203
<td nowrap align="right"><% $1 || ' ' %>\
204
% } elsif ($col->{type} eq 'datetime') {
205
<td nowrap align="right"><% $document->{$col->{attr}} || ' ' %>\
206
% } elsif ($col->{type} eq 'integer') {
207
<td align="right"><% $document->{$col->{attr}} %> \
208
% } elsif ($col->{type} eq 'lookup') {
209
<td align="left">\
210
% my $id = $document->{$col->{attr}};
211
% if ($id) {
212
% my ($doc)=$keeper->get_documents( ( ref($col->{lookup_opts}) ? %{$col->{lookup_opts}} : () ), id=>$id);
213
% if ($doc) {
214
<a href="document.html?id=<% $doc->id %>&class=<% $doc->class %>"><% $doc->name || $doc->id %></a> \
215
% } else {
216
<span class="hiddensect"><% $document->{$col->{attr}} %>???</span>\
217
% }
218
% } else {
219
<span class="hiddensect">NULL</span>\
220
% }
221
% } elsif ($col->{type} eq 'status') {
222
% my $status_map = ref $col->{cases} eq 'ARRAY' ? $col->{cases} : $keeper->default_status();
223
% my ($doc_status) = grep { $_->[0] eq $document->{$col->{attr}} } @$status_map;
224
% $doc_status ||= [$document->{$col->{attr}}, '�����������'];
225
<td nowrap><% $doc_status->[1].'('.$doc_status->[0].')' %>\
226
% } else {
227
<td><% defined($document->{$col->{attr}}) ? $document->{$col->{attr}} : ' ' %>\
228
% }
229
% }
230
%
231
</td>
232
%
233
% } #- for @columns
234
%
235
</tr>
236
% } #- foreach @documents
237
</table>
238
239
<div style="font-size:75%; font-family:Arial;">
240
<& /inc/pages_.msn, p=>$p, n=>$n, total=>$total, href=>'sections.html', params=>\%ARGS, &>
241
</div>
242
% } else {
243
<h4 align="center"><i>---- ��� ���������� -----</i></h4>
244
% }
245
%
246
% if ($section_access == 2) {
247
<& "/contenido/components/new_objects_form.msn", proto => 'documents',
248
sect_id => $owner->id,
249
default => ($owner->default_document_class ? $owner->default_document_class : $class) &>
250
% }
251
252
</fieldset>
253
</td>
254
</tr>
255
</table>
256
257
% }
258
259
</body>
260
</html>
261
<%args>
262
263
$id => 1
264
$p => 1
265
$class => undef
266
$use_section => undef
267
$alpha => undef
268
$alpha_search => undef
269
$search_by => undef
270
$search => undef
271
272
</%args>
273
<%init>
274
275
$id = 0 if $id =~ /\D/;
276
my $owner;
277
278
# ��������...
279
if ($id && ($id > 0))
280
{
281
$owner = $keeper->get_section_by_id($id);
282
}
283
if (! ref($owner))
284
{
285
return undef;
286
}
287
288
$class = $state->{users}->profile_document_class;
289
# ������� �������� � ����� ������...
290
my $filter = $m->comp('/contenido/components/context.msn', name => 'filter');
291
my $profile = $m->comp('/contenido/components/context.msn', name => 'profile');
292
293
unless (defined $request->{section_accesses}->{$id})
294
{
295
$request->{section_accesses}->{$id} = $user->get_section_access($id);
296
}
297
my $section_access = $request->{section_accesses}->{$id};
298
299
my (@documents, $total);
300
301
my $s = $owner->id;
302
my $sorted = $owner->_sorted();
303
$s .= ",$filter" if ($filter > 0);
304
305
my %filter=();
306
my %order = (not $class and $owner->order_by) ? (order_by => $owner->order_by) : (order => ['date','direct']);
307
if (defined $alpha and $alpha ne '') {
308
$filter{ilike}=1;
309
$filter{ $alpha_search || 'name' }="$alpha%";
310
$order{order}=['name','reverse'];
311
delete $order{order_by};
312
}
313
314
$filter{class} = $owner->default_document_class if $owner->default_document_class;
315
$filter{class}=$class if ($class);
316
$filter{s}=$s unless ($class && !$use_section);
317
if ( $search_by && $search ) {
318
$filter{$search_by}='%'.$search.'%';
319
$filter{ilike} = 1;
320
}
321
322
# �������������� ������� �������
323
if ($owner->filters) {
324
no strict 'vars';
325
my $filters = eval($owner->filters);
326
if ($@) {
327
warn "Bad filter: " . $owner->filters . " in section " . $owner->id;
328
} elsif (ref $filters eq 'HASH') {
329
map { $filter{$_} = $filters->{$_} } keys %$filters;
330
}
331
}
332
333
$total = $keeper->get_documents(%filter, count=>1);
334
335
my $n = 40;
336
my $first = $n * ($p - 1);
337
($first,$p)=(0,0) if ($first>$total);
338
339
if ($class && !$use_section) {
340
@documents = $keeper->get_documents(%filter, %order, limit=>$n, offset=>$first, light=>1);
341
} elsif ($sorted) {
342
@documents = $keeper->get_sorted_documents(%filter, limit=>$n, offset=>$first, light=>1);
343
} else {
344
@documents = $keeper->get_documents(%filter, %order, limit=>$n, offset=>$first, light=>1);
345
}
346
347
# ����� ������� ������� ����������...
348
my @columns = $sorted ? ({attr => '_sort_', name => 'N'}) : ();
349
350
# �������� ����� �������, ������� �������� ��� ������� �������� (required_properties -> column)...
351
if ($filter{class} or @documents and $documents[0]) {
352
push @columns,
353
sort {$a->{column} <=> $b->{column}}
354
grep {$_->{column}} ($filter{class} ? $filter{class}->new($keeper)->structure : $documents[0]->structure);
355
}
356
357
# ����������� ����� �������...
358
@columns = (@columns,
359
{attr => '_act_', rusname => '��������'},
360
);
361
</%init>
koi8/plugins/users/comps/contenido/users/store_document_sections.html
1
<%ARGS>
2
$id => undef
3
$class => undef
4
</%ARGS>
5
6
<%INIT>
7
if ($id)
8
{
9
my $document = $keeper->get_document_by_id($id, class=>$class);
10
11
my %sections = ();
12
foreach my $name (keys %ARGS)
13
{
14
if ($name =~ /^section_(\d+)$/)
15
{
16
$sections{$1} = 1;
17
}
18
}
19
my @sections_in_order = ();
20
if ($ARGS{main_section} > 0)
21
{
22
delete $sections{ $ARGS{main_section} };
23
push (@sections_in_order, $ARGS{main_section});
24
}
25
push (@sections_in_order, keys(%sections));
26
27
$document->sections(@sections_in_order);
28
$document->store();
29
30
$r->header_out("Location", "document.html?id=$id&class=$class");
31
$r->status(302);
32
$r->send_http_header();
33
$m->abort();
34
}
35
36
</%init>
koi8/plugins/users/config.tmpl
1
#############################################################################
2
#
3
# ��������� ������� ������� ���������� ������� �������� � config.mk �������
4
# � �������� � ������������ � ������������ �������
5
#
6
#############################################################################
7
8
PLUGINS += users
9
10
PROFILE_DOCUMENT_CLASS = MyProject::Profile
11
REWRITE += PROFILE_DOCUMENT_CLASS
12
13
PROFILE_AUTH_METHOD = LDAP
14
LDAP_LOGIN = <Full LDAP DSN>
15
LDAP_PASSWORD = <LDAP Password>
16
REWRITE += PROFILE_AUTH_METHOD LDAP_LOGIN LDAP_PASSWORD
17
18
PROFILE_AUTH_METHOD = RPC
19
REWRITE += PROFILE_AUTH_METHOD
20
21
22
########################################################################
23
#
24
# PROFILE_DOCUMENT_CLASS
25
# ����������� ��� ���������� ������������ ������ users::Profile
26
# ������� �� �������. � ���� ������ ��� ������ ����� �������
27
# ��������� �����
28
# PROFILE_AUTH_METHOD
29
# ����� �����������. ���� �� �������, ����� ��������������
30
# ��������� �����������. ��������: LDAP, RPC
31
# LDAP_LOGIN � LDAP_PASSWORD
32
# ��������� ������� ������ � LDAP, � ������� ������� ��������������
33
# ����� � ����������� ���� �������������.
34
#
35
########################################################################
koi8/plugins/users/lib/users/Apache.pm
1
package users::Apache;
2
3
use strict;
4
use warnings 'all';
5
6
use users::State;
7
use Contenido::Globals;
8
9
10
sub child_init {
11
# ���������� keeper ������� � keeper �������
12
$keeper->{users} = users::Keeper->new($state->users);
13
}
14
15
sub request_init {
16
}
17
18
sub child_exit {
19
}
20
21
1;
koi8/plugins/users/lib/users/Init.pm
1
package users::Init;
2
3
use strict;
4
use warnings 'all';
5
6
use Contenido::Globals;
7
use users::Apache;
8
use users::Keeper;
9
10
11
# �������� ���� ����������� ������� �������
12
# users::SQL::SomeTable
13
# users::SomeClass
14
Contenido::Init::load_classes(qw(
15
users::SQL::UserProfile
16
17
users::UserProfile
18
users::Section
19
));
20
21
sub init {
22
push @{ $state->{'available_documents'} }, 'users::UserProfile' if $state->{users}->profile_document_class eq 'users::UserProfile';
23
push @{ $state->{'available_sections'} }, 'users::Section';
24
0;
25
}
26
27
1;
koi8/plugins/users/lib/users/Keeper.pm
1
package users::Keeper;
2
3
use strict;
4
use warnings 'all';
5
use base qw(Contenido::Keeper);
6
7
use Digest::MD5;
8
use Contenido::Globals;
9
use Data::Dumper;
10
11
# ----------------------------------------------------------------------------
12
# �������:
13
# ----------------------------------------------------------------------------
14
# check_login: ������� ������������ � �������
15
#
16
# login => login ������������
17
# email => email ������������
18
# ----------------------------------------------------------------------------
19
sub check_login {
20
21
my $self = shift;
22
my %opts = @_;
23
24
return if !$opts{login} && !$opts{email};
25
my $class = $self->state->profile_document_class;
26
my $res = $keeper->get_documents (
27
class => $class,
28
$opts{login} ? (login => $opts{login}) : (),
29
$opts{email} ? (email => lc($opts{email})) : (),
30
count => 1,
31
);
32
return int($res);
33
}
34
35
36
37
# ----------------------------------------------------------------------------
38
# login: ����������� ������������
39
#
40
# login => login ������������
41
# email => e-mail ������������
42
# passwd => ������ ������������
43
# ----------------------------------------------------------------------------
44
sub login {
45
46
my $self = shift;
47
my %opts = @_;
48
49
return if !($opts{login} || $opts{email}) && !$opts{passwd};
50
my $passmd5 = Digest::MD5::md5_hex($opts{passwd});
51
my $class = $self->state->profile_document_class;
52
my $res = $keeper->get_documents (
53
class => $class,
54
$opts{login} ? (login => $opts{login}) : (),
55
$opts{email} ? (email => lc($opts{email})) : (),
56
status => [1,2,3,4,5],
57
return_mode => 'array_ref',
58
);
59
$res = ref $res eq 'ARRAY' ? $res->[0] : undef;
60
return unless ref $res;
61
# warn "Password = ".$opts{passwd}."; Pass MD5 = $passmd5; user MD5 = ".$res->passwd."\n" if $DEBUG;
62
if ($res->passwd eq $passmd5 ) {
63
my $lastlogin = Contenido::DateTime->new ( postgres => $res->lastlogin );
64
my $now = Contenido::DateTime->new;
65
my $then = $now->clone;
66
$then->subtract( hours => 2 );
67
if ( DateTime->compare($then, $lastlogin) == 1 ) {
68
$res->lastlogin( $now->ymd('-').' '.$now->hms );
69
$res->passwd(undef);
70
$res->store;
71
$res->lastlogin( $lastlogin->ymd('-').' '.$lastlogin->hms );
72
}
73
return $res;
74
}else{
75
return;
76
}
77
78
}
79
80
81
82
# ----------------------------------------------------------------------------
83
# confirm: ������������� ��������������
84
#
85
# login => login ������������
86
# email => e-mail ������������
87
# md5 => MD5 ������ ������������
88
# ----------------------------------------------------------------------------
89
sub confirm {
90
91
my $self = shift;
92
my %opts = @_;
93
94
return if !($opts{login} || $opts{email}) && !$opts{md5};
95
my $class = $self->state->profile_document_class;
96
my $res = $keeper->get_documents (
97
class => $class,
98
$opts{login} ? (login => $opts{login}) : (),
99
$opts{email} ? (email => lc($opts{email})) : (),
100
return_mode => 'array_ref',
101
);
102
$res = ref $res eq 'ARRAY' && scalar @$res ? $res->[0] : undef;
103
return unless ref $res;
104
warn "MD5 = ".$opts{md5}."; user MD5 = ".$res->passwd."\n" if $DEBUG;
105
if ($res->passwd eq $opts{md5} ) {
106
my $now = localtime;
107
$res->lastlogin( $now );
108
$res->passwd(undef);
109
$res->status(1);
110
$res->store;
111
return $res;
112
}else{
113
return;
114
}
115
116
}
117
118
119
120
# ----------------------------------------------------------------------------
121
# get_profile: �������� ������� ������������
122
#
123
# id => �� ID
124
# login => �� login
125
# email => �� e-mail
126
# nickname=> �� ��������
127
# status => ������ �� �������
128
# ----------------------------------------------------------------------------
129
sub get_profile {
130
131
my $self = shift;
132
my %opts = @_;
133
134
return if !$opts{login} && !$opts{id} && !$opts{email} && !$opts{nickname};
135
my $class = $self->state->profile_document_class;
136
my $res = $keeper->get_documents (
137
class => $class,
138
%opts,
139
return_mode => 'array_ref',
140
);
141
$res = ref $res eq 'ARRAY' && scalar @$res ? $res->[0] : undef;
142
return $res;
143
}
144
145
1;
koi8/plugins/users/lib/users/Section.pm
1
package users::Section;
2
3
use Contenido::Section;
4
@ISA = ('Contenido::Section');
5
6
sub extra_properties
7
{
8
return (
9
)
10
}
11
12
sub class_name
13
{
14
return '������ ���������������� ��������';
15
}
16
17
sub class_description
18
{
19
return '������ ���������������� ��������';
20
}
21
22
23
1;
koi8/plugins/users/lib/users/SQL/UserProfile.pm
1
package users::SQL::UserProfile;
2
3
use base 'SQL::DocumentTable';
4
5
sub db_table
6
{
7
return 'profiles';
8
}
9
10
my $available_filters = [qw(
11
12
_class_filter
13
_status_filter
14
_in_id_filter
15
_id_filter
16
_name_filter
17
_class_excludes_filter
18
_sfilter_filter
19
_excludes_filter
20
_datetime_filter
21
_date_equal_filter
22
_date_filter
23
_previous_days_filter
24
_s_filter
25
26
_type_filter
27
_login_filter
28
_email_filter
29
_nickname_filter
30
)];
31
32
sub available_filters {
33
return $available_filters;
34
}
35
36
my @required_properties = (
37
{ # ������������� ���������, �������� �� ���� �����...
38
'attr' => 'id',
39
'type' => 'integer',
40
'rusname' => '������������� ���������',
41
'hidden' => 1,
42
'readonly' => 1,
43
'auto' => 1,
44
'db_field' => 'id',
45
'db_type' => 'integer',
46
'db_opts' => "not null default nextval('public.documents_id_seq'::text)",
47
},
48
{ # ����� ���������...
49
'attr' => 'class',
50
'type' => 'string',
51
'rusname' => '����� ���������',
52
'hidden' => 1,
53
'readonly' => 1,
54
'db_field' => 'class',
55
'db_type' => 'varchar(48)',
56
'db_opts' => 'not null',
57
},
58
{ # �.�.�....
59
'attr' => 'name',
60
'type' => 'string',
61
'rusname' => '�.�.�.',
62
'column' => 2,
63
'db_field' => 'name',
64
'db_type' => 'varchar(255)',
65
},
66
{ # ����� �������� ���������, ��������� ����...
67
'attr' => 'ctime',
68
'type' => 'datetime',
69
'rusname' => '����� ��������',
70
'readonly' => 1,
71
'auto' => 1,
72
'hidden' => 1,
73
'db_field' => 'ctime',
74
'db_type' => 'timestamp',
75
'db_opts' => 'not null default now()',
76
'default' => 'CURRENT_TIMESTAMP',
77
},
78
{ # ����� ����������� ���������, ��������� ����...
79
'attr' => 'mtime',
80
'type' => 'datetime',
81
'rusname' => '����� �����������',
82
'hidden' => 1,
83
'auto' => 1,
84
'db_field' => 'mtime',
85
'db_type' => 'timestamp',
86
'db_opts' => 'not null default now()',
87
'default' => 'CURRENT_TIMESTAMP',
88
},
89
{ # ���� ��������
90
'attr' => 'birth',
91
'type' => 'date',
92
'rusname' => '���� ��������',
93
'db_field' => 'dtime',
94
'db_type' => 'timestamp',
95
'default' => 'CURRENT_TIMESTAMP',
96
},
97
{ # ���� � ����� ������...
98
'attr' => 'lastlogin',
99
'type' => 'datetime',
100
'rusname' => '���� � ����� ���������� ������<sup style="color:#888;"> 1)</sup>',
101
'column' => 1,
102
'db_field' => 'lastlogin',
103
'db_type' => 'timestamp',
104
'db_opts' => 'not null default now()',
105
'default' => 'CURRENT_TIMESTAMP',
106
},
107
{ # ������ ������, �������������� ����������� �������...
108
'attr' => 'sections',
109
'type' => 'sections_list',
110
'rusname' => '������',
111
'hidden' => 1,
112
'db_field' => 'sections',
113
'db_type' => 'integer[]',
114
},
115
{ # ���� ���� ������� �������� ����������...
116
'attr' => 'status',
117
'type' => 'status',
118
'rusname' => '������ ������������',
119
'db_field' => 'status',
120
'db_type' => 'integer',
121
},
122
{ # �������������� ���� �������
123
'attr' => 'type',
124
'type' => 'integer',
125
'rusname' => '��� ������������ (project-oriented)',
126
'db_field' => 'type',
127
'db_type' => 'integer',
128
},
129
{ # �������...
130
'attr' => 'nickname',
131
'type' => 'string',
132
'rusname' => '���',
133
'column' => 3,
134
'db_field' => 'nickname',
135
'db_type' => 'text',
136
},
137
{ # Login...
138
'attr' => 'login',
139
'type' => 'string',
140
'rusname' => '�����',
141
'column' => 4,
142
'db_field' => 'login',
143
'db_type' => 'text',
144
},
145
{ # Login method...
146
'attr' => 'login_method',
147
'type' => 'string',
148
'rusname' => '����� �����',
149
'db_field' => 'login_method',
150
'db_type' => 'text',
151
},
152
{ # E-mail...
153
'attr' => 'email',
154
'type' => 'string',
155
'rusname' => 'E-mail (primary)',
156
'db_field' => 'email',
157
'db_type' => 'text',
158
},
159
160
);
161
162
# ----------------------------------------------------------------------------
163
# �������� ������ � ��������, ������ ��� ������� �����!
164
# ��� ����� �������� - ���������� ��� ���� ����������.
165
#
166
# attr - ������������ ��������, �������� ��������;
167
# type - ��� ���������, ��������� ��� ������������;
168
# rusname - ������� ��������, ����� �� ��������� ��� �����������;
169
# hidden - ����� 1, �����
170
# readonly - ������������� ��� ������ ������ ��� ��������� � ����������
171
# db_field - ���� � �������
172
# default - �������� �� ��������� (���� ������ ����� ��� ��������)
173
# ----------------------------------------------------------------------------
174
sub required_properties
175
{
176
return @required_properties;
177
}
178
179
########### FILTERS DESCRIPTION ####################################################################################
180
sub _login_filter {
181
my ($self,%opts)=@_;
182
return undef unless ( exists($opts{login}) );
183
if (exists $opts{ilike} && $opts{ilike} == 1) {
184
return &SQL::Common::_generic_name_filter('d.login', $opts{login}, 0, \%opts);
185
}else{
186
return &SQL::Common::_generic_text_filter('d.login', $opts{login});
187
}
188
}
189
190
sub _email_filter {
191
my ($self,%opts)=@_;
192
return undef unless ( exists($opts{email}) );
193
if (exists $opts{ilike} && $opts{ilike} == 1) {
194
return &SQL::Common::_generic_name_filter('d.email', $opts{email}, 0, \%opts);
195
}else{
196
return &SQL::Common::_generic_text_filter('d.email', $opts{email});
197
}
198
}
199
200
sub _nickname_filter {
201
my ($self,%opts)=@_;
202
return undef unless ( exists($opts{nickname}) );
203
if (exists $opts{ilike} && $opts{ilike} == 1) {
204
return &SQL::Common::_generic_name_filter('d.nickname', $opts{nickname}, 0, \%opts);
205
}else{
206
return &SQL::Common::_generic_text_filter('d.nickname', $opts{nickname});
207
}
208
}
209
210
sub _type_filter {
211
my ($self,%opts)=@_;
212
return undef unless ( exists $opts{type} );
213
return &SQL::Common::_generic_int_filter('d.type', $opts{type});
214
}
215
216
sub _get_orders {
217
my ($self, %opts) = @_;
218
219
if ($opts{order_by}) {
220
return ' order by '.$opts{order_by};
221
} else {
222
return ' order by name ';
223
}
224
return undef;
225
}
226
227
228
1;
koi8/plugins/users/lib/users/State.pm.proto
1
package users::State;
2
3
use strict;
4
use warnings 'all';
5
use vars qw($AUTOLOAD);
6
7
8
sub new {
9
my ($proto) = @_;
10
my $class = ref($proto) || $proto;
11
my $self = {};
12
bless $self, $class;
13
14
# ������� ������������ �������
15
$self->{db_type} = 'none';
16
$self->{db_keepalive} = 0;
17
$self->{db_host} = '';
18
$self->{db_name} = '';
19
$self->{db_user} = '';
20
$self->{db_password} = '';
21
$self->{db_port} = '';
22
$self->{profile_document_class} = '@PROFILE_DOCUMENT_CLASS@' || 'users::UserProfile';
23
24
$self->{data_directory} = '';
25
$self->{images_directory} = '';
26
$self->{binary_directory} = '';
27
$self->{preview} = '';
28
$self->{debug} = '';
29
$self->{store_method} = '';
30
$self->{cascade} = '';
31
$self->{memcached_enable} = '';
32
33
$self->_init_();
34
$self;
35
}
36
37
sub info {
38
my $self = shift;
39
return unless ref $self;
40
41
for (sort keys %{$self->{attributes}}) {
42
my $la = length $_;
43
warn "\t$_".("\t" x (2-int($la/8))).": $self->{$_}\n";
44
}
45
}
46
47
sub _init_ {
48
my $self = shift;
49
50
# ������� ������������ �������
51
$self->{attributes}->{$_} = 'SCALAR' for qw(
52
db_type
53
profile_document_class
54
db_keepalive
55
db_host
56
db_port
57
db_name
58
db_user
59
db_password
60
data_directory images_directory binary_directory preview debug store_method cascade memcached_enable
61
);
62
}
63
64
sub AUTOLOAD {
65
my $self = shift;
66
my $attribute = $AUTOLOAD;
67
68
$attribute =~ s/.*:://;
69
return unless $attribute =~ /[^A-Z]/; # ��������� ������ ���� DESTROY
70
71
if (!exists $self->{attributes}->{$attribute}) {
72
warn "Contenido Error (users::State): ����� ������, ��� �������� �� ���������� ��������������� ��������: ->$attribute()\n";
73
return;
74
}
75
76
$self->{$attribute} = shift @_ if $#_>=0;
77
$self->{$attribute};
78
}
79
80
1;
koi8/plugins/users/lib/users/UserProfile.pm
1
package users::UserProfile;
2
3
use base "Contenido::Document";
4
use Digest::MD5;
5
use Contenido::Globals;
6
7
sub extra_properties
8
{
9
return (
10
{ 'attr' => 'status', 'type' => 'status', 'rusname' => '������ ������������',
11
'cases' => [
12
[0, '������������� ������������'],
13
[1, '���������� ������������'],
14
[5, '��������� ���������'],
15
],
16
},
17
{ 'attr' => 'visibility', 'type' => 'status', 'rusname' => '������� ���������',
18
'cases' => [
19
[0, '������ ����� �������� ����� ������ ���'],
20
[1, '������ ����� �������� ����� ����'],
21
[2, '������ ����� �������� ����� �������'],
22
[3, '������ ����� �������� ����� ������� � ������ ������'],
23
],
24
},
25
{ 'attr' => 'country', 'type' => 'string', 'rusname' => '������' },
26
{ 'attr' => 'region', 'type' => 'string', 'rusname' => '������' },
27
{ 'attr' => 'passwd', 'type' => 'password', 'rusname' => '������', 'rem' => '(<font color="red">�� ������������. ��������� ��� �������� � ��� ���������</font>)' },
28
{ 'attr' => 'confirm', 'type' => 'string', 'rusname' => '��� �������������', hidden => 1 },
29
{ 'attr' => 'secmail', 'type' => 'string', 'rusname' => 'E-mail (secondary)' },
30
{ 'attr' => 'q1', 'type' => 'string', 'rusname' => '����������� ������ 1' },
31
{ 'attr' => 'a1', 'type' => 'string', 'rusname' => '����������� ����� 1' },
32
{ 'attr' => 'q2', 'type' => 'string', 'rusname' => '����������� ������ 2' },
33
{ 'attr' => 'a2', 'type' => 'string', 'rusname' => '����������� ����� 2' },
34
{ 'attr' => 'account', 'type' => 'string', 'rusname' => '����� �� �����' },
35
{ 'attr' => 'interests', 'type' => 'text', 'rusname' => '��������� ��������', rows => 10 },
36
{ 'attr' => 'origin', 'type' => 'text', 'rusname' => '�������', rows => 4 },
37
{ 'attr' => 'avatar', 'type' => 'image', 'rusname' => '������', preview => ['32x32','100x100','120x120','160x160'] },
38
)
39
}
40
41
sub class_name
42
{
43
return '������� ������������';
44
}
45
46
sub class_description
47
{
48
return '������� ������������';
49
}
50
51
52
sub class_table
53
{
54
return 'users::SQL::UserProfile';
55
}
56
57
sub contenido_status_style
58
{
59
my $self = shift;
60
if ( $self->status == 2 ) {
61
return 'color:green;';
62
} elsif ( $self->status == 3 ) {
63
return 'color:olive;';
64
} elsif ( $self->status == 4 ) {
65
return 'color:green;';
66
} elsif ( $self->status == 5 ) {
67
return 'color:red;';
68
}
69
}
70
71
sub pre_store
72
{
73
my $self = shift;
74
75
my $up = $keeper->get_document_by_id ( $self->id,
76
class => 'users::UserProfile'
77
);
78
if ( (ref $up && $self->passwd && $self->passwd ne $up->passwd) || (!ref $up && $self->passwd) ) {
79
warn "Pass = ".$self->passwd."\n" if $DEBUG;
80
my $pass = Digest::MD5::md5_hex($self->passwd);
81
warn "Pass_hex = $pass\n" if $DEBUG;
82
$self->passwd($pass);
83
} elsif ( ref $up && (!$self->passwd || $self->passwd eq $up->passwd ) ) {
84
$self->passwd($up->passwd);
85
}
86
$self->email(lc($self->email));
87
$self->login(lc($self->login));
88
89
my $default_section = $project->s_alias->{users} if ref $project->s_alias eq 'HASH' && exists $project->s_alias->{users};
90
if ( $default_section ) {
91
my $sections = $self->{sections};
92
if ( ref $sections eq 'ARRAY' && scalar @$sections ) {
93
my @new_sects = grep { $_ != $default_section } @$sections;
94
push @new_sects, $default_section;
95
$self->sections(@new_sects);
96
} elsif ( $sections && !ref $sections && $sections != $default_section ) {
97
my @new_sects = ($default_section, $sections);
98
$self->sections(@new_sects);
99
} else {
100
$self->sections($default_section);
101
}
102
}
103
104
return 1;
105
}
106
1;
koi8/plugins/users/sql/TOAST/profiles.sql
1
create table profiles
2
(
3
id integer not null primary key default nextval('public.documents_id_seq'::text),
4
class text not null,
5
ctime timestamp not null default now(),
6
mtime timestamp not null default now(),
7
dtime timestamp,
8
lastlogin timestamp not null default now(),
9
status smallint not null default 0,
10
type integer,
11
sections integer[],
12
name text,
13
nickname text,
14
login text,
15
email text,
16
login_method text default 'local',
17
data text
18
);
19
create index profiles_sections on profiles using gist ( "sections" "gist__int_ops" );
20
create index profiles_lastlogin on profiles (lastlogin);
21
create unique index profiles_login on profiles (login);
22
create unique index profiles_email on profiles (email) where email is not null and email != '';
Небольшая справка по веткам
cnddist – контейнер, в котором хранятся все дистрибутивы всех библиотек и программных пакетов, которые использовались при построении различных версий Contenido. Если какой-то библиотеки в данном хранилище нет, инсталлятор сделает попытку "подтянуть" ее с веба (например, с CPAN). Если библиотека слишком старая, есть очень большая вероятность, что ее там уже нет. Поэтому мы храним весь хлам от всех сборок. Если какой-то дистрибутив вдруг отсутствует в cnddist - напишите нам, мы положим его туда.
koi8 – отмирающая ветка, чей код, выдача и все внутренние библиотеки заточены на кодировку KOI8-R. Вносятся только те дополнения, которые касаются внешнего вида и функционала админки, баги ядра, обязательные обновления портов и мелочи, которые легко скопипастить. В дальнейшем планируется полная остановка поддержки по данной ветке.
utf8 – актуальная ветка, заточенная под UTF-8.
Внутри каждой ветки: core – исходники ядра; install – скрипт установки инсталляции; plugins – плагины; samples – "готовые к употреблению" проекты, которые можно поставить, запустить и посмотреть, как они работают.