]> mj.ucw.cz Git - pciids.git/blob - PciIds/Html/Admin.pm
Admin button for more items
[pciids.git] / PciIds / Html / Admin.pm
1 package PciIds::Html::Admin;
2 use strict;
3 use warnings;
4 use PciIds::Users;
5 use PciIds::Html::Util;
6 use PciIds::Html::Users;
7 use PciIds::Html::Forms;
8 use PciIds::Notifications;
9 use PciIds::Address;
10 use PciIds::Log;
11 use Apache2::Const qw(:common :http);
12
13 sub safeEncode( $ ) {
14         my( $text ) = @_;
15         return encode( $text ) if defined $text;
16         return '';
17 }
18
19 sub mailEncode( $$ ) {
20         my( $email, $user ) = @_;
21         return '' unless defined $email;
22         ( $user ) = $email =~ /^(.*)@/ unless( defined $user );
23         return "<a href='mailto:$email'>".encode( $user )."</a>";
24 }
25
26 sub genHist( $$$$$$$$$$$ ) {
27         my( $class, $email, $login, $time, $name, $note, $disc, $selname, $selvalue, $delname, $delvalue ) = @_;
28         print "<tr class='$class'><td>";
29         print "<span class='author'>".mailEncode( $email, $login )."<br></span>" if( defined $email );
30         print "<span class='time'>".safeEncode( $time )."</span>";
31         print "<td>";
32         if( defined $name ) {
33                 if( $name eq '' ) {
34                         print "<span class='name'>Deletion request<br></span>";
35                 } else {
36                         print "<span class='name'>Name: ".encode( $name )."<br></span>";
37                 }
38         }
39         print "<span class='note'>Note: ".encode( $note )."<br></span>" if defined $note && $note ne '';
40         print safeEncode( $disc );
41         print "<td class='selects'><input type='radio' name='$selname' 'value='$selvalue'>\n";
42         print "<td class='deletes'><input type='checkbox' name='$delname' value='$delvalue'>\n" if defined $delname
43 }
44
45 sub genNewForm( $ ) {
46         my( $num ) = @_;
47         print "<tr class='newhistory'><td>TODO combo";
48         print "<td><span class='newname'>Name: <input type='text' name='name-$num'></span><span class='newnote'>Note: <input type='note-$num'></span><br>\n";
49         print "<textarea name='disc-$num'></textarea>\n";
50         print "<td><td class='deletes'><input type='checkbox' name='loc-$num-softdel' value='del'>\n";
51 }
52
53 sub genNewAdminForm( $$$$$ ) {
54         my( $req, $args, $tables, $error, $auth ) = @_;
55         my $address = PciIds::Address::new( $req->uri() );
56         my $prefix = $address->get();
57         my $limit = delete $args->{'limit'};
58         $prefix = '' if( $args->{'global'} );
59         my $caption = 'Administration '.( $args->{'global'} ? '(Global)' : '('.encode( $address->pretty() ).')' );
60         genHtmlHead( $req, $caption, undef );
61         my $glob = delete $args->{'global'};
62         my $moreButt = 'admin?limit='.( $limit ? int( $limit * 2 ) : 160 ).buildExcept( 'action', $args );
63         $moreButt .= '?global='.$glob if defined $glob;
64         genCustomHead( $req, $args, $address, $caption, [ $address->canAddItem() ? [ 'Add item', 'newitem' ] : (), $address->canDiscuss() ? [ 'Discuss', 'newhistory' ] : (), $glob ? [ 'Local', 'admin'.buildExcept( 'action', $args ) ] : [ 'Global', 'admin?global=1'.buildExcept( 'action', $args ) ], [ 'More items', $moreButt ], [ 'Help', 'help', 'admin' ], [ '', 'jump' ] ], [ [ 'Log out', 'logout' ] ] );
65         print "<div class='error'>$error</div>\n" if( defined $error );
66         print "<form name='admin' id='admin' class='admin' method='POST' action=''>\n";
67         my $lastId;
68         my $started = 0;
69         my $cnt = 0;
70         my $hiscnt = 0;
71         my $subcnt;
72         foreach( @{$tables->adminDump( $prefix, $limit )} ) {
73                 my( $locId, $actName, $actNote, $actHist, $actEmail, $actLogin, $actDisc, $actTime,
74                         $hist, $disc, $name, $note, $email, $login, $time ) = @{$_};
75                 if( !defined( $lastId ) || ( $lastId ne $locId ) ) {
76                         last if( $hiscnt > ( defined $limit ? $limit : 80 ) );
77                         $lastId = $locId;
78                         if( $started ) {
79                                 genNewForm( $cnt );
80                                 print "</table>\n";
81                         } else {
82                                 $started = 1;
83                         }
84                         my $addr = PciIds::Address::new( $locId );
85                         if( defined( $actHist ) ) {
86                                 print "<table class='item'>\n";
87                         } else {
88                                 print "<table class='unnamedItem'>\n";
89                         }
90                         print "<col class='author'><col class='main'><col class='controls' span='2'>\n";
91                         print "<tr class='label'><p>\n";
92                         print "<td class='path' colspan='2'>";
93                         genPathBare( $req, $addr, 0, 0, 0 );
94                         print "<input type='hidden' name='loc-$cnt-subcnt' value='$subcnt'>" if( $subcnt );
95                         $subcnt = 0;
96                         $cnt ++;
97                         print "<td class='selects'><input type='radio' name='loc-$cnt-sel' value='curr' checked='checked'>";
98                         print "<td class='deletes'><input type='checkbox' name='loc-$cnt-del' value='del'>" if hasRight( $auth->{'accrights'}, 'prune' ) || ( !defined $actHist && !$tables->hasChildren( $addr->get() ) );
99                         genHist( 'main-history', $actEmail, $actLogin, $actTime, $actName, $actNote, $actDisc, "loc-$cnt-sel", 'seen', undef, undef ) if( defined $actHist );
100                 }
101                 $hiscnt ++;
102                 $subcnt ++;
103                 genHist( 'unseen-history', $email, $login, $time, $name, $note, $disc, "loc-$cnt-sel", $hist, "del-$hiscnt", "del-$hist" );
104         }
105         print "<input type='hidden' name='subcnt-$cnt' value='$subcnt'>\n" if( defined( $subcnt ) );
106         if( $started ) {
107                 genNewForm( $cnt );
108                 print "</table>\n";
109                 print "<p><input type='submit' name='submit' value='Submit'>\n";
110                 print "<input type='hidden' name='loc-$cnt-subcnt' value='$subcnt'>" if( $subcnt );
111                 print "<input type='hidden' name='max-cnt' value='$cnt'><input type='hidden' name='max-hiscnt' value='$hiscnt'>\n";
112         } else {
113                 print "<p>No pending items.\n";
114         }
115         print "</form>\n";
116         genHtmlTail();
117         return OK;
118 }
119
120 sub adminForm( $$$$ ) {
121         my( $req, $args, $tables, $auth ) = @_;
122         if( defined( $auth->{'authid'} ) && hasRight( $auth->{'accrights'}, 'validate' ) ) {
123                 return genNewAdminForm( $req, $args, $tables, undef, $auth );
124         } else {
125                 return notLoggedComplaint( $req, $args, $auth );
126         }
127 }
128
129 my $errors;
130
131 sub appendError( $ ) {
132         if( $errors eq '' ) {
133                 $errors = "<p>".shift;
134         } else {
135                 $errors .= "<br>".shift;
136         }
137 }
138
139 sub submitAdminForm( $$$$ ) {
140         my( $req, $args, $tables, $auth ) = @_;
141         my $authid = $auth->{'authid'};
142         if( defined( $authid ) && hasRight( $auth->{'accrights'}, 'validate' ) ) {
143                 my( %deleted, %approved );
144                 my $maxcnt = getFormValue( 'max-cnt', 0 );
145                 my $maxhiscnt = getFormValue( 'max-hiscnt', 0 );
146                 $errors = '';
147                 # Scan for approved and deleted items
148                 for( my $i = 1; $i <= $maxhiscnt; $i ++ ) {
149                         my( $del ) = getFormValue( "del-$i", '' ) =~ /^del-(\d+)$/;
150                         $deleted{$del} = 1 if( defined $del && $del ne '' );
151                         my( $appr ) = getFormValue( "appr-$i", '' ) =~ /^appr-(\d+)$/;
152                         $approved{$appr} = 1 if( defined $appr && $appr ne '' );
153                 }
154                 for( my $i = 1; $i <= $maxcnt; $i ++ ) {
155                         my( $sel ) = getFormValue( "loc-$i-sel", '' ) =~ /^(\d+)$/;
156                         $approved{$sel} = 1 if( defined $sel && $sel ne '' );
157                 }
158                 # Check for collisions
159                 my %collision;
160                 foreach my $id ( keys %deleted ) {
161                         if( $approved{$id} ) {
162                                 my $owner = getFormValue( "owner-$id", '' );
163                                 appendError( "You can not approve and delete history at the same time, not modifying item ".PciIds::Address::new( $owner )->pretty() );
164                                 $collision{$owner} = $_;
165                                 delete $deleted{$id};
166                                 delete $approved{$id};
167                         }
168                 }
169                 #Do the deletes and approves
170                 foreach my $del ( keys %deleted ) {
171                         $tables->deleteHistory( $del );
172                         tulog( $authid, "Discussion deleted $del" );
173                 }
174                 foreach my $appr ( keys %approved ) {
175                         $tables->markChecked( $appr );
176                         tulog( $authid, "Discussion checked $appr" );
177                 }
178                 #Handle the items
179                 my $defaultSeen = getFormValue( 'default-seen', '' ) =~ /^default-seen$/;
180                 for( my $i = 1; $i <= $maxcnt; $i ++ ) {
181                         my $addr = PciIds::Address::new( getFormValue( "loc-$i", '' ) );
182                         next if $collision{$addr->get()};
183                         next unless defined $addr;
184                         my $del = getFormValue( "loc-$i-del", '' );
185                         if( defined $del && $del eq 'del' && ( hasRight( $auth->{'accrights'}, 'prune' ) || ( !$tables->hasChildren( $addr->get() ) && !$tables->hasMain( $addr->get() ) ) ) ) {
186                                 $tables->deleteItem( $addr->get() );
187                                 tulog( $authid, "Item deleted (recursive) ".$addr->get() );
188                                 next;
189                         }
190                         my $name = getFormValue( "name-$i", undef );
191                         $name = undef if defined $name && $name eq '';
192                         my $note = getFormValue( "note-$i", undef );
193                         $note = undef if defined $note && $note eq '';
194                         my $discussion = getFormValue( "disc-$i", '' );
195                         $discussion = undef if defined $discussion && $discussion eq '';
196                         my $delete = 0;
197                         if( getFormValue( "loc-$i-softdel", '' ) =~ /^del$/ ) {
198                                 $delete = 1;
199                                 $name = undef;
200                                 $note = undef;
201                         }
202                         if( defined $note && !defined $name ) {
203                                 appendError( "You must specify name if you set note at item ".$addr->pretty() );
204                                 next;
205                         }
206                         my( $select ) = getFormValue( "loc-$i-sel", '' ) =~ /^(\d+)$/;
207                         my $action = 0;
208                         if( defined $name || defined $discussion || $delete ) {
209                                 my $histId = $tables->submitHistory( { 'name' => $name, 'note' => $note, 'text' => $discussion, 'delete' => $delete }, $auth, $addr );
210                                 $tables->markChecked( $histId );
211                                 $select = $histId if defined $name || $delete;
212                                 tulog( $authid, "Discussion submited (admin) $histId ".$addr->get()." ".logEscape( $name )." ".logEscape( $note )." ".logEscape( $discussion ) );
213                                 $action = 1;
214                                 notify( $tables, $addr->get(), $histId, defined $name ? 1 : 0, 1 );
215                         }
216                         if( defined $select && select ne '' ) {
217                                 $tables->setMainHistory( $addr->get(), $select );
218                                 tulog( $authid, "Item main history changed ".$addr->get()." $select" );
219                                 $action = 1;
220                                 notify( $tables, $addr->get(), $select, 2, 2 );
221                         }
222                         if( $action && $defaultSeen ) {#Approve anything in this item
223                                 my $subcnt = getFormValue( "loc-$i-subcnt", 0 );
224                                 for( my $j = 1;  $j <= $subcnt; $j ++ ) {
225                                         my( $id ) = getFormValue( "his-$i-$j", '' ) =~ /^(\d+)$/;
226                                         next unless defined $id;
227                                         next if $approved{$id} || $deleted{$id};
228                                         $tables->markChecked( $id );
229                                         tulog( $authid, "Discussion checked $id" );
230                                 }
231                         }
232                 }
233                 return genNewAdminForm( $req, $args, $tables, $errors, $auth );
234         } else {
235                 return notLoggedComplaint( $req, $args, $auth );
236         }
237 }
238
239 1;