Diff for /loncom/interface/slotrequest.pm between versions 1.45 and 1.113

version 1.45, 2006/02/06 22:42:11 version 1.113, 2012/06/09 15:41:26
Line 34  use Apache::Constants qw(:common :http : Line 34  use Apache::Constants qw(:common :http :
 use Apache::loncommon();  use Apache::loncommon();
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::lonnet;  use Apache::lonnet;
   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 52  sub fail { Line 56  sub fail {
 }  }
   
 sub start_page {  sub start_page {
     my ($r,$title)=@_;      my ($r,$title,$brcrum)=@_;
     my $html=&Apache::lonxml::xmlbegin();      my $args;
     $r->print($html.'<head><title>'.&mt($title).'</title></head>');      if (ref($brcrum) eq 'ARRAY') {
     $r->print(&Apache::loncommon::bodytag($title));          $args = {bread_crumbs => $brcrum};
       }
       $r->print(&Apache::loncommon::start_page($title,undef,$args));
 }  }
   
 sub end_page {  sub end_page {
     my ($r)=@_;      my ($r)=@_;
     $r->print(&Apache::loncommon::endbodytag().'</html>');      $r->print(&Apache::loncommon::end_page());
 }  }
   
 =pod  =pod
Line 75  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 88  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 125  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,'starttime');
  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 ".
        $slots{$slot_name}->{'starttime'}." -- ".         $slots{$slot_name}->{'starttime'}." -- ".
        $slots{$slot_name}->{'startreserve'});         $slots{$slot_name}->{'startreserve'}." -- ".
  if ($slots{$slot_name}->{'endtime'} > time &&                                 $slots{$slot_name}->{'endreserve'});
     $slots{$slot_name}->{'startreserve'} < time) {   if (($slots{$slot_name}->{'endtime'} > time) &&
     # between start of reservation times and end of slot      ($slots{$slot_name}->{'startreserve'} < time) &&
               ((!$slots{$slot_name}->{'endreserve'}) || 
                ($slots{$slot_name}->{'endreserve'} > time))) {
       # between start of reservation time and end of reservation time
               # and before end of slot
     if ($mode eq 'allslots') {      if ($mode eq 'allslots') {
  push(@got,$slot_name);   push(@got,$slot_name);
     } else {      } else {
Line 159  sub check_for_reservation { Line 164  sub check_for_reservation {
     return (undef,undef);      return (undef,undef);
 }  }
   
 sub check_for_conflict {  sub get_consumed_uniqueperiods {
     my ($symb,$new_slot_name,$new_slot,$slots)=@_;      my ($slots) = @_;
       my $navmap=Apache::lonnavmaps::navmap->new;
     if (!defined($new_slot->{'uniqueperiod'})) { return undef; }      if (!defined($navmap)) {
           return 'error: Unable to determine current status';
       }
       my @problems = $navmap->retrieveResources(undef,
         sub { $_[0]->is_problem() },1,0);
       my %used_slots;
       foreach my $problem (@problems) {
    my $symb = $problem->symb();
    my $student = &Apache::lonnet::EXT("resource.0.availablestudent",
      $symb, $env{'user.domain'},
      $env{'user.name'});
    my $course =  &Apache::lonnet::EXT("resource.0.available",
      $symb, $env{'user.domain'},
      $env{'user.name'});
    if (&Apache::lonnet::error($student) 
       || &Apache::lonnet::error($course)) {
       return 'error: Unable to determine current status';
    }
    foreach my $slot (split(/:/,$student), split(/:/, $course)) {
       $used_slots{$slot}=1;
    }
       }
   
     my $student = &Apache::lonnet::EXT("resource.0.availablestudent", $symb,  
        $env{'user.domain'}, $env{'user.name'});  
     my $course =  &Apache::lonnet::EXT("resource.0.available",        $symb,  
        $env{'user.domain'}, $env{'user.name'});  
     my @slots = (split(/:/,$student), split(/:/, $course));  
     my ($cnum,$cdom)=&get_course();  
     if (!ref($slots)) {      if (!ref($slots)) {
  my %slots=&Apache::lonnet::get('slots', [@slots], $cdom, $cnum);   my ($cnum,$cdom)=&get_course();
    my %slots=&Apache::lonnet::get('slots', [keys(%used_slots)], $cdom, $cnum);
    if (&Apache::lonnet::error(%slots)) {
       return 'error: Unable to determine current status';
    }
  $slots = \%slots;   $slots = \%slots;
     }      }
   
     if (&network_error($student) || &network_error($course)  ||      my %consumed_uniqueperiods;
  &network_error(%$slots)) {      foreach my $slot_name (keys(%used_slots)) {
  return 'error: Unable to determine current status';  
     }      
   
     my ($new_uniq_start,$new_uniq_end) = @{$new_slot->{'uniqueperiod'}};  
     foreach my $slot_name (@slots) {  
  next if (!defined($slots->{$slot_name}) ||   next if (!defined($slots->{$slot_name}) ||
  !ref($slots->{$slot_name}));   !ref($slots->{$slot_name}));
   
         next if (!defined($slots->{$slot_name}{'uniqueperiod'}) ||          next if (!defined($slots->{$slot_name}{'uniqueperiod'}) ||
  !ref($slots->{$slot_name}{'uniqueperiod'}));   !ref($slots->{$slot_name}{'uniqueperiod'}));
  my ($start,$end)=@{$slots->{$slot_name}{'uniqueperiod'}};   $consumed_uniqueperiods{$slot_name} = 
       $slots->{$slot_name}{'uniqueperiod'};
       }
       return \%consumed_uniqueperiods;
   }
   
   sub check_for_conflict {
       my ($symb,$new_slot_name,$new_slot,$slots,$consumed_uniqueperiods)=@_;
   
       if (!defined($new_slot->{'uniqueperiod'})) { return undef; }
   
       if (!ref($consumed_uniqueperiods)) {
    $consumed_uniqueperiods = &get_consumed_uniqueperiods($slots);
           if (ref($consumed_uniqueperiods) eq 'HASH') {
       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'}};
       foreach my $slot_name (keys(%$consumed_uniqueperiods)) {
    my ($start,$end)=@{$consumed_uniqueperiods->{$slot_name}};
  if (!   if (!
     ($start < $new_uniq_start &&  $end < $new_uniq_start) ||      ($start < $new_uniq_start &&  $end < $new_uniq_start) ||
     ($start > $new_uniq_end   &&  $end > $new_uniq_end  )) {      ($start > $new_uniq_end   &&  $end > $new_uniq_end  )) {
Line 195  sub check_for_conflict { Line 238  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'};
     foreach my $key (keys(%consumed)) {      foreach my $key (keys(%consumed)) {
  if ($consumed{$key}->{'name'} eq $me) {   if ($consumed{$key}->{'name'} eq $me) {
     my $num=(split('\0',$key))[1];      my $num=(split('\0',$key))[1];
Line 239  sub make_reservation { Line 285  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 255  sub make_reservation { Line 301  sub make_reservation {
  return undef;   return undef;
     }      }
           
     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 269  sub make_reservation { Line 315  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 282  sub make_reservation { Line 323  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') {
    return &remove_registration_user($r);
       }
       my $slot_name = $env{'form.slotname'};
       my %slot=&Apache::lonnet::get_slot($slot_name);
   
       my ($cnum,$cdom)=&get_course();
       my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
          "^$slot_name\0");
       if (&Apache::lonnet::error(%consumed)) {
    $r->print("<p><span class=\"LC_error\">".&mt('A network error has occurred.').'</span></p>');
    return;
       }
       if (!%consumed) {
    $r->print('<p>'.&mt('Slot [_1] has no reservations.',
       '<tt>'.$slot_name.'</tt>').'</p>');
    return;
       }
   
       my @names = map { $consumed{$_}{'name'} } (sort(keys(%consumed)));
       my $names = join(' ',@names);
   
       my $msg = &mt('Remove all of [_1] from slot [_2]?',$names,$slot_name);
       &remove_registration_confirmation($r,$msg,['entry','slotname','context']);
   }
   
   sub remove_registration_user {
       my ($r) = @_;
       
       my $slot_name = $env{'form.slotname'};
   
     my $name = &Apache::loncommon::plainname($env{'form.uname'},      my $name = &Apache::loncommon::plainname($env{'form.uname'},
      $env{'form.udom'});       $env{'form.udom'});
   
     my $title = &Apache::lonnet::gettitle($env{'form.symb'});      my $title = &Apache::lonnet::gettitle($env{'form.symb'});
   
       my $msg = &mt('Remove [_1] from slot [_2] for [_3]',
     $name,$slot_name,$title);
       
       &remove_registration_confirmation($r,$msg,['uname','udom','slotname',
          'entry','symb','context']);
   }
   
   sub remove_registration_confirmation {
       my ($r,$msg,$inputs) =@_;
   
     my $hidden_input;      my $hidden_input;
     foreach my $parm ('uname','udom','slotname','entry','symb') {      foreach my $parm (@{$inputs}) {
  $hidden_input .=   $hidden_input .=
     '<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',
           'no'  => 'No',
       );
     $r->print(<<"END_CONFIRM");      $r->print(<<"END_CONFIRM");
 <p> Remove $name from slot $env{'form.slotname'} for $title</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" />
     $hidden_input      $hidden_input
     <input type="submit" name="Yes" value="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" name="No" value="no" />      <input type="submit" value="$lt{'no'}" />
 </form>  </form>
 END_CONFIRM  END_CONFIRM
   
 }  }
   
   sub release_all_slot {
       my ($r,$mgr)=@_;
       
       my $slot_name = $env{'form.slotname'};
   
       my ($cnum,$cdom)=&get_course();
   
       my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
          "^$slot_name\0");
       
       $r->print('<p>'.&mt('Releasing reservations').'</p>');
   
       foreach my $entry (sort { $consumed{$a}{'name'} cmp 
     $consumed{$b}{'name'} } (keys(%consumed))) {
    my ($uname,$udom) = split(':',$consumed{$entry}{'name'});
    my ($result,$msg) =
       &release_reservation($slot_name,$uname,$udom,
    $consumed{$entry}{'symb'},$mgr);
           if (!$result) {
               $r->print('<p><span class="LC_error">'.&mt($msg).'</span></p>');
           } else {
       $r->print("<p>$msg</p>");
           }
    $r->rflush();
       }
       $r->print('<p><a href="/adm/slotrequest?command=showslots">'.
         &mt('Return to slot list').'</a></p>');
       &return_link($r);
   }
   
 sub release_slot {  sub release_slot {
     my ($r,$symb,$slot_name,$inhibit_return_link,$mgr)=@_;      my ($r,$symb,$slot_name,$inhibit_return_link,$mgr)=@_;
   
     if ($slot_name eq '') { $slot_name=$env{'form.slotname'}; }      if ($slot_name eq '') { $slot_name=$env{'form.slotname'}; }
     my ($cnum,$cdom)=&get_course();  
   
     my ($uname,$udom) = ($env{'user.name'}, $env{'user.domain'});      my ($uname,$udom) = ($env{'user.name'}, $env{'user.domain'});
     if ($mgr eq 'F'       if ($mgr eq 'F' 
Line 324  sub release_slot { Line 466  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) =
    &release_reservation($slot_name,$uname,$udom,$symb,$mgr);
       if (!$result) {
           $r->print('<p><span class="LC_error">'.&mt($msg).'</span></p>');
       } else {
           $r->print("<p>$msg</p>");
       }
       
       if ($mgr eq 'F') {
    $r->print('<p><a href="/adm/slotrequest?command=showslots">'.
     &mt('Return to slot list').'</a></p>');
     }      }
   
       if (!$inhibit_return_link) { &return_link($r);  }
       return $result;
   }
   
   sub release_reservation {
       my ($slot_name,$uname,$udom,$symb,$mgr) = @_;
     my %slot=&Apache::lonnet::get_slot($slot_name);      my %slot=&Apache::lonnet::get_slot($slot_name);
     my $description=&get_description($env{'form.slotname'},\%slot);      my $description=&get_description($slot_name,\%slot);
   
     if ($mgr ne 'F') {      if ($mgr ne 'F') {
  if ($slot{'starttime'} < time) {   if ($slot{'starttime'} < time) {
     $r->print("<p>Not allowed to release Reservation: $description, as it has already ended.  </p>");      return (0,&mt('Not allowed to release Reservation: [_1], as it has already ended.',$description));
     &return_link($r);  
     return 0;  
  }   }
     }      }
   
       # 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 347  sub release_slot { Line 523  sub release_slot {
     }      }
     my $new_param = join(':',@new_slots);      my $new_param = join(':',@new_slots);
   
       my ($cnum,$cdom)=&get_course();
   
     # get slot reservations, check if user has one, if so remove reservation      # get slot reservations, check if user has one, if so remove reservation
     my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,      my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
        "^$slot_name\0");         "^$slot_name\0");
     foreach my $entry (keys(%consumed)) {      foreach my $entry (keys(%consumed)) {
  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);
     $r->print("<p>Released Reservation: $description</p>");      my $msg;
     if ($mgr eq 'F') {      if ($mgr eq 'F') {
  $r->print('<p><a href="/adm/slotrequest?command=showslots">'.   $msg = &mt('Released Reservation for user: [_1]',"$uname:$udom");
   &mt('Return to slot list').'</a></p>');      } else {
    $msg = '<span style="font-weight: bold;">'.&mt('Released reservation: [_1]',$description).'</span><br /><br />';
           my $person = &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'});
           my $subject = &mt('Reservation change: [_1]',$description);
           my $msgbody = &mt('Reservation released by [_1] for [_2].',$person,$description);
           $msg .= &slot_change_messaging($slot{'reservationmsg'},$subject,$msgbody,'release');
     }      }
     if (!$inhibit_return_link) { &return_link($r);  }      return (1,$msg);
     return 1;  
 }  }
   
 sub delete_slot {  sub delete_slot {
Line 388  sub delete_slot { Line 592  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 406  sub delete_slot { Line 610  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>");  
  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 class="LC_error">'.&mt('Reservation currently unchanged').'</p>');
     $r->print(<<STUFF);              if ($slot_name ne '') {
    <input type="submit" name="change" value="Change" />                  $r->print('<p>'.&mt('To complete the transaction you [_1]must confirm[_2] you want to [_3]process the change[_4] to [_5].'
 STUFF                           ,'<b>','</b>','<i>','</i>','<b>'.$description2.'</b>')
     $r->print(' your reservation from <b>'.$description1.'</b> to <b>'.                           .'<br />'
       $description2.                           .&mt('Or you can choose to [_1]make no change[_2] and continue[_2] with the reservation you already had: [_3].'
       '</b> <br />or </p>');                           ,'<i>','</i>','<b>'.$description1.'</b>')
     &return_link($r);                           .'</p><p><span class="LC_nobreak">'
                            .'<input type="submit" name="change" value="'.&mt('Process the change').'" />' 
                            .('&nbsp;'x3)
                            .'<input type="submit" name="nochange" value="'.&mt('Make no change').'" />'
                            .'</span></p>');
               }
     $r->print(<<STUFF);      $r->print(<<STUFF);
 </form>  </form>
 STUFF  STUFF
         } else {          } else {
               $r->print('<p>'.&mt('Already have a reservation: [_1].',$description1).'</p>');
     &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 style="font-weight: bold;">'.&mt('Successfully signed up:  [_1]',$description).'</p>');
       $retvalue = 1;
               my $person = &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'});
               my $subject = &mt('Reservation change: [_1]',$description);
               my $msgbody = &mt('Successful reservation by [_1] for [_2].',$person,$description);
               my $msg = &slot_change_messaging($slot{'reservationmsg'},$subject,$msgbody,'reserve');
               if ($msg) {
                   $r->print($msg);
               }
  } 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 {
     my ($slot_name,$slot,$symb,$slots)=@_;      my ($slot_name,$slot,$symb,$slots,$consumed_uniqueperiods)=@_;
   
     #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");
   
     #already ended      #already ended
     if ($slot->{'endtime'} < time) {      if ($slot->{'endtime'} < time) {
  return 0;   return 0;
     }      }
     &Apache::lonxml::debug("$slot_name endtime good");      &Apache::lonxml::debug("$slot_name endtime good");
   
     # not allowed to pick this one      # not allowed to pick this one
     if (defined($slot->{'type'})      if (defined($slot->{'type'})
  && $slot->{'type'} ne 'schedulable_student') {   && $slot->{'type'} ne 'schedulable_student') {
  return 0;   return 0;
     }      }
     &Apache::lonxml::debug("$slot_name type good");      &Apache::lonxml::debug("$slot_name type good");
   
       # reserve time not yet started
       if ($slot->{'startreserve'} > time) {
    return 0;
       }
       # reserve time ended
       if (($slot->{'endreserve'}) &&
           ($slot->{'endreserve'} < time)) {
           return 0;
       }    
       &Apache::lonxml::debug("$slot_name reserve good");
   
       my $userallowed=0;
       # its for a different set of users
       if (defined($slot->{'allowedsections'})) {
    if (!defined($env{'request.role.sec'})
       && grep(/^No section assigned$/,
       split(',',$slot->{'allowedsections'}))) {
       $userallowed=1;
    }
    if (defined($env{'request.role.sec'})
       && grep(/^\Q$env{'request.role.sec'}\E$/,
       split(',',$slot->{'allowedsections'}))) {
       $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");
   
       # its for a different set of users
       if (defined($slot->{'allowedusers'})
    && grep(/^\Q$env{'user.name'}:$env{'user.domain'}\E$/,
    split(',',$slot->{'allowedusers'}))) {
    $userallowed=1;
       }
   
       if (!defined($slot->{'allowedusers'})
    && !defined($slot->{'allowedsections'})) {
    $userallowed=1;
       }
   
       &Apache::lonxml::debug("$slot_name user is $userallowed");
       return 0 if (!$userallowed);
   
     # not allowed for this resource      # not allowed for this resource
     if (defined($slot->{'symb'})      if (defined($slot->{'symb'})
  && $slot->{'symb'} ne $symb) {   && $slot->{'symb'} ne $symb) {
  return 0;   return 0;
     }      }
     my $conflict = &check_for_conflict($symb,$slot_name,$slot,$slots);  
     if ($conflict) {      my $conflict = &check_for_conflict($symb,$slot_name,$slot,$slots,
          $consumed_uniqueperiods);
       if ($conflict =~ /^error: /) {
           return 0;
       } elsif ($conflict ne '') {
  if ($slots->{$conflict}{'starttime'} < time) {   if ($slots->{$conflict}{'starttime'} < time) {
     return 0;      return 0;
  }   }
Line 542  sub get_description { Line 839  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::get_course_slots($cnum,$cdom);
     my $available;      my $consumed_uniqueperiods = &get_consumed_uniqueperiods(\%slots);
     $r->print('<table border="1">');      if (ref($consumed_uniqueperiods) eq 'HASH') {
           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)))  {
   
  &Apache::lonxml::debug("Checking Slot $slot");   &Apache::lonxml::debug("Checking Slot $slot");
  next if (!&allowed_slot($slot,$slots{$slot},undef,\%slots));   next if (!&allowed_slot($slot,$slots{$slot},$symb,\%slots,
    $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('<p class="LC_info">'.$output.'</p>');
           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,
  if ($conflict) {     $consumed_uniqueperiods);
     $text=&mt('Change Reservation');                  if ($conflict) {
     $command='get';                      if ($conflict =~ /^error: /) {
  }                          $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 {
     my ($slot,$when,$deleted) = @_;      my ($slotname,$slot,$when,$deleted,$name) = @_;
     my $time=time;      my $time=time;
     my $week=60*60*24*7;      my $week=60*60*24*7;
   
     if ($deleted eq 'hide' && $slot->{'type'} eq 'deleted') {      if ($deleted eq 'hide' && $slot->{'type'} eq 'deleted') {
  return 0;   return 0;
     }      }
   
       if ($name && $name->{'value'} =~ /\w/) {
    if ($name->{'type'} eq 'substring') {
       if ($slotname !~ /\Q$name->{'value'}\E/) {
    return 0;
       }
    }
    if ($name->{'type'} eq 'exact') {
       if ($slotname eq $name->{'value'}) {
    return 0;
       }
    }
       }
   
     if ($when eq 'any') {      if ($when eq 'any') {
  return 1;   return 1;
     } elsif ($when eq 'now') {      } elsif ($when eq 'now') {
Line 653  sub to_show { Line 1025  sub to_show {
 sub remove_link {  sub remove_link {
     my ($slotname,$entry,$uname,$udom,$symb) = @_;      my ($slotname,$entry,$uname,$udom,$symb) = @_;
   
     $slotname  = &Apache::lonnet::escape($slotname);      my $remove = &mt('Remove');
     $entry     = &Apache::lonnet::escape($entry);  
     $uname     = &Apache::lonnet::escape($uname);      if ($entry eq 'remove all') {
     $udom      = &Apache::lonnet::escape($udom);   $remove = &mt('Remove All');
     $symb      = &Apache::lonnet::escape($symb);   undef($uname);
    undef($udom);
       }
   
     my $remove= &mt('Remove');      $slotname  = &escape($slotname);
       $entry     = &escape($entry);
       $uname     = &escape($uname);
       $udom      = &escape($udom);
       $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 672  sub show_table { Line 1050  sub show_table {
     my ($r,$mgr)=@_;      my ($r,$mgr)=@_;
   
     my ($cnum,$cdom)=&get_course();      my ($cnum,$cdom)=&get_course();
       my $crstype=&Apache::loncommon::course_type($cdom.'_'.$cnum);
     my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum);      my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum);
     if ( (keys(%slots))[0] =~ /^error: 2 /) {      if ( (keys(%slots))[0] =~ /^error: 2 /) {
  undef(%slots);   undef(%slots);
     }       } 
     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)) {
           if ($crstype eq 'Community') {
               $r->print('<div>'.&mt('No slots have been created in this community.').'</div>');
           } else {
               $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',
        'order'   => 'scalar',         'order'             => 'scalar',
        'deleted' => 'scalar',         'deleted'           => 'scalar',
          'name_filter_type'  => 'scalar',
          'name_filter_value' => 'scalar',
        );         );
     &Apache::loncommon::store_course_settings('slotrequest',\%Saveable_Parameters);      &Apache::loncommon::store_course_settings('slotrequest',
     &Apache::loncommon::restore_course_settings('slotrequest',\%Saveable_Parameters);        \%Saveable_Parameters);
       &Apache::loncommon::restore_course_settings('slotrequest',
    \%Saveable_Parameters);
       &Apache::grades::init_perm();
       my ($classlist,$section,$fullname)=&Apache::grades::getclasslist('all');
       &Apache::grades::reset_perm();
   
       # what to display filtering
     my %show_fields=&Apache::lonlocal::texthash(      my %show_fields=&Apache::lonlocal::texthash(
      'name'         => 'Slot Name',       'name'            => 'Slot Name',
      'description'  => 'Description',       'description'     => 'Description',
      'type'         => 'Type',       'type'            => 'Type',
      'starttime'    => 'Start time',       'starttime'       => 'Start time',
      'endtime'      => 'End Time',       'endtime'         => 'End Time',
              'startreserve' => 'Time students can start reserving',               'startreserve'    => 'Time students can start reserving',
      'secret'       => 'Secret Word',               'endreserve'      => 'Time students can no longer reserve',
      'maxspace'     => 'Maximum # of students',               'reservationmsg'  => 'Message triggered by reservation',
      'ip'           => 'IP or DNS restrictions',       'secret'          => 'Secret Word',
      'symb'         => 'Resource slot is restricted to.',       'space'           => '# of students/max',
      'uniqueperiod' => 'Period of time slot is unique',       'ip'              => 'IP or DNS restrictions',
      'proctor'      => 'List of proctors');       'symb'            => 'Resource slot is restricted to.',
        'allowedsections' => 'Sections slot is restricted to.',
        'allowedusers'    => 'Users slot is restricted to.',
        'uniqueperiod'    => 'Period of time slot is unique',
        'scheduled'       => 'Scheduled Students',
        'proctor'         => 'List of proctors');
       if ($crstype eq 'Community') {
           $show_fields{'startreserve'} = &mt('Time members can start reserving');
           $show_fields{'endreserve'} = &mt('Time members can no longer reserve');
           $show_fields{'scheduled'} = &mt('Scheduled Members');
       }
     my @show_order=('name','description','type','starttime','endtime',      my @show_order=('name','description','type','starttime','endtime',
        'startreserve','secret','maxspace','ip','symb',      'startreserve','endreserve','reservationmsg','secret','space',
        'uniqueperiod','proctor');      'ip','symb','allowedsections','allowedusers','uniqueperiod',
       'scheduled','proctor');
     my @show =       my @show = 
  (exists($env{'form.show'})) ? &Apache::loncommon::get_env_multiple('form.show')   (exists($env{'form.show'})) ? &Apache::loncommon::get_env_multiple('form.show')
                             : keys(%show_fields);                              : keys(%show_fields);
     my %show =  map { $_ => 1 } (@show);      my %show =  map { $_ => 1 } (@show);
   
       #when filtering setup
     my %when_fields=&Apache::lonlocal::texthash(      my %when_fields=&Apache::lonlocal::texthash(
      'now'      => 'Open now',       'now'      => 'Open now',
      'nextweek' => 'Open within the next week',       'nextweek' => 'Open within the next week',
Line 731  sub show_table { Line 1144  sub show_table {
     my $when = (exists($env{'form.when'})) ? $env{'form.when'}      my $when = (exists($env{'form.when'})) ? $env{'form.when'}
                                             : 'now';                                              : 'now';
   
       #display of students setup
       my %stu_display_fields=
    &Apache::lonlocal::texthash('username' => 'User name',
       'fullname' => 'Full name',
       );
       my @stu_display_order=('fullname','username');
       my @stu_display = 
    (exists($env{'form.studisplay'})) ? &Apache::loncommon::get_env_multiple('form.studisplay')
                                     : keys(%stu_display_fields);
       my %stu_display =  map { $_ => 1 } (@stu_display);
   
       #name filtering setup
       my %name_filter_type_fields=
    &Apache::lonlocal::texthash('substring' => 'Substring',
       'exact'     => 'Exact',
       #'reg'       => 'Regular Expression',
       );
       my @name_filter_type_order=('substring','exact');
   
       $name_filter_type_fields{'select_form_order'} = \@name_filter_type_order;
       my $name_filter_type = 
    (exists($env{'form.name_filter_type'})) ? $env{'form.name_filter_type'}
                                                   : 'substring';
       my $name_filter = {'type'  => $name_filter_type,
          'value' => $env{'form.name_filter_value'},};
   
       
       #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">
       <tr><th>'.&mt('Show').'</th>        <tr><th>'.&mt('Show').'</th>
             <th>'.&mt('Student Display').'</th>
           <th>'.&mt('Open').'</th>            <th>'.&mt('Open').'</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>'.&Apache::loncommon::select_form($when,'when',%when_fields).             <td valign="top">
            '.&Apache::loncommon::multiple_select_form('studisplay',\@stu_display,
       6,\%stu_display_fields,
       \@stu_display_order).'
              </td>
              <td valign="top">'.&Apache::loncommon::select_form($when,'when',\%when_fields).
             '</td>
              <td valign="top">'.&Apache::loncommon::select_form($name_filter_type,
    'name_filter_type',
    \%name_filter_type_fields).
         '<br />'.
         &Apache::lonhtmlcommon::textbox('name_filter_value',
         $env{'form.name_filter_value'},
         15).
           '</td>            '</td>
            <td>             <td valign="top">
             <table>              <table>
               <tr>                <tr>
                 <td rowspan="2">Deleted slots:</td>                  <td rowspan="2">Deleted slots:</td>
Line 764  sub show_table { Line 1222  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('<th>Scheduled Students</th></tr>');      $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)$/) {   if ($env{'form.order'}=~/^(type|description|endtime|startreserve|endreserve|ip|symb|allowedsections|allowedusers|reservationmsg)$/) {
     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 801  sub show_table { Line 1263  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); }
       }
   
       my %msgops = &slot_reservationmsg_options();
   
     foreach my $slot (sort $slotsort (keys(%slots)))  {      foreach my $slot (sort $slotsort (keys(%slots)))  {
  if (!&to_show($slots{$slot},$when,$env{'form.deleted'})) { next; }   if (!&to_show($slot,$slots{$slot},$when,
         $env{'form.deleted'},$name_filter)) { next; }
           my $reservemsg;
  if (defined($slots{$slot}->{'type'})   if (defined($slots{$slot}->{'type'})
     && $slots{$slot}->{'type'} ne 'schedulable_student') {      && $slots{$slot}->{'type'} eq 'schedulable_student') {
     #next;      $reservemsg = $msgops{$slots{$slot}->{'reservationmsg'}};
  }   }
  my $description=&get_description($slot,$slots{$slot});   my $description=&get_description($slot,$slots{$slot});
  my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,   my ($id_count,$ids);
    "^$slot\0");      
  my $ids;   if (exists($show{'scheduled'}) || exists($show{'space'}) ) {
       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);
     foreach my $entry (sort(keys(%consumed))) {      if (exists($show{'scheduled'})) {
  my (undef,$id)=split("\0",$entry);   foreach my $entry (sort { $consumed{$a}{name} cmp 
  my ($uname,$udom) = split('@',$consumed{$entry}{'name'});        $consumed{$b}{name} }
  my $name = &Apache::loncommon::plainname($uname,$udom);     (@this_slot)) {
  $ids.= '<nobr>'.$name.&remove_link($slot,$entry,$uname,$udom,      my (undef,$id)=split("\0",$entry);
    $consumed{$entry}{'symb'})      my ($uname,$udom) = split(':',$consumed{$entry}{'name'});
     .'</nobr><br />';      $ids.= '<span class="LC_nobreak">';
       foreach my $item (@stu_display_order) {
    if ($stu_display{$item}) {
       if ($item eq 'fullname') {
    $ids.=$fullname->{"$uname:$udom"}.' ';
       } elsif ($item eq 'username') {
    $ids.="<tt>$uname:$udom</tt> ";
       }
    }
       }
       $ids.=&remove_link($slot,$entry,$uname,$udom,
          $consumed{$entry}{'symb'}).'</span><br />';
    }
     }      }
  }   }
   
Line 830  sub show_table { Line 1316  sub show_table {
  &Apache::lonlocal::locallocaltime($slots{$slot}->{'endtime'}):'');   &Apache::lonlocal::locallocaltime($slots{$slot}->{'endtime'}):'');
  my $start_reserve=($slots{$slot}->{'startreserve'}?   my $start_reserve=($slots{$slot}->{'startreserve'}?
    &Apache::lonlocal::locallocaltime($slots{$slot}->{'startreserve'}):'');     &Apache::lonlocal::locallocaltime($slots{$slot}->{'startreserve'}):'');
           my $end_reserve=($slots{$slot}->{'endreserve'}?
                            &Apache::lonlocal::locallocaltime($slots{$slot}->{'endreserve'}):'');
   
  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 846  sub show_table { Line 1334  sub show_table {
     $title='<a href="'.$res.'?symb='.$slots{$slot}{'symb'}.'">'.$title.'</a>';      $title='<a href="'.$res.'?symb='.$slots{$slot}{'symb'}.'">'.$title.'</a>';
  }   }
   
    my $allowedsections;
    if (exists($show{'allowedsections'})) {
       $allowedsections = 
    join(', ',sort(split(/\s*,\s*/,
        $slots{$slot}->{'allowedsections'})));
    }
   
    my @allowedusers;
    if (exists($show{'allowedusers'})) {
       @allowedusers= map {
    my ($uname,$udom)=split(/:/,$_);
    my $fullname=$name_cache{$_};
    if (!defined($fullname)) {
       $fullname = &Apache::loncommon::plainname($uname,$udom);
       $fullname =~s/\s/&nbsp;/g;
       $name_cache{$_} = $fullname;
    }
    &Apache::loncommon::aboutmewrapper($fullname,$uname,$udom);
       } (sort(split(/\s*,\s*/,$slots{$slot}->{'allowedusers'})));
    }
    my $allowedusers=join(', ',@allowedusers);
   
  my @proctors;   my @proctors;
  my $rowspan=1;   my $rowspan=1;
  my $colspan=1;   my $colspan=1;
  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)) {
     &Apache::lonnet::logthis("Gettign $uname $udom");  
     $fullname = &Apache::loncommon::plainname($uname,$udom);      $fullname = &Apache::loncommon::plainname($uname,$udom);
     $fullname =~s/\s/&nbsp;/g;      $fullname =~s/\s/&nbsp;/g;
     $name_cache{$_} = $fullname;      $name_cache{$_} = $fullname;
Line 865  sub show_table { Line 1374  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
         if ($ids ne '') { undef($delete); }  
   
         $r->print("<tr>\n<td rowspan=\"$rowspan\">$edit $delete</td>\n");          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 />';
   
           if ($ids eq '') {
               undef($remove_all);
           } else {
               undef($delete);
           }
    if ($slots{$slot}{'type'} ne 'schedulable_student') {
               undef($showlog); 
       undef($remove_all);
    }
   
    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 893  DELETELINK Line 1425  DELETELINK
  if (exists($show{'startreserve'})) {   if (exists($show{'startreserve'})) {
     $colspan++;$r->print("<td>$start_reserve</td>\n");      $colspan++;$r->print("<td>$start_reserve</td>\n");
  }   }
           if (exists($show{'endreserve'})) {
               $colspan++;$r->print("<td>$end_reserve</td>\n");
           }
           if (exists($show{'reservationmsg'})) {
               $colspan++;$r->print("<td>$reservemsg</td>\n");
           }
  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 905  DELETELINK Line 1450  DELETELINK
  if (exists($show{'symb'})) {   if (exists($show{'symb'})) {
     $colspan++;$r->print("<td>$title</td>\n");      $colspan++;$r->print("<td>$title</td>\n");
  }   }
    if (exists($show{'allowedsections'})) {
       $colspan++;$r->print("<td>$allowedsections</td>\n");
    }
    if (exists($show{'allowedusers'})) {
       $colspan++;$r->print("<td>$allowedusers</td>\n");
    }
  if (exists($show{'uniqueperiod'})) {   if (exists($show{'uniqueperiod'})) {
     $colspan++;$r->print("<td>$unique</td>\n");      $colspan++;$r->print("<td>$unique</td>\n");
  }   }
  $colspan++;$r->print("<td>$ids</td>\n</tr>\n");   if (exists($show{'scheduled'})) {
       $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,$crstype) = @_;
       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>'
       );
       if (!defined($navmap)) {
           $r->print('<div class="LC_error">');
           if ($crstype eq 'Community') {
               $r->print(&mt('Unable to retrieve information about community contents'));
           } else {
               $r->print(&mt('Unable to retrieve information about course contents'));
           }
           $r->print('</div>');
           &Apache::lonnet::logthis('Manage Reservations - could not create navmap object in '.lc($crstype).':'.$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");
       my $slotheader = '<p>'.
                    &mt('Your reservation status for any such assignments is listed below:').
                    '</p>'.
                    '<table class="LC_data_table LC_tableOfContent">'."\n";
       my $shownheader = 0;
       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->RESERVABLE_LATER) {
                       $msg=&mt('Reservation needed: will be reservable later.');
                   } 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];
                           if (!$shownheader) {
                               $r->print($slotheader);
                               $shownheader = 1;
                           }
                           $r->print('<tr class="'.$bgcolor.'">'.$item.'</tr>'."\n");
                       }
                   }
                   $rownum ++;
                   my $bgcolor = $backgrounds[$rownum % $numcolors];
                   if (!$shownheader) {
                       $r->print($slotheader);
                       $shownheader = 1;
                   }
                   $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 ($shownheader) {
           $r->print('</table>');
       }
       if (!$reservable) {
           $r->print('<span class="LC_info">');
           if ($crstype eq 'Community') {
               $r->print(&mt('No community items currently require a reservation to gain access.'));
           } else {
               $r->print(&mt('No course items currently require a reservation to gain access.'));
           }
           $r->print('</span>');
       }
       $r->print('<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" alt="" />&nbsp;'."\n";
       } else {
           $output .= '<img src="/adm/lonIcons/navmap.folder.open.gif" alt="" />&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 $crstype = &Apache::loncommon::course_type();
       my %log=&Apache::lonnet::dump('nohist_'.$cdom.'_'.$cnum.'_slotlog',$udom,$uname);
       if ($env{'form.origin'} eq 'aboutme') {
           $r->print('<div class="LC_fontsize_large">');
           my $name = &Apache::loncommon::plainname($env{'form.uname'},$env{'form.udom'},
                                                       'firstname');
           if ($crstype eq 'Community') {
               $r->print(&mt('History of member-reservable slots for: [_1]',
                             $name));
           } else {
               $r->print(&mt('History of student-reservable slots for: [_1]',
                             $name));
   
           }
           $r->print('</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($crstype);
       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;
       my $crstype = &Apache::loncommon::course_type();
       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">');
               if ($crstype eq 'Community') {
                   $r->print(&mt('Reservation history unavailable for non-member-reservable slot: [_1].',$description));
               } else {
                   $r->print(&mt('Reservation history unavailable for non-student-reservable slot: [_1].',$description));
               }
               $r->print('</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">');
       if ($crstype eq 'Community') {
           $r->print(&mt('Reservation changes for member-reservable slot: [_1]',$description));
       } else {
           $r->print(&mt('Reservation changes for student-reservable slot: [_1]',$description));
       }
       $r->print('</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($crstype);
       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 ($crstype) = @_;
       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', 
                                            );
       if ($crstype eq 'Community') {
           $lt{'user'} = &mt('By member');
           $lt{'usermanage'} = $lt{'user'};
       }
       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 $crstype = &Apache::loncommon::course_type();
       my %lt = &reservationlog_contexts($crstype);
       $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>'.
                  '<p class="LC_info">'.
                  &mt('Only changes made from servers running LON-CAPA [_1] or later are displayed.'
                     ,'2.9.0');
       if ($version) {
           $output .= ' '.&mt('This LON-CAPA server is version [_1]',$version);
       }
       $output .= '</p><hr /><br />';
       return $output;
   }
   
   sub slot_change_messaging {
       my ($setting,$subject,$msg,$action) = @_;
       my $user = $env{'user.name'};
       my $domain = $env{'user.domain'};
       my ($message_status,$comment_status);
       if ($setting eq 'only_student'
           || $setting eq 'student_and_user_notes_screen') {
           $message_status =
               &Apache::lonmsg::user_normal_msg($user,$domain,$subject,$msg);
           $message_status = '<li>'.&mt('Sent to you: [_1]',
                                       $message_status).' </li>';
       }
       if ($setting eq 'student_and_user_notes_screen') {
           $comment_status =
               &Apache::lonmsg::store_instructor_comment($subject.'<br />'.
                                                         $msg,$user,$domain);
           $comment_status = '<li>'.&mt('Entry added to course record (viewable by instructor): [_1]',
                                       $comment_status).'</li>';
       }
       if ($message_status || $comment_status) {
           my $msgtitle;
           if ($action eq 'reserve') {
               $msgtitle = &mt('Status of messages about saved reservation');
           } elsif ($action eq 'release') {
               $msgtitle = &mt('Status of messages about dropped reservation');
           } elsif ($action eq 'nochange') {
               $msgtitle = &mt('Status of messages about unchanged existing reservation');
           }
           return '<span class="LC_info">'.$msgtitle.'</span>'
                  .'<ul>'
                  .$message_status
                  .$comment_status
                  .'</ul><hr />';
       }
 }  }
   
 sub upload_start {  sub upload_start {
     my ($r)=@_;          my ($r)=@_;    
     $r->print(&Apache::grades::checkforfile_js());      $r->print(
     my $result.='<table width=100% border=0><tr bgcolor="#e6ffff"><td>'."\n";          &Apache::grades::checkforfile_js()
     $result.='&nbsp;<b>'.         .'<h3>'.&mt('Specify a file containing the slot definitions.').'</h3>'
  &mt('Specify a file containing the slot definitions.').         .'<form method="post" enctype="multipart/form-data"'
  '</b></td></tr>'."\n";         .' action="/adm/slotrequest" name="slotupload">'
     $result.='<tr bgcolor=#ffffe6><td>'."\n";         .'<input type="hidden" name="command" value="csvuploadmap" />'
     my $upfile_select=&Apache::loncommon::upfile_select_html();         .&Apache::lonhtmlcommon::start_pick_box()
     my $ignore=&mt('Ignore First Line');         .&Apache::lonhtmlcommon::row_title(&mt('File'))
     $result.=<<ENDUPFORM;         .&Apache::loncommon::upfile_select_html()
 <form method="post" enctype="multipart/form-data" action="/adm/slotrequest" name="slotupload">         .&Apache::lonhtmlcommon::row_closure()
 <input type="hidden" name="command" value="csvuploadmap" />         .&Apache::lonhtmlcommon::row_title(
 $upfile_select              '<label for="noFirstLine">'
 <br /><input type="button" onClick="javascript:checkUpload(this.form);" value="Upload Data" />             .&mt('Ignore First Line')
 <label><input type="checkbox" name="noFirstLine" />$ignore</label>             .'</label>')
 </form>         .'<input type="checkbox" name="noFirstLine" id="noFirstLine" />'
 ENDUPFORM         .&Apache::lonhtmlcommon::row_closure(1)
     $result.='</td></tr></table>'."\n";         .&Apache::lonhtmlcommon::end_pick_box()
     $result.='</td></tr></table>'."\n";         .'<p>'
     $r->print($result);         .'<input type="button" onclick="javascript:checkUpload(this.form);"'
          .' value="'.&mt('Next').'" />'
          .'</p>'
         .'</form>'
       );
 }  }
   
 sub csvuploadmap_header {  sub csvuploadmap_header {
Line 954  sub csvuploadmap_header { Line 2233  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 />
 <input type="button" value="Reverse Association" onClick="javascript:this.form.associate.value='Reverse Association';submit(this.form);" />  <input type="button" value="Reverse Association" onclick="javascript:this.form.associate.value='Reverse Association';submit(this.form);" />
 <label><input type="checkbox" name="noFirstLine" $checked />$ignore</label>  <label><input type="checkbox" name="noFirstLine"$checked />$ignore</label>
 <input type="hidden" name="associate"  value="" />  <input type="hidden" name="associate"  value="" />
 <input type="hidden" name="datatoken"  value="$datatoken" />  <input type="hidden" name="datatoken"  value="$datatoken" />
 <input type="hidden" name="fileupload" value="$env{'form.fileupload'}" />  <input type="hidden" name="fileupload" value="$env{'form.fileupload'}" />
Line 980  ENDPICK Line 2261  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 1083  sub csvupload_fields { Line 2365  sub csvupload_fields {
     ['starttime','Start Time of slot'],      ['starttime','Start Time of slot'],
     ['endtime','End Time of slot'],      ['endtime','End Time of slot'],
     ['startreserve','Reservation Start Time'],      ['startreserve','Reservation Start Time'],
               ['endreserve','Reservation End Time'],
               ['reservationmsg','Message when reservation changed'],
     ['ip','IP or DNS restriction'],      ['ip','IP or DNS restriction'],
     ['proctor','List of proctor ids'],      ['proctor','List of proctor ids'],
     ['description','Slot Description'],      ['description','Slot Description'],
     ['maxspace','Maximum number of reservations'],      ['maxspace','Maximum number of reservations'],
     ['symb','Resource Restriction'],      ['symb','Resource Restriction'],
     ['uniqueperiod','Date range of slot exclusion'],      ['uniqueperiod','Date range of slot exclusion'],
     ['secret','Secret word proctor uses to validate']);      ['secret','Secret word proctor uses to validate'],
       ['allowedsections','Sections slot is restricted to'],
       ['allowedusers','Users slot is restricted to'],
       );
 }  }
   
 sub csv_upload_assign {  sub csv_upload_assign {
Line 1098  sub csv_upload_assign { Line 2385  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 1136  sub csv_upload_assign { Line 2423  sub csv_upload_assign {
  if ($entries{$fields{'endtime'}}) {   if ($entries{$fields{'endtime'}}) {
     $slot{'endtime'}=&UnixDate($entries{$fields{'endtime'}},"%s");      $slot{'endtime'}=&UnixDate($entries{$fields{'endtime'}},"%s");
  }   }
   
    # start/endtime must be defined and greater than zero
    if (!$slot{'starttime'}) {
       push(@errors,"$name not created -- Invalid start time");
       next;
    }
    if (!$slot{'endtime'}) {
       push(@errors,"$name not created -- Invalid end time");
       next;
    }
    if ($slot{'starttime'} > $slot{'endtime'}) {
       push(@errors,"$name not created -- Slot starts after it ends");
       next;
    }
   
  if ($entries{$fields{'startreserve'}}) {   if ($entries{$fields{'startreserve'}}) {
     $slot{'startreserve'}=      $slot{'startreserve'}=
  &UnixDate($entries{$fields{'startreserve'}},"%s");   &UnixDate($entries{$fields{'startreserve'}},"%s");
  }   }
    if (defined($slot{'startreserve'})
       && $slot{'startreserve'} > $slot{'starttime'}) {
       push(@errors,"$name not created -- Slot's reservation start time is after the slot's start time.");
       next;
    }
   
           if ($entries{$fields{'endreserve'}}) {
               $slot{'endreserve'}=
                   &UnixDate($entries{$fields{'endreserve'}},"%s");
           }
           if (defined($slot{'endreserve'})
               && $slot{'endreserve'} > $slot{'starttime'}) {
               push(@errors,"$name not created -- Slot's reservation end time is after the slot's start time.");
               next;
           }
   
           if ($slot{'type'} eq 'schedulable_student') {
               if ($entries{$fields{'reservationmsg'}}) {
                    if (($entries{$fields{'reservationmsg'}} eq 'only_student') ||
                        ($entries{$fields{'reservationmsg'}} eq 'student_and_user_notes_screen')) {
                         $slot{'reservationmsg'}=$entries{$fields{'reservationmsg'}};
                    } else {
                         unless (($entries{$fields{'reservationmsg'}} eq 'none') ||
                                 ($entries{$fields{'reservationmsg'}} eq '')) {
                             push(@errors,"$name -- Slot's reservationmsg setting ignored - not one of: 'only_student', 'student_and_user_notes_screen', 'none' or ''");
                         }
                    }
               }
           }
   
  foreach my $key ('ip','proctor','description','maxspace',   foreach my $key ('ip','proctor','description','maxspace',
  'secret','symb') {   'secret','symb') {
     if ($entries{$fields{$key}}) {      if ($entries{$fields{$key}}) {
  $slot{$key}=$entries{$fields{$key}};   $slot{$key}=$entries{$fields{$key}};
     }      }
  }   }
   
  if ($entries{$fields{'uniqueperiod'}}) {   if ($entries{$fields{'uniqueperiod'}}) {
     my ($start,$end)=split(',',$entries{$fields{'uniqueperiod'}});      my ($start,$end)=split(',',$entries{$fields{'uniqueperiod'}});
     my @times=(&UnixDate($start,"%s"),      my @times=(&UnixDate($start,"%s"),
        &UnixDate($end,"%s"));         &UnixDate($end,"%s"));
     $slot{'uniqueperiod'}=\@times;      $slot{'uniqueperiod'}=\@times;
  }   }
    if (defined($slot{'uniqueperiod'})
       && $slot{'uniqueperiod'}[0] > $slot{'uniqueperiod'}[1]) {
       push(@errors,"$name not created -- Slot's unique period start time is later than the unique period's end time.");
       next;
    }
   
  &Apache::lonnet::cput('slots',{$name=>\%slot},$cdom,$cname);   &Apache::lonnet::cput('slots',{$name=>\%slot},$cdom,$cname);
  $r->print('.');   $r->print('.');
  $r->rflush();   $r->rflush();
  $countdone++;   $countdone++;
     }      }
     $r->print("<p>Created $countdone slots\n</p>");      if ($countdone) {
           &Apache::lonnet::devalidate_slots_cache($cname,$cdom); 
       }
       $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 slot_reservationmsg_options {
       my %options = &Apache::lonlocal::texthash (
                           only_student  => 'Sent to student',
           student_and_user_notes_screen => 'Sent to student and added to user notes',
                                    none => 'None sent and no record in user notes',
       );
       return %options;
   }
   
 sub handler {  sub handler {
     my $r=shift;      my $r=shift;
   
Line 1177  sub handler { Line 2544  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'}}});
               }
           }
       } else {
           $brcrum =[];
     }      }
     &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);
     } elsif ($env{'form.command'} eq 'release' && $mgr eq 'F') {      } elsif ($env{'form.command'} eq 'release' && $mgr eq 'F') {
  &release_slot($r,undef,undef,undef,$mgr);   if ($env{'form.entry'} eq 'remove all') {
       &release_all_slot($r,$mgr);
    } else {
       &release_slot($r,undef,undef,undef,$mgr);
    }
     } elsif ($env{'form.command'} eq 'delete' && $mgr eq 'F') {      } elsif ($env{'form.command'} eq 'delete' && $mgr eq 'F') {
  &delete_slot($r);   &delete_slot($r);
     } elsif ($env{'form.command'} eq 'uploadstart' && $mgr eq 'F') {      } elsif ($env{'form.command'} eq 'uploadstart' && $mgr eq 'F') {
Line 1209  sub handler { Line 2630  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 1234  sub handler { Line 2663  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 ($env{'form.nochange'}) {
  &get_slot($r,$symb);                  my $slot_name = $env{'form.releaseslot'};
                   my @slots = &check_for_reservation($symb,'allslots');
                   my $msg;
                   if (($slot_name ne '') && (grep(/^\Q$slot_name\E/,@slots))) { 
                        my %slot=&Apache::lonnet::get_slot($env{'form.releaseslot'});
                        my $description=&get_description($slot_name,\%slot);
                        $msg = '<span style="font-weight: bold;">'.
                               &mt('Unchanged reservation: [_1]',$description).'</span><br /><br />';
                        my $person = 
                            &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'});
                        my $subject = &mt('Reservation unchanged: [_1]',$description);
                        my $msgbody = &mt('No change to existing registration by [_1] for [_2].',$person,$description);
                        $msg .= &slot_change_messaging($slot{'reservationmsg'},$subject,$msgbody,'nochange');
                   } else {
                       $msg = '<span class="LC_warning">'.&mt('Reservation no longer reported as available.').'</span>';
                   }
                   $r->print($msg);
                   &return_link($r);
       } elsif (&get_slot($r,$symb,$env{'form.releaseslot'},1)) {
    &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.45  
changed lines
  Added in v.1.113


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