Diff for /loncom/interface/slotrequest.pm between versions 1.58 and 1.95

version 1.58, 2006/04/24 23:23:02 version 1.95, 2009/04/23 17:33:54
Line 36  use Apache::lonlocal; Line 36  use Apache::lonlocal;
 use Apache::lonnet;  use Apache::lonnet;
 use Apache::lonnavmaps();  use Apache::lonnavmaps();
 use Date::Manip;  use Date::Manip;
   use lib '/home/httpd/lib/perl/';
   use LONCAPA;
   
 sub fail {  sub fail {
     my ($r,$code)=@_;      my ($r,$code)=@_;
     if ($code eq 'not_valid') {      if ($code eq 'not_valid') {
  $r->print('<p>'.&mt('Unable to understand what resource you wanted to sign up for.').'</p>');   $r->print('<p>'.&mt('Unable to understand what resource you wanted to sign up for.').'</p>');
       } elsif ($code eq 'not_available') {
    $r->print('<p>'.&mt('No slots are available.').'</p>');
     } elsif ($code eq 'not_allowed') {      } elsif ($code eq 'not_allowed') {
  $r->print('<p>'.&mt('Not allowed to sign up or change reservations at this time.').'</p>');   $r->print('<p>'.&mt('Not allowed to sign up or change reservations at this time.').'</p>');
     } else {      } else {
Line 53  sub fail { Line 56  sub fail {
 }  }
   
 sub start_page {  sub start_page {
     my ($r,$title)=@_;      my ($r,$title,$brcrum)=@_;
     $r->print(&Apache::loncommon::start_page($title));      my $args;
       if (ref($brcrum) eq 'ARRAY') {
           $args = {bread_crumbs => $brcrum};
       }
       $r->print(&Apache::loncommon::start_page($title,undef,$args));
 }  }
   
 sub end_page {  sub end_page {
Line 74  sub end_page { Line 81  sub end_page {
 =cut  =cut
   
 sub get_course {  sub get_course {
     (undef,my $courseid)=&Apache::lonxml::whichuser();      (undef,my $courseid)=&Apache::lonnet::whichuser();
     my $cdom=$env{'course.'.$courseid.'.domain'};      my $cdom=$env{'course.'.$courseid.'.domain'};
     my $cnum=$env{'course.'.$courseid.'.num'};      my $cnum=$env{'course.'.$courseid.'.num'};
     return ($cnum,$cdom);      return ($cnum,$cdom);
Line 87  sub get_reservation_ids { Line 94  sub get_reservation_ids {
   
     my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,      my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
        "^$slot_name\0");         "^$slot_name\0");
     if (&network_error(%consumed)) {       if (&Apache::lonnet::error(%consumed)) { 
  return 'error: Unable to determine current status';   return 'error: Unable to determine current status';
     }      }
     my ($tmp)=%consumed;      my ($tmp)=%consumed;
Line 124  sub check_for_reservation { Line 131  sub check_for_reservation {
     my ($cnum,$cdom)=&get_course();      my ($cnum,$cdom)=&get_course();
     my %slots=&Apache::lonnet::get('slots', [@slots], $cdom, $cnum);      my %slots=&Apache::lonnet::get('slots', [@slots], $cdom, $cnum);
   
     if (&network_error($student) || &network_error($course)  ||      if (&Apache::lonnet::error($student) 
  &network_error(%slots)) {   || &Apache::lonnet::error($course)
    || &Apache::lonnet::error(%slots)) {
  return 'error: Unable to determine current status';   return 'error: Unable to determine current status';
     }          }    
     my @got;      my @got;
     foreach my $slot_name (sort {      my @sorted_slots = &Apache::loncommon::sorted_slots(\@slots,\%slots);
  if (ref($slots{$a}) && ref($slots{$b})) {      foreach my $slot_name (@sorted_slots) {
     return $slots{$a}{'starttime'} <=> $slots{$b}{'starttime'}  
  }  
  if (ref($slots{$a})) { return -1;}  
  if (ref($slots{$b})) { return 1;}  
  return 0;  
     } @slots) {  
  next if (!defined($slots{$slot_name}) ||   next if (!defined($slots{$slot_name}) ||
  !ref($slots{$slot_name}));   !ref($slots{$slot_name}));
  &Apache::lonxml::debug(time." $slot_name ".   &Apache::lonxml::debug(time." $slot_name ".
Line 161  sub check_for_reservation { Line 163  sub check_for_reservation {
 sub get_consumed_uniqueperiods {  sub get_consumed_uniqueperiods {
     my ($slots) = @_;      my ($slots) = @_;
     my $navmap=Apache::lonnavmaps::navmap->new;      my $navmap=Apache::lonnavmaps::navmap->new;
       if (!defined($navmap)) {
           return 'error: Unable to determine current status';
       }
     my @problems = $navmap->retrieveResources(undef,      my @problems = $navmap->retrieveResources(undef,
       sub { $_[0]->is_problem() },1,0);        sub { $_[0]->is_problem() },1,0);
     my %used_slots;      my %used_slots;
Line 172  sub get_consumed_uniqueperiods { Line 177  sub get_consumed_uniqueperiods {
  my $course =  &Apache::lonnet::EXT("resource.0.available",   my $course =  &Apache::lonnet::EXT("resource.0.available",
    $symb, $env{'user.domain'},     $symb, $env{'user.domain'},
    $env{'user.name'});     $env{'user.name'});
  if (&network_error($student) || &network_error($course)) {   if (&Apache::lonnet::error($student) 
       || &Apache::lonnet::error($course)) {
     return 'error: Unable to determine current status';      return 'error: Unable to determine current status';
  }   }
  foreach my $slot (split(/:/,$student), split(/:/, $course)) {   foreach my $slot (split(/:/,$student), split(/:/, $course)) {
Line 183  sub get_consumed_uniqueperiods { Line 189  sub get_consumed_uniqueperiods {
     if (!ref($slots)) {      if (!ref($slots)) {
  my ($cnum,$cdom)=&get_course();   my ($cnum,$cdom)=&get_course();
  my %slots=&Apache::lonnet::get('slots', [keys(%used_slots)], $cdom, $cnum);   my %slots=&Apache::lonnet::get('slots', [keys(%used_slots)], $cdom, $cnum);
  if (&network_error(%slots)) {   if (&Apache::lonnet::error(%slots)) {
     return 'error: Unable to determine current status';      return 'error: Unable to determine current status';
  }   }
  $slots = \%slots;   $slots = \%slots;
Line 209  sub check_for_conflict { Line 215  sub check_for_conflict {
   
     if (!ref($consumed_uniqueperiods)) {      if (!ref($consumed_uniqueperiods)) {
  $consumed_uniqueperiods = &get_consumed_uniqueperiods($slots);   $consumed_uniqueperiods = &get_consumed_uniqueperiods($slots);
  if (&network_error(%$consumed_uniqueperiods)) {          if (ref($consumed_uniqueperiods) eq 'HASH') {
     return 'error: Unable to determine current status';      if (&Apache::lonnet::error(%$consumed_uniqueperiods)) {
  }          return 'error: Unable to determine current status';
       }
           } else {
               return 'error: Unable to determine current status';
           }
     }      }
           
     my ($new_uniq_start,$new_uniq_end) = @{$new_slot->{'uniqueperiod'}};      my ($new_uniq_start,$new_uniq_end) = @{$new_slot->{'uniqueperiod'}};
Line 224  sub check_for_conflict { Line 234  sub check_for_conflict {
  }   }
     }      }
     return undef;      return undef;
   
 }  
   
 sub network_error {  
     my ($result) = @_;  
     if ($result =~ /^(con_lost|no_such_host|error: [^2])/) {  
  return 1;  
     }  
     return 0;  
 }  }
   
 sub make_reservation {  sub make_reservation {
     my ($slot_name,$slot,$symb)=@_;      my ($slot_name,$slot,$symb,$cnum,$cdom)=@_;
   
     my ($cnum,$cdom)=&get_course();  
   
     my $value=&Apache::lonnet::EXT("resource.0.availablestudent",$symb,      my $value=&Apache::lonnet::EXT("resource.0.availablestudent",$symb,
    $env{'user.domain'},$env{'user.name'});     $env{'user.domain'},$env{'user.name'});
     &Apache::lonxml::debug("value is  $value<br />");      &Apache::lonxml::debug("value is  $value<br />");
     if (&network_error($value)) {   
       my $use_slots = &Apache::lonnet::EXT("resource.0.useslots",$symb,
    $env{'user.domain'},$env{'user.name'});
       &Apache::lonxml::debug("use_slots is  $use_slots<br />");
   
       if (&Apache::lonnet::error($value) 
    || &Apache::lonnet::error($use_slots)) { 
  return 'error: Unable to determine current status';   return 'error: Unable to determine current status';
     }      }
   
       my $parm_symb  = $symb;
       my $parm_level = 1;
       if ($use_slots eq 'map' || $use_slots eq 'map_map') {
    my ($map) = &Apache::lonnet::decode_symb($symb);
    $parm_symb = &Apache::lonnet::symbread($map);
    $parm_level = 2;
       }
   
     foreach my $other_slot (split(/:/, $value)) {      foreach my $other_slot (split(/:/, $value)) {
  if ($other_slot eq $slot_name) {   if ($other_slot eq $slot_name) {
     my %consumed=&Apache::lonnet::dump('slot_reservations', $cdom,      my %consumed=&Apache::lonnet::dump('slot_reservations', $cdom,
        $cnum, "^$slot_name\0");            $cnum, "^$slot_name\0");   
     if (&network_error($value)) {       if (&Apache::lonnet::error($value)) { 
  return 'error: Unable to determine current status';   return 'error: Unable to determine current status';
     }      }
     my $me=$env{'user.name'}.':'.$env{'user.domain'};      my $me=$env{'user.name'}.':'.$env{'user.domain'};
Line 268  sub make_reservation { Line 281  sub make_reservation {
     if (!defined($max)) { $max=99999; }      if (!defined($max)) { $max=99999; }
   
     my (@ids)=&get_reservation_ids($slot_name);      my (@ids)=&get_reservation_ids($slot_name);
     if (&network_error(@ids)) {       if (&Apache::lonnet::error(@ids)) { 
  return 'error: Unable to determine current status';   return 'error: Unable to determine current status';
     }      }
     my $last=0;      my $last=0;
Line 286  sub make_reservation { Line 299  sub make_reservation {
           
     my %reservation=('name'      => $env{'user.name'}.':'.$env{'user.domain'},      my %reservation=('name'      => $env{'user.name'}.':'.$env{'user.domain'},
      'timestamp' => time,       'timestamp' => time,
      'symb'      => $symb);       'symb'      => $parm_symb);
   
     my $success=&Apache::lonnet::newput('slot_reservations',      my $success=&Apache::lonnet::newput('slot_reservations',
  {"$slot_name\0$wanted" =>   {"$slot_name\0$wanted" =>
Line 298  sub make_reservation { Line 311  sub make_reservation {
  if ($value) {   if ($value) {
     $new_value=$value.':'.$new_value;      $new_value=$value.':'.$new_value;
  }   }
  my $result=&Apache::lonparmset::storeparm_by_symb($symb,          &store_slot_parm($symb,$slot_name,$parm_level,$new_value,$cnum,$cdom);
       '0_availablestudent',  
        1, $new_value, 'string',  
        $env{'user.name'},  
                $env{'user.domain'});  
  &Apache::lonxml::debug("hrrm $result");  
  return $wanted;   return $wanted;
     }      }
   
Line 311  sub make_reservation { Line 319  sub make_reservation {
     return undef;      return undef;
 }  }
   
   sub store_slot_parm {
       my ($symb,$slot_name,$parm_level,$new_value,$cnum,$cdom) = @_;
       my $result=&Apache::lonparmset::storeparm_by_symb($symb,
                                                     '0_availablestudent',
                                                      $parm_level, $new_value,
                                                      'string',
                                                      $env{'user.name'},
                                                      $env{'user.domain'});
       &Apache::lonxml::debug("hrrm $result");
       my %storehash = (
                          symb    => $symb,
                          slot    => $slot_name,
                          action  => 'reserve',
                          context => $env{'form.context'},
                       );
   
       &Apache::lonnet::instructor_log('slotreservationslog',\%storehash,
                                       '',$env{'user.name'},$env{'user.domain'},
                                       $cnum,$cdom);
       &Apache::lonnet::instructor_log($cdom.'_'.$cnum.'_slotlog',\%storehash,
                                       1,$env{'user.name'},$env{'user.domain'},
                                       $env{'user.name'},$env{'user.domain'});
   
       return;
   }
   
 sub remove_registration {  sub remove_registration {
     my ($r) = @_;      my ($r) = @_;
     if ($env{'form.entry'} ne 'remove all') {      if ($env{'form.entry'} ne 'remove all') {
Line 322  sub remove_registration { Line 356  sub remove_registration {
     my ($cnum,$cdom)=&get_course();      my ($cnum,$cdom)=&get_course();
     my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,      my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
        "^$slot_name\0");         "^$slot_name\0");
     if (&network_error(%consumed)) {      if (&Apache::lonnet::error(%consumed)) {
  $r->print("<p>".&mt('A network error has occured.').'</p>');   $r->print("<p><span class=\"LC_error\">".&mt('A network error has occurred.').'</span></p>');
  return;   return;
     }      }
     if (!%consumed) {      if (!%consumed) {
  $r->print("<p>".&mt('Slot <tt>[_1]</tt> has no reservations.',   $r->print('<p>'.&mt('Slot [_1] has no reservations.',
     $slot_name)."</p>");      '<tt>'.$slot_name.'</tt>').'</p>');
  return;   return;
     }      }
   
Line 336  sub remove_registration { Line 370  sub remove_registration {
     my $names = join(' ',@names);      my $names = join(' ',@names);
   
     my $msg = &mt('Remove all of [_1] from slot [_2]?',$names,$slot_name);      my $msg = &mt('Remove all of [_1] from slot [_2]?',$names,$slot_name);
     &remove_registration_confirmation($r,$msg,['entry','slotname']);      &remove_registration_confirmation($r,$msg,['entry','slotname','context']);
 }  }
   
 sub remove_registration_user {  sub remove_registration_user {
Line 353  sub remove_registration_user { Line 387  sub remove_registration_user {
   $name,$slot_name,$title);    $name,$slot_name,$title);
           
     &remove_registration_confirmation($r,$msg,['uname','udom','slotname',      &remove_registration_confirmation($r,$msg,['uname','udom','slotname',
        'entry','symb']);         'entry','symb','context']);
 }  }
   
 sub remove_registration_confirmation {  sub remove_registration_confirmation {
Line 365  sub remove_registration_confirmation { Line 399  sub remove_registration_confirmation {
     '<input type="hidden" name="'.$parm.'" value="'      '<input type="hidden" name="'.$parm.'" value="'
     .&HTML::Entities::encode($env{'form.'.$parm},'"<>&\'').'" />'."\n";      .&HTML::Entities::encode($env{'form.'.$parm},'"<>&\'').'" />'."\n";
     }      }
     my %lt = &Apache::lonlocal::texthash('yes' => 'Yes',      my %lt = &Apache::lonlocal::texthash(
  'no'  => 'No',);          'yes' => 'Yes',
           'no'  => 'No',
       );
     $r->print(<<"END_CONFIRM");      $r->print(<<"END_CONFIRM");
 <p> $msg </p>  <p> $msg </p>
 <form action="/adm/slotrequest" method="POST">  <form action="/adm/slotrequest" method="post">
     <input type="hidden" name="command" value="release" />      <input type="hidden" name="command" value="release" />
     <input type="hidden" name="button" value="yes" />      <input type="hidden" name="button" value="yes" />
     $hidden_input      $hidden_input
     <input type="submit" value="$lt{'yes'}" />      <input type="submit" value="$lt{'yes'}" />
 </form>  </form>
 <form action="/adm/slotrequest" method="POST">  <form action="/adm/slotrequest" method="post">
     <input type="hidden" name="command" value="showslots" />      <input type="hidden" name="command" value="showslots" />
     <input type="submit" value="$lt{'no'}" />      <input type="submit" value="$lt{'no'}" />
 </form>  </form>
Line 401  sub release_all_slot { Line 437  sub release_all_slot {
  my ($result,$msg) =   my ($result,$msg) =
     &release_reservation($slot_name,$uname,$udom,      &release_reservation($slot_name,$uname,$udom,
  $consumed{$entry}{'symb'},$mgr);   $consumed{$entry}{'symb'},$mgr);
  $r->print("<p>$msg</p>");          if (!$result) {
               $r->print('<p><span class="LC_error">'.&mt($msg).'</span></p>');
           } else {
       $r->print("<p>$msg</p>");
           }
  $r->rflush();   $r->rflush();
     }      }
     $r->print('<p><a href="/adm/slotrequest?command=showslots">'.      $r->print('<p><a href="/adm/slotrequest?command=showslots">'.
Line 422  sub release_slot { Line 462  sub release_slot {
   
     if ($mgr eq 'F'       if ($mgr eq 'F' 
  && defined($env{'form.symb'})) {   && defined($env{'form.symb'})) {
  $symb = $env{'form.symb'};   $symb = &unescape($env{'form.symb'});
     }      }
   
     my ($result,$msg) =      my ($result,$msg) =
  &release_reservation($slot_name,$uname,$udom,$symb,$mgr);   &release_reservation($slot_name,$uname,$udom,$symb,$mgr);
     $r->print("<p>$msg</p>");      if (!$result) {
           $r->print('<p><span class="LC_error">'.&mt($msg).'</span></p>');
       } else {
           $r->print("<p>$msg</p>");
       }
           
     if ($mgr eq 'F') {      if ($mgr eq 'F') {
  $r->print('<p><a href="/adm/slotrequest?command=showslots">'.   $r->print('<p><a href="/adm/slotrequest?command=showslots">'.
Line 448  sub release_reservation { Line 492  sub release_reservation {
     return (0,&mt('Not allowed to release Reservation: [_1], as it has already ended.',$description));      return (0,&mt('Not allowed to release Reservation: [_1], as it has already ended.',$description));
  }   }
     }      }
   
       # if the reservation symb is for a map get a resource in that map
       # to check slot parameters on
       my $navmap=Apache::lonnavmaps::navmap->new;
       if (!defined($navmap)) {
           return (0,'error: Unable to determine current status');
       }
       my $passed_resource = $navmap->getBySymb($symb);
       if ($passed_resource->is_map()) {
    my ($a_resource) = 
       $navmap->retrieveResources($passed_resource, 
          sub {$_[0]->is_problem()},0,1);
    $symb = $a_resource->symb();
       }
   
     # get parameter string, check for existance, rebuild string with the slot      # get parameter string, check for existance, rebuild string with the slot
     my @slots = split(/:/,&Apache::lonnet::EXT("resource.0.availablestudent",      my $student = &Apache::lonnet::EXT("resource.0.availablestudent",
        $symb,$udom,$uname));                                         $symb,$udom,$uname);
       my @slots = split(/:/,$student);
   
     my @new_slots;      my @new_slots;
     foreach my $exist_slot (@slots) {      foreach my $exist_slot (@slots) {
Line 468  sub release_reservation { Line 528  sub release_reservation {
  if ( $consumed{$entry}->{'name'} eq ($uname.':'.$udom) ) {   if ( $consumed{$entry}->{'name'} eq ($uname.':'.$udom) ) {
     &Apache::lonnet::del('slot_reservations',[$entry],      &Apache::lonnet::del('slot_reservations',[$entry],
  $cdom,$cnum);   $cdom,$cnum);
               my %storehash = (
                                  symb    => $symb,
                                  slot    => $slot_name,
                                  action  => 'release',
                                  context => $env{'form.context'},
                           );
               &Apache::lonnet::instructor_log('slotreservationslog',\%storehash,
                                               1,$uname,$udom,$cnum,$cdom);
               &Apache::lonnet::instructor_log($cdom.'_'.$cnum.'_slotlog',\%storehash,
                                               1,$uname,$udom,$uname,$udom);
  }   }
     }      }
   
       my $use_slots = &Apache::lonnet::EXT("resource.0.useslots",
    $symb,$udom,$uname);
       &Apache::lonxml::debug("use_slots is  $use_slots<br />");
   
       if (&Apache::lonnet::error($use_slots)) { 
    return (0,'error: Unable to determine current status');
       }
   
       my $parm_level = 1;
       if ($use_slots eq 'map' || $use_slots eq 'map_map') {
    $parm_level = 2;
       }
     # store new parameter string      # store new parameter string
     my $result=&Apache::lonparmset::storeparm_by_symb($symb,      my $result=&Apache::lonparmset::storeparm_by_symb($symb,
       '0_availablestudent',        '0_availablestudent',
       1, $new_param, 'string',        $parm_level, $new_param,
       $uname,$udom);        'string', $uname, $udom);
   
     my $msg;      my $msg;
     if ($mgr eq 'F') {      if ($mgr eq 'F') {
  $msg = &mt('Released Reservation for user: [_1]',"$uname:$udom");   $msg = &mt('Released Reservation for user: [_1]',"$uname:$udom");
Line 503  sub delete_slot { Line 584  sub delete_slot {
  my $ret = &Apache::lonnet::cput('slots', {$slot_name => \%slot},   my $ret = &Apache::lonnet::cput('slots', {$slot_name => \%slot},
  $cdom, $cnum);   $cdom, $cnum);
  if ($ret eq 'ok') {   if ($ret eq 'ok') {
     $r->print("<p>Slot <tt>$slot_name</tt> marked as deleted.</p>");      $r->print('<p>'.&mt('Slot [_1] marked as deleted.','<tt>'.$slot_name.'</tt>').'</p>');
  } else {   } else {
     $r->print("<p> An error ($ret) occurse when attempting to delete Slot <tt>$slot_name</tt>.</p>");      $r->print('<p><span class="LC_error">'.&mt('An error occurred when attempting to delete slot: [_1]','<tt>'.$slot_name.'</tt>')." ($ret)</span></p>");
  }   }
     } else {      } else {
  if (%consumed) {   if (%consumed) {
     $r->print("<p>Slot <tt>$slot_name</tt> has active reservations.</p>");      $r->print('<p>'.&mt('Slot [_1] has active reservations.','<tt>'.$slot_name.'</tt>').'</p>');
  } else {   } else {
     $r->print("<p>Slot <tt>$slot_name</tt> does not exist.</p>");      $r->print('<p>'.&mt('Slot [_1] does not exist.','<tt>'.$slot_name.'</tt>').'</p>');
  }   }
     }      }
     $r->print('<p><a href="/adm/slotrequest?command=showslots">'.      $r->print('<p><a href="/adm/slotrequest?command=showslots">'.
Line 521  sub delete_slot { Line 602  sub delete_slot {
   
 sub return_link {  sub return_link {
     my ($r) = @_;      my ($r) = @_;
     $r->print('<p><a href="/adm/flip?postdata=return:">'.      if (($env{'form.command'} eq 'manageresv') || ($env{'form.context'} eq 'usermanage')) {
       &mt('Return to last resource').'</a></p>');   $r->print('<p><a href="/adm/slotrequest?command=manageresv">'.
                     &mt('Return to reservations'));  
       } else {
           $r->print('<p><a href="/adm/flip?postdata=return:">'.
             &mt('Return to last resource').'</a></p>');
       }
 }  }
   
 sub get_slot {  sub get_slot {
     my ($r,$symb)=@_;      my ($r,$symb,$conflictable_slot,$inhibit_return_link)=@_;
   
     my %slot=&Apache::lonnet::get_slot($env{'form.slotname'});      my %slot=&Apache::lonnet::get_slot($env{'form.slotname'});
     my $slot_name=&check_for_conflict($symb,$env{'form.slotname'},\%slot);      my $slot_name=&check_for_conflict($symb,$env{'form.slotname'},\%slot);
   
     if ($slot_name =~ /^error: (.*)/) {      if ($slot_name =~ /^error: (.*)/) {
  $r->print("<p>An error occured while attempting to make a reservation. ($1)</p>");   $r->print('<p><span class="LC_error">'
                    .&mt('An error occurred while attempting to make a reservation. ([_1])',$1)
                    .'</span></p>');
  &return_link($r);   &return_link($r);
  return;   return 0;
     }      }
     if ($slot_name) {      if ($slot_name && $slot_name ne $conflictable_slot) {
  my %slot=&Apache::lonnet::get_slot($slot_name);   my %slot=&Apache::lonnet::get_slot($slot_name);
  my $description1=&get_description($slot_name,\%slot);   my $description1=&get_description($slot_name,\%slot);
  %slot=&Apache::lonnet::get_slot($env{'form.slotname'});   %slot=&Apache::lonnet::get_slot($env{'form.slotname'});
  my $description2=&get_description($env{'form.slotname'},\%slot);   my $description2=&get_description($env{'form.slotname'},\%slot);
  $r->print("<p>Already have a reservation: $description1</p>");   $r->print('<p>'.&mt('Already have a reservation: [_1].',$description1).'</p>');
  if ($slot_name ne $env{'form.slotname'}) {   if ($slot_name ne $env{'form.slotname'}) {
     $r->print(<<STUFF);      $r->print(<<STUFF);
 <form method="POST" action="/adm/slotrequest">  <form method="post" action="/adm/slotrequest">
    <input type="hidden" name="symb" value="$env{'form.symb'}" />     <input type="hidden" name="symb" value="$env{'form.symb'}" />
    <input type="hidden" name="slotname" value="$env{'form.slotname'}" />     <input type="hidden" name="slotname" value="$env{'form.slotname'}" />
    <input type="hidden" name="releaseslot" value="$slot_name" />     <input type="hidden" name="releaseslot" value="$slot_name" />
    <input type="hidden" name="command" value="change" />     <input type="hidden" name="command" value="change" />
 STUFF  STUFF
             $r->print("<p>You can either ");              $r->print('<p>'
     $r->print(<<STUFF);                       .&mt('You can either [_1]Change[_2] your reservation from [_3] to [_4] or'
    <input type="submit" name="change" value="Change" />                           ,'<input type="submit" name="change" value="'
 STUFF                           ,'" />'
     $r->print(' your reservation from <b>'.$description1.'</b> to <b>'.                           ,'<b>'.$description1.'</b>'
       $description2.                           ,'<b>'.$description2.'</b>')
       '</b> <br />or </p>');                       .'<br /></p>'
               );
     &return_link($r);      &return_link($r);
     $r->print(<<STUFF);      $r->print(<<STUFF);
 </form>  </form>
Line 564  STUFF Line 653  STUFF
         } else {          } else {
     &return_link($r);      &return_link($r);
  }   }
  return;   return 0;
     }      }
   
       my ($cnum,$cdom)=&get_course();
     my $reserved=&make_reservation($env{'form.slotname'},      my $reserved=&make_reservation($env{'form.slotname'},
    \%slot,$symb);     \%slot,$symb,$cnum,$cdom);
     my $description=&get_description($env{'form.slotname'},\%slot);      my $description=&get_description($env{'form.slotname'},\%slot);
     if (defined($reserved)) {      if (defined($reserved)) {
    my $retvalue = 0;
  if ($slot_name =~ /^error: (.*)/) {   if ($slot_name =~ /^error: (.*)/) {
     $r->print("<p>An error occured while attempting to make a reservation. ($1)</p>");      $r->print('<p><span class="LC_error">'
                        .&mt('An error occurred while attempting to make a reservation. ([_1])',$1)
                        .'</span></p>');
  } elsif ($reserved > -1) {   } elsif ($reserved > -1) {
     $r->print("<p>Success: $description</p>");      $r->print('<p>'.&mt('Success: [_1]',$description).'</p>');
       $retvalue = 1;
  } elsif ($reserved < 0) {   } elsif ($reserved < 0) {
     $r->print("<p>Already reserved: $description</p>");      $r->print('<p>'.&mt('Already reserved: [_1]',$description).'</p>');
  }   }
  &return_link($r);   if (!$inhibit_return_link) { &return_link($r); }
  return;   return 1;
     }      }
   
     my %lt=('request'=>"Availibility list",      my %lt = &Apache::lonlocal::texthash(
     'try'    =>'Try again');          'request' => 'Availibility list',
     %lt=&Apache::lonlocal::texthash(%lt);          'try'     => 'Try again?',
           'or'      => 'or',
       );
   
       my $extra_input;
       if ($conflictable_slot) {
    $extra_input='<input type="hidden" name="releaseslot" value="'.$env{'form.slotname'}.'" />';
       }
   
       $r->print('<p>'.&mt('[_1]Failed[_2] to reserve a slot for [_3].','<span class="LC_warning">','</span>',$description).'</p>');
     $r->print(<<STUFF);      $r->print(<<STUFF);
 <p> <font color="red">Failed</font> to reserve a spot for $description. </p>  
 <p>  <p>
 <form method="POST" action="/adm/slotrequest">  <form method="post" action="/adm/slotrequest">
    <input type="submit" name="Try Again" value="$lt{'try'}" />     <input type="submit" name="Try Again" value="$lt{'try'}" />
    <input type="hidden" name="symb" value="$env{'form.symb'}" />     <input type="hidden" name="symb" value="$env{'form.symb'}" />
    <input type="hidden" name="slotname" value="$env{'form.slotname'}" />     <input type="hidden" name="slotname" value="$env{'form.slotname'}" />
    <input type="hidden" name="command" value="get" />     <input type="hidden" name="command" value="$env{'form.command'}" />
      $extra_input
 </form>  </form>
 ?  
 </p>  </p>
 <p>  <p>
 or  $lt{'or'}
 <form method="POST" action="/adm/slotrequest">  <form method="post" action="/adm/slotrequest">
     <input type="hidden" name="symb" value="$env{'form.symb'}" />      <input type="hidden" name="symb" value="$env{'form.symb'}" />
     <input type="submit" name="requestattempt" value="$lt{'request'}" />      <input type="submit" name="requestattempt" value="$lt{'request'}" />
 </form>  </form>
 </p>  
 or  
 STUFF  STUFF
   
     &return_link($r);      if (!$inhibit_return_link) { 
     return;          $r->print(&mt('or').'</p>').&return_link($r);
       } else {
           $r->print('</p>');
       }
       return 0;
 }  }
   
 sub allowed_slot {  sub allowed_slot {
Line 616  sub allowed_slot { Line 719  sub allowed_slot {
   
     #already started      #already started
     if ($slot->{'starttime'} < time) {      if ($slot->{'starttime'} < time) {
  # all open slot to be schedulable   return 0;
  #return 0;  
     }      }
     &Apache::lonxml::debug("$slot_name starttime good");      &Apache::lonxml::debug("$slot_name starttime good");
   
Line 653  sub allowed_slot { Line 755  sub allowed_slot {
     split(',',$slot->{'allowedsections'}))) {      split(',',$slot->{'allowedsections'}))) {
     $userallowed=1;      $userallowed=1;
  }   }
    if (defined($env{'request.course.groups'})) {
       my @groups = split(/:/,$env{'request.course.groups'});
       my @allowed_sec = split(',',$slot->{'allowedsections'});
       foreach my $group (@groups) {
    if (grep {$_ eq $group} (@allowed_sec)) {
       $userallowed=1;
       last;
    }
       }
    }
     }      }
     &Apache::lonxml::debug("$slot_name sections is $userallowed");      &Apache::lonxml::debug("$slot_name sections is $userallowed");
   
Line 679  sub allowed_slot { Line 791  sub allowed_slot {
   
     my $conflict = &check_for_conflict($symb,$slot_name,$slot,$slots,      my $conflict = &check_for_conflict($symb,$slot_name,$slot,$slots,
        $consumed_uniqueperiods);         $consumed_uniqueperiods);
     if ($conflict) {      if ($conflict =~ /^error: /) {
           return 0;
       } elsif ($conflict ne '') {
  if ($slots->{$conflict}{'starttime'} < time) {   if ($slots->{$conflict}{'starttime'} < time) {
     return 0;      return 0;
  }   }
Line 700  sub get_description { Line 814  sub get_description {
 }  }
   
 sub show_choices {  sub show_choices {
     my ($r,$symb)=@_;      my ($r,$symb,$formname)=@_;
   
     my ($cnum,$cdom)=&get_course();      my ($cnum,$cdom)=&get_course();
     my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum);      my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum);
     my $consumed_uniqueperiods = &get_consumed_uniqueperiods(\%slots);      my $consumed_uniqueperiods = &get_consumed_uniqueperiods(\%slots);
     my $available;      if (ref($consumed_uniqueperiods) eq 'HASH') {
     $r->print('<table border="1">');          if (&Apache::lonnet::error(%$consumed_uniqueperiods)) {
               $r->print('<span class="LC_error">'.
                         &mt('An error occurred determining slot availability').
                         '</span>');
               return;
           }
       } elsif ($consumed_uniqueperiods =~ /^error: /) {
           $r->print('<span class="LC_error">'.
                     &mt('An error occurred determining slot availability').
                     '</span>');
           return;
       }
       my (@available,$output);
     &Apache::lonxml::debug("Checking Slots");      &Apache::lonxml::debug("Checking Slots");
     my @got_slots=&check_for_reservation($symb,'allslots');      my @got_slots=&check_for_reservation($symb,'allslots');
       if ($got_slots[0] =~ /^error: /) {
           $r->print('<span class="LC_error">'.
                     &mt('An error occurred determining slot availability').
                     '</span>');
           return;
       }
     foreach my $slot (sort       foreach my $slot (sort 
       { return $slots{$a}->{'starttime'} <=> $slots{$b}->{'starttime'} }        { return $slots{$a}->{'starttime'} <=> $slots{$b}->{'starttime'} }
       (keys(%slots)))  {        (keys(%slots)))  {
Line 717  sub show_choices { Line 849  sub show_choices {
  next if (!&allowed_slot($slot,$slots{$slot},undef,\%slots,   next if (!&allowed_slot($slot,$slots{$slot},undef,\%slots,
  $consumed_uniqueperiods));   $consumed_uniqueperiods));
   
  $available++;          push(@available,$slot);
       }
       if (!@available) {
           $output = &mt('No available times.');
           if ($env{'form.command'} ne 'manageresv') {
               $output .= ' <a href="/adm/flip?postdata=return:">'.
                          &mt('Return to last resource').'</a>';
           }
           $r->print($output);
           return;
       }
       if ($env{'form.command'} eq 'manageresv') {
           $output = '<table border="0">';
       } else {
           $output = &Apache::loncommon::start_data_table();
       }
       foreach my $slot (@available) { 
  my $description=&get_description($slot,$slots{$slot});   my $description=&get_description($slot,$slots{$slot});
    my $form;
  my $form=&mt('Unavailable');  
  if ((grep(/^\Q$slot\E$/,@got_slots)) ||   if ((grep(/^\Q$slot\E$/,@got_slots)) ||
     &space_available($slot,$slots{$slot},$symb)) {      &space_available($slot,$slots{$slot},$symb)) {
     my $text=&mt('Select');      my $text=&mt('Select');
     my $command='get';      my $command='get';
     if (grep(/^\Q$slot\E$/,@got_slots)) {      if (grep(/^\Q$slot\E$/,@got_slots)) {
  $text=&mt('Free Reservation');   $text=&mt('Drop Reservation');
  $command='release';   $command='release';
     } else {      } else {
  my $conflict = &check_for_conflict($symb,$slot,$slots{$slot},   my $conflict = &check_for_conflict($symb,$slot,$slots{$slot},
    \%slots,     \%slots,
    $consumed_uniqueperiods);     $consumed_uniqueperiods);
  if ($conflict) {                  if ($conflict) {
     $text=&mt('Change Reservation');                      if ($conflict =~ /^error: /) {
     $command='get';                          $form = '<span class="LC_error">'.
  }                                  &mt('Slot: [_1] has unknown status.',$description).
                                   '</span>';
                       } else {
           $text=&mt('Change Reservation');
           $command='get';
       }
                   }
     }      }
     my $escsymb=&Apache::lonnet::escape($symb);      my $escsymb=&escape($symb);
     $form=<<STUFF;              if (!$form) {
    <form method="POST" action="/adm/slotrequest">                  if ($formname) {
                       $formname = 'name="'.$formname.'" ';
                   }
                   my $context = 'user';
                   if ($env{'form.command'} eq 'manageresv') {
                       $context = 'usermanage';
                   }
           $form=<<STUFF;
      <form method="post" action="/adm/slotrequest" $formname>
      <input type="submit" name="Select" value="$text" />       <input type="submit" name="Select" value="$text" />
      <input type="hidden" name="symb" value="$escsymb" />       <input type="hidden" name="symb" value="$escsymb" />
      <input type="hidden" name="slotname" value="$slot" />       <input type="hidden" name="slotname" value="$slot" />
      <input type="hidden" name="command" value="$command" />       <input type="hidden" name="command" value="$command" />
        <input type="hidden" name="context" value="$context" />
    </form>     </form>
 STUFF  STUFF
  }      }
  $r->print(<<STUFF);          } else {
 <tr>              $form = &mt('Unavailable');
           }
           if ($env{'form.command'} eq 'manageresv') {
               $output .= '<tr>';
           } else {
       $output .= &Apache::loncommon::start_data_table_row();
           }
           $output .= " 
  <td>$form</td>   <td>$form</td>
  <td>$description</td>   <td>$description</td>\n";
 </tr>          if ($env{'form.command'} eq 'manageresv') {
 STUFF              $output .= '</tr>';
           } else {
               $output .= &Apache::loncommon::end_data_table_row();
           }
     }      }
       if ($env{'form.command'} eq 'manageresv') {
     if (!$available) {          $output .= '</table>';
  $r->print('<tr><td>No available times. <a href="/adm/flip?postdata=return:">'.      } else {
   &mt('Return to last resource').'</a></td></tr>');         $output .= &Apache::loncommon::end_data_table();
     }      }
     $r->print('</table>');      $r->print($output);
 }  }
   
 sub to_show {  sub to_show {
Line 837  sub remove_link { Line 1008  sub remove_link {
  undef($udom);   undef($udom);
     }      }
   
     $slotname  = &Apache::lonnet::escape($slotname);      $slotname  = &escape($slotname);
     $entry     = &Apache::lonnet::escape($entry);      $entry     = &escape($entry);
     $uname     = &Apache::lonnet::escape($uname);      $uname     = &escape($uname);
     $udom      = &Apache::lonnet::escape($udom);      $udom      = &escape($udom);
     $symb      = &Apache::lonnet::escape($symb);      $symb      = &escape($symb);
   
     return <<"END_LINK";      return <<"END_LINK";
  <a href="/adm/slotrequest?command=remove_registration&slotname=$slotname&entry=$entry&uname=$uname&udom=$udom&symb=$symb"   <a href="/adm/slotrequest?command=remove_registration&amp;slotname=$slotname&amp;entry=$entry&amp;uname=$uname&amp;udom=$udom&amp;symb=$symb&amp;context=manage"
    >($remove)</a>     >($remove)</a>
 END_LINK  END_LINK
   
Line 860  sub show_table { Line 1031  sub show_table {
     }       } 
     my $available;      my $available;
     if ($mgr eq 'F') {      if ($mgr eq 'F') {
       # FIXME: This line should be deleted once Slots uses breadcrumbs
       $r->print(&Apache::loncommon::help_open_topic('Slot About', 'Help on slots'));
   
  $r->print('<div>');   $r->print('<div>');
  $r->print('<form method="POST" action="/adm/slotrequest">   $r->print('<form method="post" action="/adm/slotrequest">
 <input type="hidden" name="command" value="uploadstart" />  <input type="hidden" name="command" value="uploadstart" />
 <input type="submit" name="start" value="'.&mt('Upload Slot List').'" />  <input type="submit" name="start" value="'.&mt('Upload Slot List').'" />
 </form>');  </form>');
  $r->print('<form method="POST" action="/adm/helper/newslot.helper">   $r->print(&Apache::loncommon::help_open_topic('Slot CommaDelimited'));
    $r->print('<form method="post" action="/adm/helper/newslot.helper">
 <input type="submit" name="newslot" value="'.&mt('Create a New Slot').'" />  <input type="submit" name="newslot" value="'.&mt('Create a New Slot').'" />
 </form>');  </form>');
    $r->print(&Apache::loncommon::help_open_topic('Slot AddInterface'));
  $r->print('</div>');   $r->print('</div>');
     }      }
   
       if (!keys(%slots)) {
           $r->print('<div>'.&mt('No slots have been created in this course.').'</div>');
           return;
       }
           
     my %Saveable_Parameters = ('show'              => 'array',      my %Saveable_Parameters = ('show'              => 'array',
        'when'              => 'scalar',         'when'              => 'scalar',
Line 895  sub show_table { Line 1076  sub show_table {
      'endtime'         => 'End Time',       'endtime'         => 'End Time',
              'startreserve'    => 'Time students can start reserving',               'startreserve'    => 'Time students can start reserving',
      'secret'          => 'Secret Word',       'secret'          => 'Secret Word',
      'maxspace'        => 'Maximum # of students',       'space'           => '# of students/max',
      'ip'              => 'IP or DNS restrictions',       'ip'              => 'IP or DNS restrictions',
      'symb'            => 'Resource slot is restricted to.',       'symb'            => 'Resource slot is restricted to.',
      'allowedsections' => 'Sections slot is restricted to.',       'allowedsections' => 'Sections slot is restricted to.',
Line 904  sub show_table { Line 1085  sub show_table {
      'scheduled'       => 'Scheduled Students',       'scheduled'       => 'Scheduled Students',
      'proctor'         => 'List of proctors');       'proctor'         => 'List of proctors');
     my @show_order=('name','description','type','starttime','endtime',      my @show_order=('name','description','type','starttime','endtime',
     'startreserve','secret','maxspace','ip','symb',      'startreserve','secret','space','ip','symb',
     'allowedsections','allowedusers','uniqueperiod',      'allowedsections','allowedusers','uniqueperiod',
     'scheduled','proctor');      'scheduled','proctor');
     my @show =       my @show = 
Line 952  sub show_table { Line 1133  sub show_table {
     my $name_filter = {'type'  => $name_filter_type,      my $name_filter = {'type'  => $name_filter_type,
        'value' => $env{'form.name_filter_value'},};         'value' => $env{'form.name_filter_value'},};
   
       
     #deleted slot filtering      #deleted slot filtering
       #default to hide if no value
       $env{'form.deleted'} ||= 'hide';
     my $hide_radio =       my $hide_radio = 
  &Apache::lonhtmlcommon::radio('deleted',$env{'form.deleted'},'hide');   &Apache::lonhtmlcommon::radio('deleted',$env{'form.deleted'},'hide');
     my $show_radio =       my $show_radio = 
  &Apache::lonhtmlcommon::radio('deleted',$env{'form.deleted'},'show');   &Apache::lonhtmlcommon::radio('deleted',$env{'form.deleted'},'show');
   
     $r->print('<form method="POST" action="/adm/slotrequest">      $r->print('<form method="post" action="/adm/slotrequest">
 <input type="hidden" name="command" value="showslots" />');  <input type="hidden" name="command" value="showslots" />');
     $r->print('<div>');      $r->print('<div>');
     $r->print('<table class="inline">      $r->print('<table class="inline">
Line 968  sub show_table { Line 1152  sub show_table {
           <th>'.&mt('Slot Name Filter').'</th>            <th>'.&mt('Slot Name Filter').'</th>
           <th>'.&mt('Options').'</th>            <th>'.&mt('Options').'</th>
       </tr>        </tr>
       <tr><td>'.&Apache::loncommon::multiple_select_form('show',\@show,6,\%show_fields,\@show_order).        <tr><td valign="top">'.&Apache::loncommon::multiple_select_form('show',\@show,6,\%show_fields,\@show_order).
       '</td>        '</td>
            <td>             <td valign="top">
          '.&Apache::loncommon::multiple_select_form('studisplay',\@stu_display,           '.&Apache::loncommon::multiple_select_form('studisplay',\@stu_display,
     6,\%stu_display_fields,      6,\%stu_display_fields,
     \@stu_display_order).'      \@stu_display_order).'
            </td>             </td>
            <td>'.&Apache::loncommon::select_form($when,'when',%when_fields).             <td valign="top">'.&Apache::loncommon::select_form($when,'when',%when_fields).
           '</td>            '</td>
            <td>'.&Apache::loncommon::select_form($name_filter_type,             <td valign="top">'.&Apache::loncommon::select_form($name_filter_type,
  'name_filter_type',   'name_filter_type',
  %name_filter_type_fields).   %name_filter_type_fields).
       '<br />'.        '<br />'.
Line 985  sub show_table { Line 1169  sub show_table {
       $env{'form.name_filter_value'},        $env{'form.name_filter_value'},
       15).        15).
           '</td>            '</td>
            <td>             <td valign="top">
             <table>              <table>
               <tr>                <tr>
                 <td rowspan="2">Deleted slots:</td>                  <td rowspan="2">Deleted slots:</td>
Line 1001  sub show_table { Line 1185  sub show_table {
     $r->print('</div>');      $r->print('</div>');
     $r->print('<p><input type="submit" name="start" value="'.&mt('Update Display').'" /></p>');      $r->print('<p><input type="submit" name="start" value="'.&mt('Update Display').'" /></p>');
     my $linkstart='<a href="/adm/slotrequest?command=showslots&amp;order=';      my $linkstart='<a href="/adm/slotrequest?command=showslots&amp;order=';
     $r->print('<table class="thinborder">      $r->print(&Apache::loncommon::start_data_table().
 <tr>        &Apache::loncommon::start_data_table_header_row().'
   <th></th>');         <th></th>');
     foreach my $which (@show_order) {      foreach my $which (@show_order) {
  if ($which ne 'proctor' && exists($show{$which})) {   if ($which ne 'proctor' && exists($show{$which})) {
     $r->print('<th>'.$linkstart.$which.'">'.$show_fields{$which}.'</a></th>');      $r->print('<th>'.$linkstart.$which.'">'.$show_fields{$which}.'</a></th>');
  }   }
     }      }
       $r->print(&Apache::loncommon::end_data_table_header_row());
   
     my %name_cache;      my %name_cache;
     my $slotsort = sub {      my $slotsort = sub {
  if ($env{'form.order'}=~/^(type|description|endtime|startreserve|maxspace|ip|symb|allowedsections|allowedusers)$/) {   if ($env{'form.order'}=~/^(type|description|endtime|startreserve|ip|symb|allowedsections|allowedusers)$/) {
     if (lc($slots{$a}->{$env{'form.order'}})      if (lc($slots{$a}->{$env{'form.order'}})
  ne lc($slots{$b}->{$env{'form.order'}})) {   ne lc($slots{$b}->{$env{'form.order'}})) {
  return (lc($slots{$a}->{$env{'form.order'}})    return (lc($slots{$a}->{$env{'form.order'}}) 
  cmp lc($slots{$b}->{$env{'form.order'}}));   cmp lc($slots{$b}->{$env{'form.order'}}));
     }      }
    } elsif ($env{'form.order'} eq 'space') {
       if ($slots{$a}{'maxspace'} ne $slots{$b}{'maxspace'}) {
    return ($slots{$a}{'maxspace'} cmp $slots{$b}{'maxspace'});
       }
  } elsif ($env{'form.order'} eq 'name') {   } elsif ($env{'form.order'} eq 'name') {
     if (lc($a) cmp lc($b)) {      if (lc($a) cmp lc($b)) {
  return lc($a) cmp lc($b);   return lc($a) cmp lc($b);
Line 1037  sub show_table { Line 1226  sub show_table {
  }   }
  return $slots{$a}->{'starttime'} <=> $slots{$b}->{'starttime'};   return $slots{$a}->{'starttime'} <=> $slots{$b}->{'starttime'};
     };      };
   
       my %consumed;
       if (exists($show{'scheduled'}) || exists($show{'space'}) ) {
    %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum);
    my ($tmp)=%consumed;
    if ($tmp =~ /^error: /) { undef(%consumed); }
       }
   
     foreach my $slot (sort $slotsort (keys(%slots)))  {      foreach my $slot (sort $slotsort (keys(%slots)))  {
  if (!&to_show($slot,$slots{$slot},$when,   if (!&to_show($slot,$slots{$slot},$when,
       $env{'form.deleted'},$name_filter)) { next; }        $env{'form.deleted'},$name_filter)) { next; }
Line 1045  sub show_table { Line 1242  sub show_table {
     #next;      #next;
  }   }
  my $description=&get_description($slot,$slots{$slot});   my $description=&get_description($slot,$slots{$slot});
  my $ids;   my ($id_count,$ids);
  if (exists($show{'scheduled'})) {      
     my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,   if (exists($show{'scheduled'}) || exists($show{'space'}) ) {
        "^$slot\0");      my $re_str = "$slot\0";
     my ($tmp)=%consumed;      my @this_slot = grep(/^\Q$re_str\E/,keys(%consumed));
     if ($tmp !~ /^error: /) {      $id_count = scalar(@this_slot);
       if (exists($show{'scheduled'})) {
  foreach my $entry (sort { $consumed{$a}{name} cmp    foreach my $entry (sort { $consumed{$a}{name} cmp 
       $consumed{$b}{name} }        $consumed{$b}{name} }
    (keys(%consumed))) {     (@this_slot)) {
     my (undef,$id)=split("\0",$entry);      my (undef,$id)=split("\0",$entry);
     my ($uname,$udom) = split(':',$consumed{$entry}{'name'});      my ($uname,$udom) = split(':',$consumed{$entry}{'name'});
     $ids.= '<nobr>';      $ids.= '<span class="LC_nobreak">';
     foreach my $item (@stu_display_order) {      foreach my $item (@stu_display_order) {
  if ($stu_display{$item}) {   if ($stu_display{$item}) {
     if ($item eq 'fullname') {      if ($item eq 'fullname') {
Line 1067  sub show_table { Line 1265  sub show_table {
  }   }
     }      }
     $ids.=&remove_link($slot,$entry,$uname,$udom,      $ids.=&remove_link($slot,$entry,$uname,$udom,
        $consumed{$entry}{'symb'}).'</nobr><br />';         $consumed{$entry}{'symb'}).'</span><br />';
  }   }
     }      }
  }   }
Line 1081  sub show_table { Line 1279  sub show_table {
   
  my $unique;   my $unique;
  if (ref($slots{$slot}{'uniqueperiod'})) {   if (ref($slots{$slot}{'uniqueperiod'})) {
     $unique=localtime($slots{$slot}{'uniqueperiod'}[0]).','.      $unique=localtime($slots{$slot}{'uniqueperiod'}[0]).', '.
  localtime($slots{$slot}{'uniqueperiod'}[1]);   localtime($slots{$slot}{'uniqueperiod'}[1]);
  }   }
   
Line 1122  sub show_table { Line 1320  sub show_table {
  if (exists($show{'proctor'})) {   if (exists($show{'proctor'})) {
     $rowspan=2;      $rowspan=2;
     @proctors= map {      @proctors= map {
  my ($uname,$udom)=split(/@/,$_);   my ($uname,$udom)=split(/:/,$_);
  my $fullname=$name_cache{$_};   my $fullname=$name_cache{$_};
  if (!defined($fullname)) {   if (!defined($fullname)) {
     $fullname = &Apache::loncommon::plainname($uname,$udom);      $fullname = &Apache::loncommon::plainname($uname,$udom);
Line 1134  sub show_table { Line 1332  sub show_table {
  }   }
  my $proctors=join(', ',@proctors);   my $proctors=join(', ',@proctors);
   
           my %lt = &Apache::lonlocal::texthash (
                                                  edit   => 'Edit',
                                                  delete => 'Delete',
                                                  slotlog => 'History',
           );
  my $edit=(<<"EDITLINK");   my $edit=(<<"EDITLINK");
 <a href="/adm/helper/newslot.helper?name=$slot">Edit</a>  <a href="/adm/helper/newslot.helper?name=$slot">$lt{'edit'}</a>
 EDITLINK  EDITLINK
   
  my $delete=(<<"DELETELINK");   my $delete=(<<"DELETELINK");
 <a href="/adm/slotrequest?command=delete&slotname=$slot">Delete</a>  <a href="/adm/slotrequest?command=delete&amp;slotname=$slot">$lt{'delete'}</a>
 DELETELINK  DELETELINK
   
           my $showlog=(<<"LOGLINK");
   <a href="/adm/slotrequest?command=slotlog&amp;slotname=$slot">$lt{'slotlog'}</a>
   LOGLINK
   
         my $remove_all=&remove_link($slot,'remove all').'<br />';          my $remove_all=&remove_link($slot,'remove all').'<br />';
   
         if ($ids ne '') { undef($delete); }          if ($ids eq '') {
  if ($slots{$slot}{'type'} ne 'schedulable_student'               undef($remove_all);
     || $ids eq '') {           } else {
               undef($delete);
           }
    if ($slots{$slot}{'type'} ne 'schedulable_student') {
               undef($showlog); 
     undef($remove_all);      undef($remove_all);
  }   }
   
         $r->print("<tr>\n<td rowspan=\"$rowspan\">$edit $delete</td>\n");   my $row_start=&Apache::loncommon::start_data_table_row();
    my $row_end=&Apache::loncommon::end_data_table_row();
           $r->print($row_start.
     "\n<td rowspan=\"$rowspan\">$edit $delete $showlog</td>\n");
  if (exists($show{'name'})) {   if (exists($show{'name'})) {
     $colspan++;$r->print("<td>$slot</td>");      $colspan++;$r->print("<td>$slot</td>");
  }   }
Line 1172  DELETELINK Line 1386  DELETELINK
  if (exists($show{'secret'})) {   if (exists($show{'secret'})) {
     $colspan++;$r->print("<td>$slots{$slot}{'secret'}</td>\n");      $colspan++;$r->print("<td>$slots{$slot}{'secret'}</td>\n");
  }   }
  if (exists($show{'maxspace'})) {   if (exists($show{'space'})) {
     $colspan++;$r->print("<td>$slots{$slot}{'maxspace'}</td>\n");      my $display = $id_count;
       if ($slots{$slot}{'maxspace'}>0) {
    $display.='/'.$slots{$slot}{'maxspace'};
    if ($slots{$slot}{'maxspace'} <= $id_count) {
       $display = '<strong>'.$display.' (full) </strong>';
    }
       }
       $colspan++;$r->print("<td>$display</td>\n");
  }   }
  if (exists($show{'ip'})) {   if (exists($show{'ip'})) {
     $colspan++;$r->print("<td>$slots{$slot}{'ip'}</td>\n");      $colspan++;$r->print("<td>$slots{$slot}{'ip'}</td>\n");
Line 1187  DELETELINK Line 1408  DELETELINK
  if (exists($show{'allowedusers'})) {   if (exists($show{'allowedusers'})) {
     $colspan++;$r->print("<td>$allowedusers</td>\n");      $colspan++;$r->print("<td>$allowedusers</td>\n");
  }   }
    if (exists($show{'uniqueperiod'})) {
       $colspan++;$r->print("<td>$unique</td>\n");
    }
  if (exists($show{'scheduled'})) {   if (exists($show{'scheduled'})) {
     $colspan++;$r->print("<td>$remove_all $ids</td>\n</tr>\n");      $colspan++;$r->print("<td>$remove_all $ids</td>\n");
  }   }
    $r->print("$row_end\n");
  if (exists($show{'proctor'})) {   if (exists($show{'proctor'})) {
     $r->print(<<STUFF);      $r->print(<<STUFF);
 <tr>  $row_start
  <td colspan="$colspan">$proctors</td>   <td colspan="$colspan">$proctors</td>
 </tr>  $row_end
 STUFF  STUFF
         }          }
     }      }
     $r->print('</table>');      $r->print(&Apache::loncommon::end_data_table().'</form>');
       return;
   }
   
   sub manage_reservations {
       my ($r,$type) = @_;
       my $navmap = Apache::lonnavmaps::navmap->new();
       $r->print('<p>'
                .&mt('Instructors may use a reservation system to place restrictions on when and where assignments can be worked on.')
                .'<br />'
                .&mt('One example is for management of laboratory space, which is only available at certain times, and has a limited number of seats.')
                .'</p><p>'
                .&mt('Your reservation status for any such assignments is listed below:')
                .'</p>'
       );
       if (!defined($navmap)) {
           $r->print('<div class="LC_error">'.
                     &mt('Unable to retrieve information about course contents').
                     '</div>');
           &Apache::lonnet::logthis('Manage Reservations - could not create navmap object in '.lc($type).':'.$env{'request.course.id'});
           return;
       }
       my (%parent,%shownparent,%container,%container_title,%contents);
       my ($depth,$count,$reservable,$lastcontainer,$rownum) = (0,0,0,0,0);
       my @backgrounds = ("LC_odd_row","LC_even_row");
       my $numcolors = scalar(@backgrounds);
       my $location=&Apache::loncommon::lonhttpdurl("/adm/lonIcons/whitespace_21.gif");
       $r->print('<table class="LC_data_table LC_tableOfContent">'."\n");
       my $it=$navmap->getIterator(undef,undef,undef,1,undef,undef);
       while (my $resource = $it->next()) {
           if ($resource == $it->BEGIN_MAP()) {
               $depth++;
               $parent{$depth} = $lastcontainer;
           }
           if ($resource == $it->END_MAP()) {
               $depth--;
               $lastcontainer = $parent{$depth};
           }
           if (ref($resource)) {
               my $symb = $resource->symb();
               my $ressymb = $symb;
               $contents{$lastcontainer} ++;
               next if (!$resource->is_problem() && !$resource->is_sequence() && 
                        !$resource->is_page());
               $count ++;
               if (($resource->is_sequence()) || ($resource->is_page())) {
                   $lastcontainer = $count;
                   $container{$lastcontainer} = $resource;
                   $container_title{$lastcontainer} = $resource->compTitle();
               }
               if ($resource->is_problem()) {
                   my ($useslots) = $resource->slot_control();
                   next if (($useslots eq '') || ($useslots =~ /^\s*no\s*$/i));
                   my ($msg,$get_choices,$slotdescription);
                   my $title = $resource->compTitle();
                   my $status = $resource->simpleStatus('0');
                   my ($slot_status,$date,$slot_name) = $resource->check_for_slot('0');
                   if ($slot_name ne '') {
                       my %slot=&Apache::lonnet::get_slot($slot_name);
                       $slotdescription=&get_description($slot_name,\%slot);
                   }
                   if ($slot_status == $resource->NOT_IN_A_SLOT) {
                       $msg=&mt('No current reservation.');
                       $get_choices = 1;
                   } elsif ($slot_status == $resource->NEEDS_CHECKIN) {
                       $msg='<span class="LC_nobreak">'.&mt('Reserved:').
                            '&nbsp;'.$slotdescription.'</span><br />'.
                            &mt('Access requires proctor validation.');
                   } elsif ($slot_status == $resource->WAITING_FOR_GRADE) {
                       $msg=&mt('Submitted and currently in grading queue.');
                   } elsif ($slot_status == $resource->CORRECT) {
                       $msg=&mt('Problem is unavailable.');
                   } elsif ($slot_status == $resource->RESERVED) {
                       $msg='<span class="LC_nobreak">'.&mt('Reserved:').
                            '&nbsp;'.$slotdescription.'</span><br />'.
                            &mt('Problem is currently available.');
                   } elsif ($slot_status == $resource->RESERVED_LOCATION) {
                       $msg='<span class="LC_nobreak">'.&mt('Reserved:').
                            '&nbsp;'.$slotdescription.'</span><br />'.
                            &mt('Problem is available at a different location.');
                       $get_choices = 1;
                   } elsif ($slot_status == $resource->RESERVED_LATER) {
                       $msg='<span class="LC_nobreak">'.&mt('Reserved:').
                            '&nbsp;'.$slotdescription.'</span><br />'.
                            &mt('Problem will be available later.');
                       $get_choices = 1;
                   } elsif ($slot_status == $resource->RESERVABLE) {
                       $msg=&mt('Reservation needed');
                       $get_choices = 1;
                   } elsif ($slot_status == $resource->NOTRESERVABLE) {
                       $msg=&mt('Reservation needed: none available.');
                   } elsif ($slot_status == $resource->UNKNOWN) {
                       $msg=&mt('Unable to determine status due to network problems.');
                   } else {
                       if ($status != $resource->OPEN) {
                           $msg = &Apache::lonnavmaps::getDescription($resource,'0'); 
                       }
                   }
                   $reservable ++;
                   my $treelevel = $depth;
                   my $higherup = $lastcontainer;
                   if ($depth > 1) {
                       my @maprows;
                       while ($treelevel > 1) {
                           if (ref($container{$higherup})) {
                               my $res = $container{$higherup};
                               last if (defined($shownparent{$higherup}));
                               my $maptitle = $res->compTitle();
                               my $type = 'sequence';
                               if ($res->is_page()) {
                                   $type = 'page';
                               }
                               &show_map_row($treelevel,$location,$type,$maptitle,
                                             \@maprows);
                               $shownparent{$higherup} = 1;
                           }
                           $treelevel --;
                           $higherup = $parent{$treelevel};
                       }
                       foreach my $item (@maprows) {
                           $rownum ++;
                           my $bgcolor = $backgrounds[$rownum % $numcolors];
                           $r->print('<tr class="'.$bgcolor.'">'.$item.'</tr>'."\n");
                       }
                   }
                   $rownum ++;
                   my $bgcolor = $backgrounds[$rownum % $numcolors];
                   $r->print('<tr class="'.$bgcolor.'"><td>'."\n");
                   for (my $i=0; $i<$depth; $i++) {
                       $r->print('<img src="'.$location.'" alt="" />');
                   }
                   my $result = '<a href="'.$resource->src().'?symb='.$symb.'">'.
                                '<img class="LC_contentImage" src="/adm/lonIcons/';
                   if ($resource->is_task()) {
                       $result .= 'task.gif" alt="'.&mt('Task');
                   } else {
                       $result .= 'problem.gif" alt="'.&mt('Problem');
                   }
                   $result .= '" /><b>'.$title.'</b></a>'.('&nbsp;' x6).'</td>';
                   my $hasaction;
                   if ($status == $resource->OPEN) {
                       if ($get_choices) {
                           $hasaction = 1;
                       }
                   }
                   if ($hasaction) {
                       $result .= '<td valgn="middle">'.$msg.'</td>'.
                                  '<td valign="middle">'.('&nbsp;' x6);
                   } else {
                       $result .= '<td colspan="2" valign="middle">'.$msg.'</td>';
                   }
                   $r->print($result);
                   if ($hasaction) {
                       my $formname = 'manageres_'.$reservable;
                       &show_choices($r,$symb,$formname);
                       $r->print('</td>');
                   }
                   $r->print('</tr>');
               }
           }
       }
       if (!$reservable) {
           $r->print('<span class="LC_info">'.&mt('No course items currently require a reservation to gain access.').'</span>');
       }
       $r->print('</table>'.
                 '<p><a href="/adm/slotrequest?command=showresv">'.
                 &mt('Reservation History').'</a></p>');
   }
   
   sub show_map_row {
       my ($depth,$location,$type,$title,$maprows) = @_;
       my $output = '<td>';
       for (my $i=0; $i<$depth-1; $i++) {
           $output .= '<img src="'.$location.'" alt="" />';
       }
       if ($type eq 'page') {
           $output .= '<img src="/adm/lonIcons/navmap.page.open.gif">&nbsp;'."\n";
       } else {
           $output .= '<img src="/adm/lonIcons/navmap.folder.open.gif">&nbsp;'."\n";
       }
       $output .= $title.'</td><td colspan="2">&nbsp;</td>'."\n";
       unshift (@{$maprows},$output);
       return;
   }
   
   sub show_reservations {
       my ($r,$uname,$udom) = @_;
       if (!defined($uname)) {
           $uname = $env{'user.name'};
       }
       if (!defined($udom)) {
           $udom = $env{'user.domain'};
       }
       my $formname = 'slotlog';
       my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
       my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
       my %log=&Apache::lonnet::dump('nohist_'.$cdom.'_'.$cnum.'_slotlog',$udom,$uname);
       if ($env{'form.origin'} eq 'aboutme') {
           $r->print('<div class="LC_fontsize_large">'.
                     &mt('History of student-reservable slots for: [_1]',
                         &Apache::loncommon::plainname($env{'form.uname'},$env{'form.udom'},
                                                       'firstname')).'</div>');
       }
       $r->print('<form action="/adm/slotrequest" method="post" name="'.$formname.'">');
       # set defaults
       my $now = time();
       my $defstart = $now - (7*24*3600); #7 days ago
       my %defaults = (
                        page           => '1',
                        show           => '10',
                        action         => 'any',
                        log_start_date => $defstart,
                        log_end_date   => $now,
                      );
       my $more_records = 0;
   
       # set current
       my %curr;
       foreach my $item ('show','page','action') {
           $curr{$item} = $env{'form.'.$item};
       }
       my ($startdate,$enddate) =
           &Apache::lonuserutils::get_dates_from_form('log_start_date',
                                                      'log_end_date');
       $curr{'log_start_date'} = $startdate;
       $curr{'log_end_date'} = $enddate;
       foreach my $key (keys(%defaults)) {
           if ($curr{$key} eq '') {
               $curr{$key} = $defaults{$key};
           }
       }
       my ($version) = ($r->dir_config('lonVersion') =~ /^([\d\.]+)\-/);
       $r->print(&display_filter($formname,$cdom,$cnum,\%curr,$version));
       my $showntablehdr = 0;
       my $tablehdr = &Apache::loncommon::start_data_table().
                      &Apache::loncommon::start_data_table_header_row().
                      '<th>&nbsp;</th><th>'.&mt('When').'</th><th>'.&mt('Action').'</th>'.
                      '<th>'.&mt('Description').'</th><th>'.&mt('Start time').'</th>'.
                      '<th>'.&mt('End time').'</th><th>'.&mt('Resource').'</th>'.
                      &Apache::loncommon::end_data_table_header_row();
       my ($minshown,$maxshown);
       $minshown = 1;
       my $count = 0;
       if ($curr{'show'} ne &mt('all')) {
           $maxshown = $curr{'page'} * $curr{'show'};
           if ($curr{'page'} > 1) {
               $minshown = 1 + ($curr{'page'} - 1) * $curr{'show'};
           }
       }
       my (%titles,%maptitles);
       my %lt = &reservationlog_contexts();
       foreach my $id (sort { $log{$b}{'exe_time'}<=>$log{$a}{'exe_time'} } (keys(%log))) {
           next if (($log{$id}{'exe_time'} < $curr{'log_start_date'}) ||
                    ($log{$id}{'exe_time'} > $curr{'log_end_date'}));
           if ($curr{'show'} ne &mt('all')) {
               if ($count >= $curr{'page'} * $curr{'show'}) {
                   $more_records = 1;
                   last;
               }
           }
           if ($curr{'action'} ne 'any') {
               next if ($log{$id}{'logentry'}{'action'} ne $curr{'action'});
           }
           $count ++;
           next if ($count < $minshown);
           if (!$showntablehdr) {
               $r->print($tablehdr);
               $showntablehdr = 1;
           }
           my $symb = $log{$id}{'logentry'}{'symb'};
           my $slot_name = $log{$id}{'logentry'}{'slot'};
           my %slot=&Apache::lonnet::get_slot($slot_name);
           my $description = $slot{'description'};
           my $start = ($slot{'starttime'}?
                        &Apache::lonlocal::locallocaltime($slot{'starttime'}):'');
           my $end = ($slot{'endtime'}?
                      &Apache::lonlocal::locallocaltime($slot{'endtime'}):'');
           my $title = &get_resource_title($symb,\%titles,\%maptitles);
           my $chgaction = $log{$id}{'logentry'}{'action'};
           if ($chgaction ne '' && $lt{$chgaction} ne '') {
               $chgaction = $lt{$chgaction};
           }
           $r->print(&Apache::loncommon::start_data_table_row().'<td>'.$count.'</td><td>'.&Apache::lonlocal::locallocaltime($log{$id}{'exe_time'}).'</td><td>'.$chgaction.'</td><td>'.$description.'</td><td>'.$start.'</td><td>'.$end.'</td><td>'.$title.'</td>'.&Apache::loncommon::end_data_table_row()."\n");
       }
       if ($showntablehdr) {
           $r->print(&Apache::loncommon::end_data_table().'<br />');
           if (($curr{'page'} > 1) || ($more_records)) {
               $r->print('<table><tr>');
               if ($curr{'page'} > 1) {
                   $r->print('<td><a href="javascript:chgPage('."'previous'".');">'.&mt('Previous [_1] changes',$curr{'show'}).'</a></td>');
               }
               if ($more_records) {
                   $r->print('<td><a href="javascript:chgPage('."'next'".');">'.&mt('Next [_1] changes',$curr{'show'}).'</a></td>');
               }
               $r->print('</tr></table>');
               $r->print(<<"ENDSCRIPT");
   <script type="text/javascript">
   function chgPage(caller) {
       if (caller == 'previous') {
           document.$formname.page.value --;
       }
       if (caller == 'next') {
           document.$formname.page.value ++;
       }
       document.$formname.submit();
       return;
   }
   </script>
   ENDSCRIPT
           }
       } else {
           $r->print('<span class="LC_info">'
                    .&mt('There are no transactions to display')
                    .'</span>'
           );
       }
       $r->print('<input type="hidden" name="page" value="'.$curr{'page'}.'" />'."\n".
                 '<input type="hidden" name="command" value="showresv" />'."\n");
       if ($env{'form.origin'} eq 'aboutme') {
           $r->print('<input type="hidden" name="origin" value="'.$env{'form.origin'}.'" />'."\n".
                     '<input type="hidden" name="uname" value="'.$env{'form.uname'}.'" />'."\n".
                     '<input type="hidden" name="udom" value="'.$env{'form.udom'}.'" />'."\n");
       }
       $r->print('</form>');
       return;
   }
   
   sub show_reservations_log {
       my ($r) = @_;
       my $badslot;
       if ($env{'form.slotname'} eq '') {
           $r->print('<div class="LC_warning">'.&mt('No slot name provided').'</div>');
           $badslot = 1;
       } else {
           my %slot=&Apache::lonnet::get_slot($env{'form.slotname'});
           if (keys(%slot) == 0) {
               $r->print('<div class="LC_warning">'.&mt('Invalid slot name: [_1]',$env{'form.slotname'}).'</div>');
               $badslot = 1;
           } elsif ($slot{type} ne 'schedulable_student') {
               my $description = &get_description($env{'form.slotname'},\%slot);
               $r->print('<div class="LC_warning">'.&mt('Reservation history unavailable for non-student-reservable slot: [_1].',$description).'</div>');
               $badslot = 1;
           }
       }
       if ($badslot) {
           $r->print('<p><a href="/adm/slotrequest?command=showslots">'.
                     &mt('Return to slot list').'</a></p>');
           return;
       }
       my $formname = 'reservationslog';
       my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
       my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
       my %slotlog=&Apache::lonnet::dump('nohist_slotreservationslog',$cdom,$cnum);
       if ((keys(%slotlog))[0]=~/^error\:/) { undef(%slotlog); }
   
       my (%log,@allsymbs);
       if (keys(%slotlog)) {
           foreach my $key (keys(%slotlog)) {
               if (ref($slotlog{$key}) eq 'HASH') {
                   if (ref($slotlog{$key}{'logentry'}) eq 'HASH') {
                       if ($slotlog{$key}{'logentry'}{'slot'} eq $env{'form.slotname'}) {
                           $log{$key} = $slotlog{$key};
                           if ($slotlog{$key}{'logentry'}{'symb'} ne '') {
                               push(@allsymbs,$slotlog{$key}{'logentry'}{'symb'});
                           }
                       }
                   }
               }
           }
       }
   
       $r->print('<form action="/adm/slotrequest" method="post" name="'.$formname.'">');
       my %saveable_parameters = ('show' => 'scalar',);
       &Apache::loncommon::store_course_settings('reservationslog',
                                                 \%saveable_parameters);
       &Apache::loncommon::restore_course_settings('reservationslog',
                                                   \%saveable_parameters);
       # set defaults
       my $now = time();
       my $defstart = $now - (7*24*3600); #7 days ago
       my %defaults = (
                        page           => '1',
                        show           => '10',
                        chgcontext     => 'any',
                        action         => 'any',
                        symb           => 'any',
                        log_start_date => $defstart,
                        log_end_date   => $now,
                      );
       my $more_records = 0;
   
       # set current
       my %curr;
       foreach my $item ('show','page','chgcontext','action','symb') {
           $curr{$item} = $env{'form.'.$item};
       }
       my ($startdate,$enddate) =
           &Apache::lonuserutils::get_dates_from_form('log_start_date',
                                                      'log_end_date');
       $curr{'log_start_date'} = $startdate;
       $curr{'log_end_date'} = $enddate;
       foreach my $key (keys(%defaults)) {
           if ($curr{$key} eq '') {
               $curr{$key} = $defaults{$key};
           }
       }
       my (%whodunit,%changed,$version);
       ($version) = ($r->dir_config('lonVersion') =~ /^([\d\.]+)\-/);
   
       my %slot=&Apache::lonnet::get_slot($env{'form.slotname'});
       my $description = $slot{'description'};
       $r->print('<span class="LC_fontsize_large">'.
                 &mt('Reservation changes for student-reservable slot: [_1]',$description).'</span><br />');
   
       $r->print(&display_filter($formname,$cdom,$cnum,\%curr,$version,\@allsymbs));
       my $showntablehdr = 0;
       my $tablehdr = &Apache::loncommon::start_data_table().
                      &Apache::loncommon::start_data_table_header_row().
                      '<th>&nbsp;</th><th>'.&mt('When').'</th><th>'.&mt('Who made the change').
                      '</th><th>'.&mt('Affected User').'</th><th>'.&mt('Action').'</th>'.
                      '<th>'.&mt('Resource').'</th><th>'.&mt('Context').'</th>'.
                      &Apache::loncommon::end_data_table_header_row();
       my ($minshown,$maxshown);
       $minshown = 1;
       my $count = 0;
       if ($curr{'show'} ne &mt('all')) {
           $maxshown = $curr{'page'} * $curr{'show'};
           if ($curr{'page'} > 1) {
               $minshown = 1 + ($curr{'page'} - 1) * $curr{'show'};
           }
       }
       my %lt = &reservationlog_contexts();
       my (%titles,%maptitles);
       foreach my $id (sort { $log{$b}{'exe_time'}<=>$log{$a}{'exe_time'} } (keys(%log))) {
           next if (($log{$id}{'exe_time'} < $curr{'log_start_date'}) ||
                    ($log{$id}{'exe_time'} > $curr{'log_end_date'}));
           if ($curr{'show'} ne &mt('all')) {
               if ($count >= $curr{'page'} * $curr{'show'}) {
                   $more_records = 1;
                   last;
               }
           }
           if ($curr{'chgcontext'} ne 'any') {
               if ($curr{'chgcontext'} eq 'user') {
                   next if (($log{$id}{'logentry'}{'context'} ne 'user') && 
                            ($log{$id}{'logentry'}{'context'} ne 'usermanage'));
               } else {
                   next if ($log{$id}{'logentry'}{'context'} ne $curr{'chgcontext'});
               }
           }
           if ($curr{'action'} ne 'any') {
               next if ($log{$id}{'logentry'}{'action'} ne $curr{'action'});
           }
           if ($curr{'symb'} ne 'any') {
               next if ($log{$id}{'logentry'}{'symb'} ne $curr{'symb'});
           }
           $count ++;
           next if ($count < $minshown);
           if (!$showntablehdr) {
               $r->print($tablehdr);
               $showntablehdr = 1;
           }
           if ($whodunit{$log{$id}{'exe_uname'}.':'.$log{$id}{'exe_udom'}} eq '') {
               $whodunit{$log{$id}{'exe_uname'}.':'.$log{$id}{'exe_udom'}} =
                   &Apache::loncommon::plainname($log{$id}{'exe_uname'},$log{$id}{'exe_udom'});
           }
           if ($changed{$log{$id}{'uname'}.':'.$log{$id}{'udom'}} eq '') {
               $changed{$log{$id}{'uname'}.':'.$log{$id}{'udom'}} =
                   &Apache::loncommon::plainname($log{$id}{'uname'},$log{$id}{'udom'});
           }
           my $symb = $log{$id}{'logentry'}{'symb'};
           my $title = &get_resource_title($symb,\%titles,\%maptitles); 
           my $chgcontext = $log{$id}{'logentry'}{'context'};
           if ($chgcontext ne '' && $lt{$chgcontext} ne '') {
               $chgcontext = $lt{$chgcontext};
           }
           my $chgaction = $log{$id}{'logentry'}{'action'};
           if ($chgaction ne '' && $lt{$chgaction} ne '') {
               $chgaction = $lt{$chgaction}; 
           }
           $r->print(&Apache::loncommon::start_data_table_row().'<td>'.$count.'</td><td>'.&Apache::lonlocal::locallocaltime($log{$id}{'exe_time'}).'</td><td>'.$whodunit{$log{$id}{'exe_uname'}.':'.$log{$id}{'exe_udom'}}.'</td><td>'.$changed{$log{$id}{'uname'}.':'.$log{$id}{'udom'}}.'</td><td>'.$chgaction.'</td><td>'.$title.'</td><td>'.$chgcontext.'</td>'.&Apache::loncommon::end_data_table_row()."\n");
       }
       if ($showntablehdr) {
           $r->print(&Apache::loncommon::end_data_table().'<br />');
           if (($curr{'page'} > 1) || ($more_records)) {
               $r->print('<table><tr>');
               if ($curr{'page'} > 1) {
                   $r->print('<td><a href="javascript:chgPage('."'previous'".');">'.&mt('Previous [_1] changes',$curr{'show'}).'</a></td>');
               }
               if ($more_records) {
                   $r->print('<td><a href="javascript:chgPage('."'next'".');">'.&mt('Next [_1] changes',$curr{'show'}).'</a></td>');
               }
               $r->print('</tr></table>');
               $r->print(<<"ENDSCRIPT");
   <script type="text/javascript">
   function chgPage(caller) {
       if (caller == 'previous') {
           document.$formname.page.value --;
       }
       if (caller == 'next') {
           document.$formname.page.value ++;
       }
       document.$formname.submit();
       return;
   }
   </script>
   ENDSCRIPT
           }
       } else {
           $r->print(&mt('There are no records to display'));
       }
       $r->print('<input type="hidden" name="page" value="'.$curr{'page'}.'" />'.
                 '<input type="hidden" name="slotname" value="'.$env{'form.slotname'}.'" />'.
                 '<input type="hidden" name="command" value="slotlog" /></form>'.
                 '<p><a href="/adm/slotrequest?command=showslots">'.
                 &mt('Return to slot list').'</a></p>');
       return;
   }
   
   sub get_resource_title {
       my ($symb,$titles,$maptitles) = @_;
       my $title;
       if ((ref($titles) eq 'HASH') && (ref($maptitles) eq 'HASH')) { 
           if (defined($titles->{$symb})) {
               $title = $titles->{$symb};
           } else {
               $title = &Apache::lonnet::gettitle($symb);
               my $maptitle;
               my ($mapurl) = &Apache::lonnet::decode_symb($symb);
               if (defined($maptitles->{$mapurl})) {
                   $maptitle = $maptitles->{$mapurl};
               } else {
                   if ($mapurl eq $env{'course.'.$env{'request.course.id'}.'.url'}) {
                       $maptitle=&mt('Main Course Documents');
                   } else {
                       $maptitle=&Apache::lonnet::gettitle($mapurl);
                   }
                   $maptitles->{$mapurl} = $maptitle;
               }
               if ($maptitle ne '') {
                   $title .= ' '.&mt('(in [_1])',$maptitle);
               }
               $titles->{$symb} = $title;
           }
       } else {
           $title = $symb;
       }
       return $title;
   }
   
   sub reservationlog_contexts {
       my %lt = &Apache::lonlocal::texthash (
                                                any        => 'Any',
                                                user       => 'By student',
                                                manage     => 'Via Slot Manager',
                                                parameter  => 'Via Parameter Manager',
                                                reserve    => 'Made reservation',
                                                release    => 'Dropped reservation',
                                                usermanage => 'By student', 
                                            );
       return %lt;
   }
   
   sub display_filter {
       my ($formname,$cdom,$cnum,$curr,$version,$allsymbs) = @_;
       my $nolink = 1;
       my (%titles,%maptitles);
       my $output = '<br /><table><tr><td valign="top">'.
                    '<span class="LC_nobreak"><b>'.&mt('Changes/page:').'</b><br />'.
                    &Apache::lonmeta::selectbox('show',$curr->{'show'},undef,
                                                 (&mt('all'),5,10,20,50,100,1000,10000)).
                    '</td><td>&nbsp;&nbsp;</td>';
       my $startform =
           &Apache::lonhtmlcommon::date_setter($formname,'log_start_date',
                                               $curr->{'log_start_date'},undef,
                                               undef,undef,undef,undef,undef,undef,$nolink);
       my $endform =
           &Apache::lonhtmlcommon::date_setter($formname,'log_end_date',
                                               $curr->{'log_end_date'},undef,
                                               undef,undef,undef,undef,undef,undef,$nolink);
       my %lt = &reservationlog_contexts();
       $output .= '<td valign="top"><b>'.&mt('Window during which changes occurred:').
                  '</b><br /><table><tr><td>'.&mt('After:').
                  '</td><td>'.$startform.'</td></tr><tr><td>'.&mt('Before:').'</td><td>'.
                  $endform.'</td></tr></table></td><td>&nbsp;&nbsp;</td>';
       if (ref($allsymbs) eq 'ARRAY') {
           $output .= '<td valign="top"><b>'.&mt('Resource').'</b><br />'.
                      '<select name="resource"><option value="any"';
           if ($curr->{'resource'} eq 'any') {
               $output .= ' selected="selected"';
           }
           $output .=  '>'.&mt('Any').'</option>'."\n";
           foreach my $symb (@{$allsymbs}) {
               my $title = &get_resource_title($symb,\%titles,\%maptitles);
               my $selstr = '';
               if ($curr->{'resource'} eq $symb) {
                   $selstr = ' selected="selected"';
               }
               $output .= '  <option value="'.$symb.'"'.$selstr.'>'.$title.'</option>';
           }
           $output .= '</select></td><td>&nbsp;&nbsp;</td><td valign="top"><b>'.
                      &mt('Context:').'</b><br /><select name="chgcontext">';
           foreach my $chgtype ('any','user','manage','parameter') {
               my $selstr = '';
               if ($curr->{'chgcontext'} eq $chgtype) {
                   $output .= $selstr = ' selected="selected"';
               }
               $output .= '<option value="'.$chgtype.'"'.$selstr.'>'.$lt{$chgtype}.'</option>'."\n";
           }
           $output .= '</select></td>';
       } else {
           $output .= '<td valign="top"><b>'.&mt('Action').'</b><br />'.
                      '<select name="action"><option value="any"';
           if ($curr->{'action'} eq 'any') {
               $output .= ' selected="selected"';
           }
           $output .=  '>'.&mt('Any').'</option>'."\n";
           foreach my $actiontype ('reserve','release') {
               my $selstr = '';
               if ($curr->{'action'} eq $actiontype) {
                   $output .= $selstr = ' selected="selected"';
               }
               $output .= '<option value="'.$actiontype.'"'.$selstr.'>'.$lt{$actiontype}.'</option>'."\n";
           }
           $output .= '</select></td>';
       }
       $output .= '<td>&nbsp;&nbsp;</td><td valign="middle"><input type="submit" value="'.
                  &mt('Update Display').'" /></tr></table>'.
                  '<span class="LC_roleslog_note">'.
                  &mt('[_1]Note:[_2] Only changes made from servers running LON-CAPA 2.8.99.0 or later are displayed.');
       if ($version) {
           $output .= ' '.&mt('This server is version [_3].','<b>','</b>',$version);
       }
       $output .= '</span><hr noshade><br />';
       return $output;
 }  }
   
 sub upload_start {  sub upload_start {
     my ($r)=@_;          my ($r)=@_;    
     $r->print(&Apache::grades::checkforfile_js());      $r->print(&Apache::grades::checkforfile_js());
     my $result.='<table width=100% border=0><tr bgcolor="#e6ffff"><td>'."\n";      my $result.='<table width="100%" border="0"><tr bgcolor="#E6FFFF"><td>'."\n";
     $result.='&nbsp;<b>'.      $result.='&nbsp;<b>'.
  &mt('Specify a file containing the slot definitions.').   &mt('Specify a file containing the slot definitions.').
  '</b></td></tr>'."\n";   '</b></td></tr>'."\n";
     $result.='<tr bgcolor=#ffffe6><td>'."\n";      $result.='<tr bgcolor="#ffffe6"><td>'."\n";
     my $upfile_select=&Apache::loncommon::upfile_select_html();      my $upfile_select=&Apache::loncommon::upfile_select_html();
     my $ignore=&mt('Ignore First Line');      my $ignore=&mt('Ignore First Line');
     $result.=<<ENDUPFORM;      $result.=<<ENDUPFORM;
Line 1235  sub csvuploadmap_header { Line 2094  sub csvuploadmap_header {
   
     my $checked=(($env{'form.noFirstLine'})?' checked="checked"':'');      my $checked=(($env{'form.noFirstLine'})?' checked="checked"':'');
     my $ignore=&mt('Ignore First Line');      my $ignore=&mt('Ignore First Line');
    my $help_field = &Apache::loncommon::help_open_topic('Slot SelectingField');
   
     $r->print(<<ENDPICK);      $r->print(<<ENDPICK);
 <form method="post" enctype="multipart/form-data" action="/adm/slotrequest" name="slotupload">  <form method="post" enctype="multipart/form-data" action="/adm/slotrequest" name="slotupload">
 <h3>Identify fields</h3>  <h3>Identify fields $help_field</h3>
 Total number of records found in file: $distotal <hr />  Total number of records found in file: $distotal <hr />
 Enter as many fields as you can. The system will inform you and bring you back  Enter as many fields as you can. The system will inform you and bring you back
 to this page if the data selected is insufficient to create the slots.<hr />  to this page if the data selected is insufficient to create the slots.<hr />
Line 1261  ENDPICK Line 2122  ENDPICK
   
 sub csvuploadmap_footer {  sub csvuploadmap_footer {
     my ($request,$i,$keyfields) =@_;      my ($request,$i,$keyfields) =@_;
       my $buttontext = &mt('Create Slots');
     $request->print(<<ENDPICK);      $request->print(<<ENDPICK);
 </table>  </table>
 <input type="hidden" name="nfields" value="$i" />  <input type="hidden" name="nfields" value="$i" />
 <input type="hidden" name="keyfields" value="$keyfields" />  <input type="hidden" name="keyfields" value="$keyfields" />
 <input type="button" onClick="javascript:verify(this.form)" value="Create Slots" /><br />  <input type="button" onClick="javascript:verify(this.form)" value="$buttontext" /><br />
 </form>  </form>
 ENDPICK  ENDPICK
 }  }
Line 1382  sub csv_upload_assign { Line 2244  sub csv_upload_assign {
     my @slotdata = &Apache::loncommon::upfile_record_sep();      my @slotdata = &Apache::loncommon::upfile_record_sep();
     if ($env{'form.noFirstLine'}) { shift(@slotdata); }      if ($env{'form.noFirstLine'}) { shift(@slotdata); }
     my %fields=&Apache::grades::get_fields();      my %fields=&Apache::grades::get_fields();
     $r->print('<h3>Creating Slots</h3>');      $r->print('<h3>'.&mt('Creating Slots').'</h3>');
     my $cname=$env{'course.'.$env{'request.course.id'}.'.num'};      my $cname=$env{'course.'.$env{'request.course.id'}.'.num'};
     my $cdom=$env{'course.'.$env{'request.course.id'}.'.domain'};      my $cdom=$env{'course.'.$env{'request.course.id'}.'.domain'};
     my $countdone=0;      my $countdone=0;
Line 1469  sub csv_upload_assign { Line 2331  sub csv_upload_assign {
  $r->rflush();   $r->rflush();
  $countdone++;   $countdone++;
     }      }
     $r->print("<p>Created $countdone slots\n</p>");      $r->print('<p>'.&mt('Created [quant,_1,slot]',$countdone)."\n".'</p>');
     foreach my $error (@errors) {      foreach my $error (@errors) {
  $r->print("<p>$error\n</p>");   $r->print('<p><span class="LC_warning">'.$error.'</span></p>'."\n");
     }      }
     &show_table($r,$mgr);      &show_table($r,$mgr);
     return '';      return '';
 }  }
   
   sub slot_command_titles {
       my %titles = (
                    slotlog            => 'Reservation Logs',
                    showslots          => 'Manage Slots',
                    showresv           => 'Reservation History',
                    manageresv         => 'Manage Reservations',
                    uploadstart        => 'Upload Slots File',
                    csvuploadmap       => 'Upload Slots File',
                    csvuploadassign    => 'Upload Slots File',
                    delete             => 'Slot Deletion',
                    release            => 'Reservation Result',
                    remove_reservation => 'Remove Registration',
                    get_reservation    => 'Request Reservation',
                 );
       return %titles;
   }
   
 sub handler {  sub handler {
     my $r=shift;      my $r=shift;
   
Line 1488  sub handler { Line 2367  sub handler {
     }      }
   
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'});      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'});
       
       my %crumb_titles = &slot_command_titles();
       my $brcrum;
   
     my $vgr=&Apache::lonnet::allowed('vgr',$env{'request.course.id'});      my $vgr=&Apache::lonnet::allowed('vgr',$env{'request.course.id'});
     my $mgr=&Apache::lonnet::allowed('mgr',$env{'request.course.id'});      my $mgr=&Apache::lonnet::allowed('mgr',$env{'request.course.id'});
       if ($env{'form.command'} eq 'showslots') {
           if (($vgr ne 'F') && ($mgr ne 'F')) {
               $env{'form.command'} = 'manageresv'; 
           }
       } elsif ($env{'form.command'} eq 'manageresv') {
           if (($vgr eq 'F') || ($mgr eq 'F')) {
               $env{'form.command'} = 'showslots';
           }
       }
     my $title='Requesting Another Worktime';      my $title='Requesting Another Worktime';
     if ($env{'form.command'} =~ /^(showslots|uploadstart|csvuploadmap|csvuploadassign)$/ && $vgr eq 'F') {      if ($env{'form.command'} eq 'showresv') {
  $title = 'Managing Slots';          $title = 'Reservation History';
           if ($env{'form.origin'} eq 'aboutme') {
               $brcrum =[{href=>"/adm/$env{'form.udom'}/$env{'form.uname'}/aboutme",text=>'Personal Information Page'}];
           } else {
               $brcrum =[{href=>"/adm/slotrequest?command=manageresv",text=>'Manage Reservations'}];
           }
           if (ref($brcrum) eq 'ARRAY') {
               push(@{$brcrum},{href=>"/adm/slotrequest?command=showresv",text=>$title});
           }
       } elsif ($env{'form.command'} eq 'manageresv') {
           $title = 'Manage Reservations';
           $brcrum =[{href=>"/adm/slotrequest?command=manageresv",text=>$title}];
       } elsif ($vgr eq 'F') {
           if ($env{'form.command'} =~ /^(slotlog|showslots|uploadstart|csvuploadmap|csvuploadassign|delete|release|remove_registration)$/) {
               $brcrum =[{href=>"/adm/slotrequest?command=showslots",
                          text=>$crumb_titles{'showslots'}}];
       $title = 'Managing Slots';
               unless ($env{'form.command'} eq 'showslots') {
                   if (ref($brcrum) eq 'ARRAY') {
                       push(@{$brcrum},{href=>"/adm/slotrequest?command=$env{'form.command'}",text=>$crumb_titles{$env{'form.command'}}});
                   }
               }
           }
       } elsif ($env{'form.command'} eq 'release') {
           if ($env{'form.context'} eq 'usermanage') {
               $brcrum =[{href=>"/adm/slotrequest?command=manageresv",
                          text=>$crumb_titles{'showslots'}}];
               $title = 'Manage Reservations';
               if (ref($brcrum) eq 'ARRAY') {
                   push(@{$brcrum},{href=>"/adm/slotrequest?command=$env{'form.command'}",text=>$crumb_titles{$env{'form.command'}}});
               }
               
           }
     }      }
     &start_page($r,$title);      &start_page($r,$title,$brcrum);
   
     if ($env{'form.command'} eq 'showslots' && $vgr eq 'F') {      if ($env{'form.command'} eq 'manageresv') {
           my $crstype = &Apache::loncommon::course_type();
           &manage_reservations($r,$crstype);
       } elsif ($env{'form.command'} eq 'showresv') {
           &show_reservations($r,$env{'form.uname'},$env{'form.udom'});
       } elsif ($env{'form.command'} eq 'showslots' && $vgr eq 'F') {
  &show_table($r,$mgr);   &show_table($r,$mgr);
     } elsif ($env{'form.command'} eq 'remove_registration' && $mgr eq 'F') {      } elsif ($env{'form.command'} eq 'remove_registration' && $mgr eq 'F') {
  &remove_registration($r);   &remove_registration($r);
Line 1524  sub handler { Line 2452  sub handler {
     }      }
     &csv_upload_map($r);      &csv_upload_map($r);
  }   }
       } elsif ($env{'form.command'} eq 'slotlog' && $mgr eq 'F') {
           &show_reservations_log($r);
     } else {      } else {
  my $symb=&Apache::lonnet::unescape($env{'form.symb'});   my $symb=&unescape($env{'form.symb'});
    if (!defined($symb)) {
       &fail($r,'not_valid');
       return OK;
    }
  my (undef,undef,$res)=&Apache::lonnet::decode_symb($symb);   my (undef,undef,$res)=&Apache::lonnet::decode_symb($symb);
  my $useslots = &Apache::lonnet::EXT("resource.0.useslots",$symb);   my $useslots = &Apache::lonnet::EXT("resource.0.useslots",$symb);
  if ($useslots ne 'resource') {   if ($useslots ne 'resource' 
     &fail($r,'not_valid');      && $useslots ne 'map' 
       && $useslots ne 'map_map') {
       &fail($r,'not_available');
     return OK;      return OK;
  }   }
  $env{'request.symb'}=$symb;   $env{'request.symb'}=$symb;
Line 1549  sub handler { Line 2485  sub handler {
  } elsif ($env{'form.command'} eq 'get') {   } elsif ($env{'form.command'} eq 'get') {
     &get_slot($r,$symb);      &get_slot($r,$symb);
  } elsif ($env{'form.command'} eq 'change') {   } elsif ($env{'form.command'} eq 'change') {
     if (&release_slot($r,$symb,$env{'form.releaseslot'},1)) {      if (&get_slot($r,$symb,$env{'form.releaseslot'},1)) {
  &get_slot($r,$symb);   &release_slot($r,$symb,$env{'form.releaseslot'});
     }      }
  } else {   } else {
     $r->print("<p>Unknown command: ".$env{'form.command'}."</p>");      $r->print('<p>'.&mt('Unknown command: [_1]',$env{'form.command'}).'</p>');
  }   }
     }      }
     &end_page($r);      &end_page($r);

Removed from v.1.58  
changed lines
  Added in v.1.95


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>