use PciIds::Html::Users;
use PciIds::Html::Forms;
use PciIds::Notifications;
+use PciIds::Address;
use PciIds::Log;
use Apache2::Const qw(:common :http);
-sub genNewAdminForm( $$$$ ) {
- my( $req, $args, $tables, $error ) = @_;
- genHtmlHead( $req, 'Administration ‒ pending events', undef );
- print "<h1>Administration ‒ pending events</h1>\n";
- print "<div class='error'>".$error."</div>\n" if( defined $error );
- print '<form name="admin" id="admin" class="admin" method="POST" action="'.setAddrPrefix( $req->uri(), 'mods' ).buildExcept( 'action', $args )."?action=admin\">\n";
+sub safeEncode( $ ) {
+ my( $text ) = @_;
+ return encode( $text ) if defined $text;
+ return '';
+}
+
+sub mailEncode( $ ) {
+ my( $email ) = @_;
+ return '' unless defined $email;
+ return "<a href='mailto:$email'>".encode( $email )."</a>";
+}
+
+sub genNewAdminForm( $$$$$ ) {
+ my( $req, $args, $tables, $error, $auth ) = @_;
+ my $address = PciIds::Address::new( $req->uri() );
+ my $prefix = $address->get();
+ $prefix = '' if( $args->{'global'} );
+ my $caption = 'Administration '.( $args->{'global'} ? '(Global)' : '('.encode( $address->pretty() ).')' );
+ genHtmlHead( $req, $caption, undef );
+ my $glob = delete $args->{'global'};
+ genCustomHead( $req, $args, $address, $caption, [ $address->canAddItem() ? [ 'Add item', 'newitem' ] : (), $address->canDiscuss() ? [ 'Discuss', 'newhistory' ] : (), $glob ? [ 'Local', 'admin' ] : [ 'Global', 'admin?global=1' ], [ 'Help', 'help', 'admin' ], [ '', 'jump' ] ], [ [ 'Log out', 'logout' ] ] );
+ print "<div class='error'>$error</div>\n" if( defined $error );
+ print "<form name='admin' id='admin' class='admin' method='POST' action=''>\n";
my $lastId;
my $started = 0;
my $cnt = 0;
my $hiscnt = 0;
my $subcnt;
- foreach( @{$tables->adminDump()} ) {
- my( $locId, $actName, $actDescription, $actCom, $actUser, $actText,
- $com, $text, $name, $description, $user ) = @{$_};
+ print "<p><input type='checkbox' name='default-seen' value='default-seen' checked='checked'> Any action approves all discussion\n";
+ print "<table class='admin'>\n";
+ print "<col class='id-col'><col class='name-col'><col class='note-col'><col class='disc-col'><col class='auth-col'><col class='control-col' span='3'>\n";
+ print "<tr class='head'><th>ID<th>Name<th>Note<th>Discussion<th>Author<th>Ok<th>Sel<th>Del\n";
+ foreach( @{$tables->adminDump( $prefix )} ) {
+ my( $locId, $actName, $actNote, $actHist, $actUser, $actDisc,
+ $hist, $disc, $name, $note, $user ) = @{$_};
if( !defined( $lastId ) || ( $lastId ne $locId ) ) {
+ last if( $hiscnt > 80 );
$lastId = $locId;
- print "</div>\n" if( $started );
$started = 1;
- print "<div class='".( defined( $actCom ) ? 'item' : 'unnamedItem' )."'>\n";
my $addr = PciIds::Address::new( $locId );
- print "<h3><a href='/read/".$addr->get()."/'>".encode( $addr->pretty() )."</a></h3>\n";
- print htmlDiv( 'name', '<p>'.encode( $actName ) ) if( defined( $actName ) );
- print htmlDiv( 'description', '<p>'.encode( $actDescription ) ) if( defined( $actDescription ) );
- print '<p>'.encode( $actText ) if( defined( $actText ) );
- print '<p><a class="navigation" href="/read/'.$addr->parent()->get().'/">'.encode( $addr->parent()->pretty() )."</a>" if( defined( $addr->parent() ) );
- print htmlDiv( 'author', '<p>'.encode( $actUser ) ) if( defined( $actUser ) );
- print "<input type='hidden' name='subcnt-$cnt' value='$subcnt'>\n" if( defined( $subcnt ) );
+ if( defined( $actHist ) ) {
+ print "<tr class='item'>";
+ } else {
+ print "<tr class='unnamedItem'>";
+ }
+ print "<td><a href='/read/".$addr->get()."'>".encode( $addr->pretty() )."</a><td>".safeEncode( $actName )."<td>".safeEncode( $actNote )."<td>".safeEncode( $actDisc )."<td>".mailEncode( $actUser );
+
+ print "<input type='hidden' name='loc-$cnt-subcnt' value='$subcnt'>" if( $subcnt );
$subcnt = 0;
$cnt++;
print "<input type='hidden' name='loc-$cnt' value='".$addr->get()."'>\n";
- print "<p><input type='radio' name='action-$cnt' value='ignore' checked='checked'> I will decide later.\n";
- if( defined( $actCom ) ) {
- print "<br><input type='radio' name='action-$cnt' value='keep'> Keep current name.\n";
+ print "<td class='empty'>";
+ print "<td><input type='radio' name='loc-$cnt-sel' value='curr' checked='checked'>";
+ if( hasRight( $auth->{'accrights'}, 'prune' ) || ( !defined $actHist && !$tables->hasChildren( $addr->get() ) ) ) {
+ print "<td><input type='checkbox' name='loc-$cnt-del' value='del'>\n";
+ } else {
+ print "<td class='empty'>";
}
- print "<br><input type='radio' name='action-$cnt' value='delete'> Delete item.\n";
- print "<br>Add comment:\n";
- print "<br><table>\n";
- print "<tr><td>Set name:<td><input type='text' name='name-$cnt' maxlength='200'>\n";
- print "<tr><td>Set description:<td><input type='text' name='description-$cnt' maxlength='1024'>\n";
- print "<tr><td>Text:<td><textarea name='text-$cnt' rows='2'></textarea>\n";
- print "</table>\n";
+ print "<tr class='new'><td>New:<td><input type='text' name='name-$cnt' class='text'><td><input type='text' name='note-$cnt' class='text'><td><textarea name='disc-$cnt'></textarea>\n";
+ print "<td colspan='3'>";
+ genPathBare( $req, $addr, 0, 0 );
+ print "<td><input type='checkbox' name='loc-$cnt-softdel' value='del'>\n";
}
- print "<div class='unseen-comment'>\n";
- print "<p class='name'>".encode( $name ) if( defined( $name ) );
- print "<p class='description'>".encode( $description ) if( defined( $description ) );
- print '<p>'.encode( $text ) if( defined( $text ) );
- print "<p class='author'>".encode( $user ) if( defined( $user ) );
- print "<p><input type='radio' name='action-$cnt' value='set-$com'> Use this one.\n" if( defined( $name ) && ( $name ne "" ) );
+ print "<tr class='unseen-history'><td class='empty'><td>".safeEncode( ( defined $name && $name eq '' ) ? 'Deletion request' : $name )."<td>".safeEncode( $note )."<td>".safeEncode( $disc )."<td>".mailEncode( $user );
$hiscnt ++;
- print "<br><input type='checkbox' name='delete-$hiscnt' value='delete-$com'> Delete comment.\n";
- print "</div>\n";
$subcnt ++;
- print "<input type='hidden' name='sub-$cnt-$subcnt' value='$com'>\n";
+ print "<input type='hidden' name='his-$cnt-$subcnt' value='$hist'>";
+ print "<td><input type='checkbox' name='appr-$hiscnt' value='appr-$hist'>";
+ if( defined $name ) {
+ print "<td><input type='radio' name='loc-$cnt-sel' value='$hist'>";
+ } else {
+ print "<td class='empty'>";
+ }
+ print "<td><input type='checkbox' name='del-$hiscnt' value='del-$hist'>";
+ print "<input type='hidden' name='owner-$hist' value='$lastId'>\n";
}
+ print "</table>\n";
print "<input type='hidden' name='subcnt-$cnt' value='$subcnt'>\n" if( defined( $subcnt ) );
if( $started ) {
- print "</div>\n" if( $started );
+ print "<input type='hidden' name='loc-$cnt-subcnt' value='$subcnt'>" if( $subcnt );
print "<p><input type='submit' name='submit' value='Submit'>\n";
print "<input type='hidden' name='max-cnt' value='$cnt'><input type='hidden' name='max-hiscnt' value='$hiscnt'>\n";
} else {
- print "<p>No pending comments.\n";
+ print "<p>No pending items.\n";
}
print "</form>\n";
genHtmlTail();
sub adminForm( $$$$ ) {
my( $req, $args, $tables, $auth ) = @_;
if( defined( $auth->{'authid'} ) && hasRight( $auth->{'accrights'}, 'validate' ) ) {
- return genNewAdminForm( $req, $args, $tables, undef );
+ return genNewAdminForm( $req, $args, $tables, undef, $auth );
} else {
return notLoggedComplaint( $req, $args, $auth );
}
}
-sub markAllChecked( $$$$ ) {
- my( $tables, $itemNum, $deleted, $authid ) = @_;
- my $i;
- my $subcnt = getFormValue( "subcnt-$itemNum", 0 );
- for( $i = 1; $i <= $subcnt; ++ $i ) {
- my $id = getFormValue( "sub-$itemNum-$i", undef );
- next unless( defined( $id ) );
- next if( $deleted->{$id} );#Do not update this one, already deleted
- $tables->markChecked( $id );
- tulog( $authid, "Comment checked $id" );
+my $errors;
+
+sub appendError( $ ) {
+ if( $errors eq '' ) {
+ $errors = "<p>".shift;
+ } else {
+ $errors .= "<br>".shift;
}
}
my( $req, $args, $tables, $auth ) = @_;
my $authid = $auth->{'authid'};
if( defined( $authid ) && hasRight( $auth->{'accrights'}, 'validate' ) ) {
- my $errors = '';
- my %deleted;
+ my( %deleted, %approved );
my $maxcnt = getFormValue( 'max-cnt', 0 );
my $maxhiscnt = getFormValue( 'max-hiscnt', 0 );
+ $errors = '';
+ # Scan for approved and deleted items
for( my $i = 1; $i <= $maxhiscnt; $i ++ ) {
- my $del = getFormValue( "delete-$i", "" );
- $del =~ s/^delete-//;
- if( $del ne '' ) {
- $deleted{$del} = 1;
- $tables->deleteHistory( $del );
- tulog( $authid, "Comment deleted $del" );
+ my( $del ) = getFormValue( "del-$i", '' ) =~ /^del-(\d+)$/;
+ $deleted{$del} = 1 if( defined $del && $del ne '' );
+ my( $appr ) = getFormValue( "appr-$i", '' ) =~ /^appr-(\d+)$/;
+ $approved{$appr} = 1 if( defined $appr && $appr ne '' );
+ }
+ for( my $i = 1; $i <= $maxcnt; $i ++ ) {
+ my( $sel ) = getFormValue( "loc-$i-sel", '' ) =~ /^(\d+)$/;
+ $approved{$sel} = 1 if( defined $sel && $sel ne '' );
+ }
+ # Check for collisions
+ my %collision;
+ foreach my $id ( keys %deleted ) {
+ if( $approved{$id} ) {
+ my $owner = getFormValue( "owner-$id", '' );
+ appendError( "You can not approve and delete history at the same time, not modifying item ".PciIds::Address::new( $owner )->pretty() );
+ $collision{$owner} = $_;
+ delete $deleted{$id};
+ delete $approved{$id};
}
}
+ #Do the deletes and approves
+ foreach my $del ( keys %deleted ) {
+ $tables->deleteHistory( $del );
+ tulog( $authid, "Discussion deleted $del" );
+ }
+ foreach my $appr ( keys %approved ) {
+ $tables->markChecked( $appr );
+ tulog( $authid, "Discussion checked $appr" );
+ }
+ #Handle the items
+ my $defaultSeen = getFormValue( 'default-seen', '' ) =~ /^default-seen$/;
for( my $i = 1; $i <= $maxcnt; $i ++ ) {
- my $action = getFormValue( "action-$i", 'ignore' );
- my $loc = getFormValue( "loc-$i", undef );
- next unless( defined( $loc ) );
- my( $text, $name, $description ) = (
- getFormValue( "text-$i", undef ),
- getFormValue( "name-$i", undef ),
- getFormValue( "description-$i", undef ) );
- if( defined( $description ) && ( $description ne '' ) && ( !defined( $name ) || ( length $name < 3 ) ) ) {
- if( $errors eq '' ) {
- $errors = '<p>';
- } else {
- $errors .= '<br>';
- }
- $errors .= "$loc - You need to provide name if you provide description\n";
+ my $addr = PciIds::Address::new( getFormValue( "loc-$i", '' ) );
+ next if $collision{$addr->get()};
+ next unless defined $addr;
+ my $del = getFormValue( "loc-$i-del", '' );
+ if( defined $del && $del eq 'del' && ( hasRight( $auth->{'accrights'}, 'prune' ) || ( !$tables->hasChildren( $addr->get() ) && !$tables->hasMain( $addr->get() ) ) ) ) {
+ $tables->deleteItem( $addr->get() );
+ tulog( $authid, "Item deleted (recursive) ".$addr->get() );
next;
}
- if( ( defined( $name ) && ( length $name >= 3 ) ) || ( defined( $text ) && ( $text ne '' ) ) ) { #Submited comment
- my $addr = PciIds::Address::new( $loc );
- my $comId = $tables->submitComment( { 'name' => $name, 'description' => $description, 'explanation' => $text }, $auth, $addr );
- my $main = defined $name && ( $name ne '' );
- notify( $tables, $addr->get(), $comId, $main ? 2 : 0, $main ? 2 : 1 );
- $tables->markChecked( $comId );
- tulog( $authid, "Comment created (admin) $comId $loc ".logEscape( $name )." ".logEscape( $description )." ".logEscape( $text ) );
- if( defined( $name ) && ( length $name >= 3 ) ) {
- $tables->setMainComment( $loc, $comId );
- tulog( $authid, "Item main comment changed $loc $comId" );
- $action = 'keep';
- }
+ my $name = getFormValue( "name-$i", undef );
+ $name = undef if defined $name && $name eq '';
+ my $note = getFormValue( "note-$i", undef );
+ $note = undef if defined $note && $note eq '';
+ my $discussion = getFormValue( "disc-$i", '' );
+ $discussion = undef if defined $discussion && $discussion eq '';
+ my $delete = 0;
+ if( getFormValue( "loc-$i-softdel", '' ) =~ /^del$/ ) {
+ $delete = 1;
+ $name = undef;
+ $note = undef;
}
- next if( $action eq 'ignore' );
- if( $action eq 'keep' ) {
- markAllChecked( $tables, $i, \%deleted, $authid );
- } elsif( $action eq 'delete' ) {
- eval {
- $tables->deleteItem( $loc );
- tulog( $authid, "Item deleted (recursive) $loc" );
- } #Ignore if it was already deleted by superitem
- } elsif( my( $setId ) = ( $action =~ /set-(.*)/ ) ) {
- next if( $deleted{$setId} );
- $tables->setMainComment( $loc, $setId );
- notify( $tables, $loc, $setId, 2, 2 );
- tulog( $authid, "Item main comment changed $loc $setId" );
- markAllChecked( $tables, $i, \%deleted, $authid );
+ if( defined $note && !defined $name ) {
+ appendError( "You must specify name if you set note at item ".$addr->pretty() );
+ next;
+ }
+ my( $select ) = getFormValue( "loc-$i-sel", '' ) =~ /^(\d+)$/;
+ my $action = 0;
+ if( defined $name || defined $discussion || $delete ) {
+ my $histId = $tables->submitHistory( { 'name' => $name, 'note' => $note, 'text' => $discussion, 'delete' => $delete }, $auth, $addr );
+ $tables->markChecked( $histId );
+ $select = $histId if defined $name || $delete;
+ tulog( $authid, "Discussion submited (admin) $histId ".$addr->get()." ".logEscape( $name )." ".logEscape( $note )." ".logEscape( $discussion ) );
+ $action = 1;
+ notify( $tables, $addr->get(), $histId, defined $name ? 1 : 0, 1 );
+ }
+ if( defined $select && select ne '' ) {
+ $tables->setMainHistory( $addr->get(), $select );
+ tulog( $authid, "Item main history changed ".$addr->get()." $select" );
+ $action = 1;
+ notify( $tables, $addr->get(), $select, 2, 2 );
+ }
+ if( $action && $defaultSeen ) {#Approve anything in this item
+ my $subcnt = getFormValue( "loc-$i-subcnt", 0 );
+ for( my $j = 1; $j <= $subcnt; $j ++ ) {
+ my( $id ) = getFormValue( "his-$i-$j", '' ) =~ /^(\d+)$/;
+ next unless defined $id;
+ next if $approved{$id} || $deleted{$id};
+ $tables->markChecked( $id );
+ tulog( $authid, "Discussion checked $id" );
+ }
}
}
- return genNewAdminForm( $req, $args, $tables, $errors );
+ return genNewAdminForm( $req, $args, $tables, $errors, $auth );
} else {
return notLoggedComplaint( $req, $args, $auth );
}