Diff for /loncom/interface/slotrequest.pm between versions 1.69 and 1.146

version 1.69, 2006/10/17 15:11:26 version 1.146, 2023/07/08 16:57:47
Line 37  use Apache::lonnet; Line 37  use Apache::lonnet;
 use Apache::lonnavmaps();  use Apache::lonnavmaps();
 use Date::Manip;  use Date::Manip;
 use lib '/home/httpd/lib/perl/';  use lib '/home/httpd/lib/perl/';
 use LONCAPA;  use LONCAPA qw(:DEFAULT :match);
   
 sub fail {  sub fail {
     my ($r,$code)=@_;      my ($r,$code)=@_;
Line 56  sub fail { Line 56  sub fail {
 }  }
   
 sub start_page {  sub start_page {
     my ($r,$title)=@_;      my ($r,$title,$brcrum,$bread_crumbs_component,$js,$mgr)=@_;
     $r->print(&Apache::loncommon::start_page($title));      my $args;
       if (ref($brcrum) eq 'ARRAY') {
           $args = {bread_crumbs => $brcrum};
           if ($bread_crumbs_component) {    
               $args->{bread_crumbs_component} = $bread_crumbs_component;    
           }
       }
       if (($env{'form.requestattempt'}) || ($env{'form.command'} eq 'manageresv')) {
           my %loaditems = (
                              onload => 'javascript:uncheckSlotRadio();',
                           );
           if (ref($args) eq 'HASH') {
               $args->{'add_entries'} = \%loaditems;
           } else {
               $args = { 'add_entries' => \%loaditems };
           }
       }
       unless (($env{'form.context'} eq 'usermanage') || (($mgr eq 'F') &&
               (($env{'form.command'} eq 'release') ||
                ($env{'form.command'} eq 'remove_registration')))) {
           if ($env{'form.symb'}) {
               my $symb=&unescape($env{'form.symb'});
               my ($mapurl,$id,$resurl) = &Apache::lonnet::decode_symb($symb);
               if ($resurl =~ /ext\.tool$/) {
                   my $target;
                   my ($marker,$exttool) = (split(m{/},$resurl))[3,4];
                   $marker=~s/\D//g;
                   if (($marker) && ($exttool) && ($env{'request.course.id'})) {
                       my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                       my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                       my ($idx,$crstool,$is_tool,%toolhash,%toolsettings);
                       if ($resurl eq "adm/$cdom/$cnum/$marker/$exttool") {
                           my %toolsettings=&Apache::lonnet::dump('exttool_'.$marker,$cdom,$cnum);
                           $target = $toolsettings{'target'};
                       }
                   }
                   if ($target eq 'iframe') {
                       $args->{'only_body'} = 1;
                   }
               }
           }
       }
       $r->print(&Apache::loncommon::start_page($title,$js,$args));
 }  }
   
 sub end_page {  sub end_page {
Line 65  sub end_page { Line 107  sub end_page {
     $r->print(&Apache::loncommon::end_page());      $r->print(&Apache::loncommon::end_page());
 }  }
   
   sub reservation_js {
       my ($slots,$consumed_uniqueperiods,$available,$got_slots,$symb) = @_;
       return unless ((ref($slots) eq 'HASH') && (ref($available) eq 'ARRAY'));
       my $toskip;
       if ($symb eq '') {
           $toskip = { symb => 1, };
       }
       my ($i,$j) = (0,0);
       my $js;
       foreach my $slot (sort
           { return $slots->{$a}->{'starttime'} <=> $slots->{$b}->{'starttime'} }
                       (keys(%{$slots})))  {
   
           next if (!&allowed_slot($slot,$slots->{$slot},$symb,$slots,
                                   $consumed_uniqueperiods,$toskip));
           $js .= "    slotstart[$i]='$slots->{$slot}->{'starttime'}';\n".
                  "    slotend[$i]='$slots->{$slot}->{'endtime'}';\n".
                  "    slotname[$i]='$slot';\n";
           if (($symb) && (ref($got_slots) eq 'ARRAY')) {
               if (grep(/^\Q$slot\E$/,@{$got_slots})) {
                   $js .= "    currslot[$j]='$slot';\n";
                   $j++;
               }
           }
           $i++;
           push(@{$available},$slot);
       }
       if ($j) {
           $js = "    var currslot = new Array($j);\n\n$js";
       }
       my %alerts = &Apache::lonlocal::texthash (
                                                   none    => 'No reservable time slots found',
                                                   invalid => 'Invalid date format',
                                                );
       return <<"ENDSCRIPT";
   <script type="text/javascript">
   // <![CDATA[
   function updateSlotDisplay(form,num,slotpickradio) {
       var slotstart = new Array($i);
       var slotend = new Array($i);
       var slotname = new Array($i);
   $js
   
       if (slotpickradio == 'all') {
           for (var i=0; i<$i; i++) {
               if (document.getElementById('LC_slotrow_'+num+'_'+slotname[i])) {
                   document.getElementById('LC_slotrow_'+num+'_'+slotname[i]).style.display = '';
               }
               if (document.getElementById('LC_slotsearch_'+num)) {
                   document.getElementById('LC_slotsearch_'+num).style.display = 'block';
               }
           }
       } else {
           if (slotpickradio == 'show') {
               for (var i=0; i<$i; i++) {
                   if (document.getElementById('LC_slotrow_'+num+'_'+slotname[i])) {
                       document.getElementById('LC_slotrow_'+num+'_'+slotname[i]).style.display = 'none';
                   }
               }
               for (var j=0; j<$j; j++) {
                   if (document.getElementById('LC_slotrow_'+num+'_'+currslot[j])) {
                       document.getElementById('LC_slotrow_'+num+'_'+currslot[j]).style.display = '';
                   }
               }
               if (document.getElementById('LC_slotsearch_'+num)) {
                   document.getElementById('LC_slotsearch_'+num).style.display = 'block';
               }
           } else {
               var numberRegExp = /^[0-9]+\$/;
               var startm = form.start_month.options[form.start_month.selectedIndex].value;
               var startd = form.start_day.value;
               startd=startd.trim();
               var starty = form.start_year.value;
               starty=starty.trim();
               var endm = form.end_month.options[form.end_month.selectedIndex].value;
               var endd = form.end_day.value;
               endd=endd.trim();
               var endy = form.end_year.value;
               endy=endy.trim();
               if (numberRegExp.test(endd) && numberRegExp.test(endy) && numberRegExp.test(startd) && numberRegExp.test(starty)) {
                   var startdate = startm+"/"+startd+"/"+starty;
                   var starttime = new Date(startdate).getTime();
                   starttime = starttime/1000;
                   var starth = form.start_hour.options[form.start_hour.selectedIndex].value;
                   if (numberRegExp.test(starth)) {
                       starth = parseInt(starth);
                       if (starth > 0 && starth <= 23) {
                           starttime += 3600 * starth;
                       }
                   }
                   var enddate = endm+"/"+endd+"/"+endy;
                   var endtime = new Date(enddate).getTime();
                   endtime = endtime/1000;
                   var endh = form.end_hour.options[form.end_hour.selectedIndex].value;
                   if (numberRegExp.test(endh)) {
                       endh = parseInt(endh);
                       if (endh > 0 && endh <= 23) {
                           endtime += 3600 * endh;
                       }
                   }
   
                   var shown = 0;
                   for (var i=0; i<$i; i++) {
                       if ((slotstart[i] >= starttime) && (slotend[i] <= endtime)) {
                           if (document.getElementById('LC_slotrow_'+num+'_'+slotname[i])) {
                               document.getElementById('LC_slotrow_'+num+'_'+slotname[i]).style.display = '';
                               shown ++;
                           }
                       } else {
                           if (document.getElementById('LC_slotrow_'+num+'_'+slotname[i])) {
                               document.getElementById('LC_slotrow_'+num+'_'+slotname[i]).style.display = 'none';
                           }
                       }
                   }
                   if (document.getElementById('LC_slotsearch_'+num)) {
                       if (shown) {
                           document.getElementById('LC_slotsearch_'+num).style.display = 'block';
                       } else {
                           document.getElementById('LC_slotsearch_'+num).style.display = 'none';
                       }
                   }
                   if (shown == 0) {
                       alert('$alerts{"none"}');
                   }
               } else {
                   alert('$alerts{"invalid"}');
               }
           }
       }
       return;
   }
   
   function toggleSlotDisplay(form,num) {
       if (form.slotpick.length) {
           for (var i=0; i<form.slotpick.length; i++) {
               if (form.slotpick[i].checked) {
                   var val = form.slotpick[i].value;
                   if (document.getElementById('LC_slotfilter_'+num)) {
                       document.getElementById('LC_slotsearch_'+num).style.display = 'none';
                       if (val == 'filter') {
                           document.getElementById('LC_slotfilter_'+num).style.display = 'block';
                       } else {
                           document.getElementById('LC_slotfilter_'+num).style.display = 'none';
                           if (val == 'all') {
                               updateSlotDisplay(form,num,val);
                           } else {
                               updateSlotDisplay(form,num,val);
                           }
                       }
                   }
                   break;
               }
           }
       }
       return false;
   }
   
   if (!document.getElementsByClassName) {
       function getElementsByClassName(node, classname) {
           var a = [];
           var re = new RegExp('(^| )'+classname+'( |$)');
           var els = node.getElementsByTagName("*");
           for(var i=0,j=els.length; i<j; i++)
               if(re.test(els[i].className))a.push(els[i]);
           return a;
       }
   }
   
   function uncheckSlotRadio() {
       var slotpicks;
       if (document.getElementsByClassName) {
           slotpicks = document.getElementsByClassName('LC_slotpick_radio');
       } else {
           slotpicks = getElementsByClassName(document.body,'LC_slotpick_radio');
       }
       if (slotpicks.length) {
           for (var i=0; i<slotpicks.length; i++) {
               slotpicks[i].checked = false;  
           }
       }
   }
   
   function toggleSlotMap(maprownum,rownum) {
       if (document.getElementById('arrow'+maprownum)) {
           var img = document.getElementById('arrow'+maprownum);
           var rowdisplay;
           var celldisplay = '';
           if (img.src.indexOf('arrow.open.gif')!=-1) {
               img.src = '/adm/lonIcons/arrow.closed.gif';
               rowdisplay = 'none';
           }
           else {
               img.src = '/adm/lonIcons/arrow.open.gif';
               rowdisplay = 'table-row';
               celldisplay = 'none';
           }
           var resrows;
           var maptext;
           if (document.getElementsByClassName) {
               resrows = document.getElementsByClassName('LC_slotresrow_'+maprownum);
               maptext = document.getElementsByClassName('LC_slotmaptext_'+maprownum);
           } else {
               resrows = getElementsByClassName(document.body,'LC_slotresrow_'+maprownum);
               maptext = getElementsByClassName(document.body,'LC_slotmaptext_'+maprownum);
           }
           if (maptext.length) {
               for (var i=0; i<maptext.length; i++) {
                   maptext[i].style.display = celldisplay;
               }
           }
           if (resrows.length) {
              var mapbgidx = 0;
              var rowclasses = ['LC_even_row','LC_odd_row'];
              var mapbgClass = 'LC_even_row';
              var regExpBg = /LC_odd_row/i;
              if (rowdisplay == 'table-row') {
                   if (document.getElementById('LC_slotmaprow_'+rownum)) {
                       mapbgClass = document.getElementById('LC_slotmaprow_'+rownum).className;
                       if (regExpBg.test(mapbgClass)) {
                           mapbgidx = 1;
                       }
                   }
               }
               for (var i=0; i<resrows.length; i++) {
                   resrows[i].style.display = rowdisplay;
                   if (rowdisplay == 'table-row') {
                       mapbgidx ++;        
                       var bgcolnew = mapbgidx % 2;
                       var bgcolold = (mapbgidx+1) % 2;
                       var k = i+parseInt(rownum)+1; 
                       if (document.getElementById('LC_slotresrow_'+k)) {
                           document.getElementById('LC_slotresrow_'+k).className = document.getElementById('LC_slotresrow_'+k).className.replace(rowclasses[bgcolold],rowclasses[bgcolnew]);
                       }
                   }
               }
               if (document.getElementById('LC_slot_reservations')) {
                   var numrowsOdd = resrows.length % 2;
                   if (numrowsOdd) {
                       var lastbgClass = 'LC_even_row';
                       var idx = 0;
                       var lastresnum = parseInt(rownum) + resrows.length; 
                       if (rowdisplay == 'none') {
                           lastresnum = rownum;
                           if (document.getElementById('LC_slotmaprow_'+rownum)) {
                               lastbgClass = document.getElementById('LC_slotmaprow_'+rownum).className;
                           }
                       } else {
                           lastresnum = parseInt(rownum) + resrows.length;
                           if (document.getElementById('LC_slotresrow_'+lastresnum)) {
                               lastbgClass = document.getElementById('LC_slotresrow_'+lastresnum).className;
                           }
                       }
                       if (regExpBg.test(lastbgClass)) {
                           idx = 1;
                       }
                       var table = document.getElementById('LC_slot_reservations');
                       if ((table.rows.length) && (table.rows.length >= lastresnum)) {
                           for (var i=lastresnum; i<table.rows.length; i++) {
                               if (table.rows[i].style.display != 'none') {
                                   idx ++;
                                   var bgcolnew = idx % 2;
                                   var bgcolold = (idx+1) % 2;  
                                   j = i+1;
                                   if (document.getElementById('LC_slotmaprow_'+j)) {
                                       document.getElementById('LC_slotmaprow_'+j).className = rowclasses[bgcolnew];
                                   } else {
                                       if (document.getElementById('LC_slotresrow_'+j)) {
                                           document.getElementById('LC_slotresrow_'+j).className = document.getElementById('LC_slotresrow_'+j).className.replace(rowclasses[bgcolold],rowclasses[bgcolnew]);
                                       }
                                   }
                               }
                           }
                       }
                   }
               }
           }
       }
   }
   // ]]>
   </script>
   ENDSCRIPT
   
   }
   
   
 =pod  =pod
   
  slot_reservations db   slot_reservations db
Line 117  sub check_for_reservation { Line 444  sub check_for_reservation {
     my ($symb,$mode)=@_;      my ($symb,$mode)=@_;
     my $student = &Apache::lonnet::EXT("resource.0.availablestudent", $symb,      my $student = &Apache::lonnet::EXT("resource.0.availablestudent", $symb,
        $env{'user.domain'}, $env{'user.name'});         $env{'user.domain'}, $env{'user.name'});
   
     my $course = &Apache::lonnet::EXT("resource.0.available", $symb,      my $course = &Apache::lonnet::EXT("resource.0.available", $symb,
     $env{'user.domain'}, $env{'user.name'});      $env{'user.domain'}, $env{'user.name'});
     my @slots = (split(/:/,$student), split(/:/, $course));      my @slots = (split(/:/,$student), split(/:/, $course));
Line 133  sub check_for_reservation { Line 459  sub check_for_reservation {
  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 165  sub check_for_reservation { Line 489  sub check_for_reservation {
 sub get_consumed_uniqueperiods {  sub get_consumed_uniqueperiods {
     my ($slots) = @_;      my ($slots) = @_;
     my $navmap=Apache::lonnavmaps::navmap->new;      my $navmap=Apache::lonnavmaps::navmap->new;
       if (!defined($navmap)) {
           return 'error: Unable to determine current status';
       }
     my @problems = $navmap->retrieveResources(undef,      my @problems = $navmap->retrieveResources(undef,
       sub { $_[0]->is_problem() },1,0);        sub { $_[0]->is_problem() || $_[0]->is_tool() },1,0);
     my %used_slots;      my %used_slots;
     foreach my $problem (@problems) {      foreach my $problem (@problems) {
  my $symb = $problem->symb();   my $symb = $problem->symb();
Line 213  sub check_for_conflict { Line 540  sub check_for_conflict {
     if (!defined($new_slot->{'uniqueperiod'})) { return undef; }      if (!defined($new_slot->{'uniqueperiod'})) { return undef; }
   
     if (!ref($consumed_uniqueperiods)) {      if (!ref($consumed_uniqueperiods)) {
  $consumed_uniqueperiods = &get_consumed_uniqueperiods($slots);          if ($consumed_uniqueperiods =~ /^error: /) {
  if (&Apache::lonnet::error(%$consumed_uniqueperiods)) {              return $consumed_uniqueperiods;
     return 'error: Unable to determine current status';          } else {
  }      $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'}};      my ($new_uniq_start,$new_uniq_end) = @{$new_slot->{'uniqueperiod'}};
     foreach my $slot_name (keys(%$consumed_uniqueperiods)) {      foreach my $slot_name (keys(%$consumed_uniqueperiods)) {
  my ($start,$end)=@{$consumed_uniqueperiods->{$slot_name}};   my ($start,$end)=@{$consumed_uniqueperiods->{$slot_name}};
Line 229  sub check_for_conflict { Line 563  sub check_for_conflict {
  }   }
     }      }
     return undef;      return undef;
   
 }  }
   
 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 />");
   
     my $use_slots = &Apache::lonnet::EXT("resource.0.useslots");      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 />");      &Apache::lonxml::debug("use_slots is  $use_slots<br />");
   
     if (&Apache::lonnet::error($value)       if (&Apache::lonnet::error($value) 
Line 249  sub make_reservation { Line 581  sub make_reservation {
  return 'error: Unable to determine current status';   return 'error: Unable to determine current status';
     }      }
   
     my $parm_symb  = $symb;      my $symb_for_db = $symb;
     my $parm_level = 1;      my $parm_level = 1;
     if ($use_slots eq 'map' || $use_slots eq 'map_map') {      if ($use_slots eq 'map' || $use_slots eq 'map_map') {
  my ($map) = &Apache::lonnet::decode_symb($symb);   my ($map) = &Apache::lonnet::decode_symb($symb);
  $parm_symb = &Apache::lonnet::symbread($map);   $symb_for_db = &Apache::lonnet::symbread($map);
  $parm_level = 2;   $parm_level = 2;
     }      }
   
Line 296  sub make_reservation { Line 628  sub make_reservation {
           
     my %reservation=('name'      => $env{'user.name'}.':'.$env{'user.domain'},      my %reservation=('name'      => $env{'user.name'}.':'.$env{'user.domain'},
      'timestamp' => time,       'timestamp' => time,
      'symb'      => $parm_symb);       'symb'      => $symb_for_db);
   
     my $success=&Apache::lonnet::newput('slot_reservations',      my $success=&Apache::lonnet::newput('slot_reservations',
  {"$slot_name\0$wanted" =>   {"$slot_name\0$wanted" =>
Line 308  sub make_reservation { Line 640  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,          my $result = &store_slot_parm($symb,$symb_for_db,$slot_name,$parm_level,
       '0_availablestudent',                                        $new_value,$cnum,$cdom,$env{'user.name'},
        $parm_level, $new_value,                                        $env{'user.domain'},'reserve',$env{'form.context'});
        'string',  
        $env{'user.name'},  
                $env{'user.domain'});  
  &Apache::lonxml::debug("hrrm $result");  
  return $wanted;   return $wanted;
     }      }
   
Line 322  sub make_reservation { Line 650  sub make_reservation {
     return undef;      return undef;
 }  }
   
   sub store_slot_parm {
       my ($symb_for_parm,$symb_for_db,$slot_name,$parm_level,$new_value,
           $cnum,$cdom,$uname,$udom,$action,$context,$delflag) = @_;
   
       # store new parameter string
       my $result=&Apache::lonparmset::storeparm_by_symb($symb_for_parm,
                                                         '0_availablestudent',
                                                         $parm_level,$new_value,
                                                         'string',$uname,$udom);
       &Apache::lonxml::debug("hrrm $result");
       my %storehash = (
                          symb    => $symb_for_db,
                          slot    => $slot_name,
                          action  => $action,
                          context => $context,
                       );
   
       &Apache::lonnet::write_log('course','slotreservationslog',\%storehash,
                                  $delflag,$uname,$udom,$cnum,$cdom);
       &Apache::lonnet::write_log('course',$cdom.'_'.$cnum.'_slotlog',\%storehash,
                                  $delflag,$uname,$udom,$uname,$udom);
       return $result;
   }
   
 sub remove_registration {  sub remove_registration {
     my ($r) = @_;      my ($r) = @_;
     if ($env{'form.entry'} ne 'remove all') {      if ($env{'form.entry'} ne 'remove all') {
Line 334  sub remove_registration { Line 686  sub remove_registration {
     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 (&Apache::lonnet::error(%consumed)) {      if (&Apache::lonnet::error(%consumed)) {
  $r->print("<p>".&mt('A network error has occured.').'</p>');   $r->print("<p><span class=\"LC_error\">".&mt('A network error has occurred.').'</span></p>');
  return;   return;
     }      }
     if (!%consumed) {      if (!%consumed) {
  $r->print("<p>".&mt('Slot <tt>[_1]</tt> has no reservations.',   $r->print('<p>'.&mt('Slot [_1] has no reservations.',
     $slot_name)."</p>");      '<tt>'.$slot_name.'</tt>').'</p>');
  return;   return;
     }      }
   
Line 347  sub remove_registration { Line 699  sub remove_registration {
     my $names = join(' ',@names);      my $names = join(' ',@names);
   
     my $msg = &mt('Remove all of [_1] from slot [_2]?',$names,$slot_name);      my $msg = &mt('Remove all of [_1] from slot [_2]?',$names,$slot_name);
     &remove_registration_confirmation($r,$msg,['entry','slotname']);      &remove_registration_confirmation($r,$msg,['entry','slotname','context']);
 }  }
   
 sub remove_registration_user {  sub remove_registration_user {
Line 364  sub remove_registration_user { Line 716  sub remove_registration_user {
   $name,$slot_name,$title);    $name,$slot_name,$title);
           
     &remove_registration_confirmation($r,$msg,['uname','udom','slotname',      &remove_registration_confirmation($r,$msg,['uname','udom','slotname',
        'entry','symb']);         'entry','symb','context']);
 }  }
   
 sub remove_registration_confirmation {  sub remove_registration_confirmation {
Line 376  sub remove_registration_confirmation { Line 728  sub remove_registration_confirmation {
     '<input type="hidden" name="'.$parm.'" value="'      '<input type="hidden" name="'.$parm.'" value="'
     .&HTML::Entities::encode($env{'form.'.$parm},'"<>&\'').'" />'."\n";      .&HTML::Entities::encode($env{'form.'.$parm},'"<>&\'').'" />'."\n";
     }      }
     my %lt = &Apache::lonlocal::texthash('yes' => 'Yes',      my %lt = &Apache::lonlocal::texthash(
  'no'  => 'No',);          'yes' => 'Yes',
           'no'  => 'No',
       );
     $r->print(<<"END_CONFIRM");      $r->print(<<"END_CONFIRM");
 <p> $msg </p>  <p> $msg </p>
 <form action="/adm/slotrequest" method="post">  <form action="/adm/slotrequest" method="post">
Line 412  sub release_all_slot { Line 766  sub release_all_slot {
  my ($result,$msg) =   my ($result,$msg) =
     &release_reservation($slot_name,$uname,$udom,      &release_reservation($slot_name,$uname,$udom,
  $consumed{$entry}{'symb'},$mgr);   $consumed{$entry}{'symb'},$mgr);
  $r->print("<p>$msg</p>");          if (!$result) {
               $r->print('<p class="LC_error">'.&mt($msg).'</p>');
           } else {
       $r->print("<p>$msg</p>");
           }
  $r->rflush();   $r->rflush();
     }      }
     $r->print('<p><a href="/adm/slotrequest?command=showslots">'.      $r->print('<p><a href="/adm/slotrequest?command=showslots">'.
Line 433  sub release_slot { Line 791  sub release_slot {
   
     if ($mgr eq 'F'       if ($mgr eq 'F' 
  && defined($env{'form.symb'})) {   && defined($env{'form.symb'})) {
  $symb = $env{'form.symb'};   $symb = &unescape($env{'form.symb'});
     }      }
   
     my ($result,$msg) =      my ($result,$msg) =
  &release_reservation($slot_name,$uname,$udom,$symb,$mgr);   &release_reservation($slot_name,$uname,$udom,$symb,$mgr);
     $r->print("<p>$msg</p>");      if (!$result) {
           $r->print('<p class="LC_error">'.&mt($msg).'</p>');
       } else {
           $r->print("<p>$msg</p>");
       }
           
     if ($mgr eq 'F') {      if ($mgr eq 'F') {
  $r->print('<p><a href="/adm/slotrequest?command=showslots">'.   $r->print('<p><a href="/adm/slotrequest?command=showslots">'.
Line 453  sub release_reservation { Line 815  sub release_reservation {
     my ($slot_name,$uname,$udom,$symb,$mgr) = @_;      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($slot_name,\%slot);      my $description=&get_description($slot_name,\%slot);
       my $msg;
   
     if ($mgr ne 'F') {      if ($mgr ne 'F') {
  if ($slot{'starttime'} < time) {   if ($slot{'starttime'} < time) {
     return (0,&mt('Not allowed to release Reservation: [_1], as it has already ended.',$description));      return (0,&mt('Not allowed to release Reservation: [_1], as it has already started.',$description));
  }   }
     }      }
     # get parameter string, check for existance, rebuild string with the slot      my $context = $env{'form.context'};
     my @slots = split(/:/,&Apache::lonnet::EXT("resource.0.availablestudent",  
        $symb,$udom,$uname));  
   
     my @new_slots;      # get navmap object
     foreach my $exist_slot (@slots) {      my $navmap=Apache::lonnavmaps::navmap->new;
  if ($exist_slot eq $slot_name) { next; }      if (!defined($navmap)) {
  push(@new_slots,$exist_slot);          return (0,'error: Unable to determine current status');
     }      }
     my $new_param = join(':',@new_slots);  
   
     my ($cnum,$cdom)=&get_course();      my ($cnum,$cdom)=&get_course();
   
     # get slot reservations, check if user has one, if so remove reservation      # get slot reservations, check if user has 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");
   
       #
       # If release is because of a reservation *change*, symb(s) associated with reservation
       # being dropped may differ from the current symb.
       #
       # We need to get symb(s) from slot_reservations.db, and for each symb, update
       # the value of the availablestudent parameter, at the appropriate level
       # (as dictated by the value of the useslots parameter for the symb and user).
       #
       # We also delete all entries for the slot being released, for the specific user.
       #
   
       my $conflict;
   
       if (($env{'form.command'} eq 'change') && ($slot_name eq $env{'form.releaseslot'}) &&
           ($env{'form.slotname'} ne $slot_name)) {
           my %changedto = &Apache::lonnet::get_slot($env{'form.slotname'});
   
           # check for conflicts
           my ($to_uniq_start,$to_uniq_end,$from_uniq_start,$from_uniq_end);
           if (ref($changedto{'uniqueperiod'}) eq 'ARRAY') {
               ($to_uniq_start,$to_uniq_end) = @{$changedto{'uniqueperiod'}};
           }
           if (ref($slot{'uniqueperiod'}) eq 'ARRAY') {
               ($from_uniq_start,$from_uniq_end) = @{$slot{'uniqueperiod'}};
           }
           my $to_start = $changedto{'starttime'};
           my $to_end = $changedto{'endtime'};
           my $from_start = $slot{'starttime'};
           my $from_end = $slot{'endtime'};
   
           if (!
                ($from_start < $to_uniq_start && $from_end < $to_uniq_start) ||
                ($from_start > $to_uniq_end   && $from_end > $to_uniq_end  )) {
               $conflict = 1;
           }
           if (!
                ($to_start < $from_uniq_start && $to_end < $from_uniq_start) ||
                ($to_start > $from_uniq_end   && $to_end > $from_uniq_end  )) {
               $conflict = 1;
           }
   
           if ($conflict) {
               my %symbs_for_slot;
               my (%to_delete,%failed,%released);
               foreach my $entry (keys(%consumed)) {
                   if ( $consumed{$entry}->{'name'} eq ($uname.':'.$udom) ) {
                       $symbs_for_slot{$consumed{$entry}->{'symb'}} = 1;
                       $to_delete{$entry} = 1;
                   }
               }
               if (keys(%to_delete)) {
                   my @removals = keys(%to_delete);
                   if (&Apache::lonnet::del('slot_reservations',\@removals,
                                        $cdom,$cnum) eq 'ok') {
                       foreach my $item (keys(%symbs_for_slot)) {
                           my $result = &update_selectable($navmap,$slot_name,$item,$cdom,
                                                           $cnum,$udom,$uname,$context);
                           if ($result =~ /^error/) {
                               $failed{$item} = 1;
                           } else {
                               $released{$item} = 1;
                           }
                       }
                   }
               }
               if (keys(%released)) {
                   $msg = '<span style="font-weight: bold;">'.
                          &mt('Released Reservation: [_1]',$description).'</span>&nbsp;&nbsp;'.
                          &mt('The following items had their reservation status change').':';
                   my (%folders,%pages,%container,%titles);
                   foreach my $item (keys(%released)) {
                       my $res = $navmap->getBySymb($item);
                       if (ref($res)) {
                           $titles{$item} = $res->title();
                           if ($res->is_map()) {
                               $folders{$item}{'title'} = $titles{$item};
                               if ($res->is_page()) {
                                   $pages{$item}{'title'} = $titles{$item};
                               } else {
                                   $folders{$item}{'title'} = $titles{$item};
                               }
                           } else {
                               my $mapsrc = $res->enclosing_map_src();
                               my $map = $navmap->getResourceByUrl($mapsrc);
                               if (ref($map)) {
                                   if ($map->id() eq '0.0') {
                                       $container{$mapsrc}{'title'} &mt('Top level of course');
                                   } else {
                                       $container{$mapsrc}{'title'} = $map->title();
                                       if ($map->is_page()) {
                                           $container{$mapsrc}{'page'} = 1;
                                       }
                                   }
                               }
                               $container{$mapsrc}{'resources'}{$item} = 1;
                           }
                       }
                   }
                   $msg .= '<ul>';
                   if (keys(%folders)) {
                       $msg .= '<li>'.&mt('Folders').': '.
                               join(', ', map { $folders{$_}{'title'} } (sort { $folders{$b}{'title'} cmp $folders{$a}{'title'} } (keys(%folders)))).
                               '</li>';
                   }
                   if (keys(%pages)) {
                       $msg .= '<li>'.&mt('Composite Pages').': '.
                               join(', ', map { $pages{$_}{'title'} } (sort { $pages{$b}{'title'} cmp $pages{$a}{'title'} } (keys(%pages)))).
                               '</li>';
                   }
                   if (keys(%container)) {
                       $msg .= '<li>'.&mt('Resources').':<ul>';
                       foreach my $key (sort { $container{$b}{'title'} cmp $container{$a}{'title'} } (keys(%container))) {
                           if (ref($container{$key}{'resources'}) eq 'HASH') {
                               $msg .= '<li>'.
                                       join(', ', map { $titles{$_} } (sort(keys(%{$container{$key}{'resources'}}))));
                               if ($container{$key}{'page'}) {
                                   $msg .= ' '.&mt('(in composite page [_1])',$container{$key}{'title'}).'</li>';
                               } else {
                                   $msg .= ' '.&mt('(in folder [_1])',$container{$key}{'title'}).'</li>';
                               }
                           }
                       }
                       $msg .= '</ul></li>';
                   }
                   $msg .= '</ul>';
                   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');
                   return (1,$msg);
               } else {
                   if (keys(%to_delete)) {
                       $msg = &mt('Reservation release partially complete for [_1]',$description);
                   } else {
                       $msg = &mt('No entries found for this user to release for [_1].',$description);
                   }
                   return (0,$msg);
               }
           } else {
               $msg = &mt('No conflict found; not releasing: [_1].',$description);
               return (0,$msg);
           }
       }
   
       my $map_symb;
       my $parm_symb = $symb;
       my $passed_resource = $navmap->getBySymb($symb);
   
       # if the reservation symb is for a map get a resource in that map
       # to check slot parameters on
       my $parm_level = 1;
       if (ref($passed_resource)) {
           if ($passed_resource->is_map()) {
       my ($a_resource) = 
                   $navmap->retrieveResources($passed_resource, 
                       sub {$_[0]->is_problem() || $_[0]->is_tool() },0,1);
               $parm_symb = $a_resource->symb();
           }
       } else {
           unless ($mgr eq 'F') {
               return (0,'error: Unable to determine current status');
           }
       }
   
       # Get value of useslots parameter in effect for this user.
       # If value is map or map_map, then the parm level is 2 (i.e.,
       # non-recursive enclosing map/folder level for specific user)
       # and the symb for this reservation in slot_reservations.db
       # will be the symb of the map itself.
   
       my $use_slots = &Apache::lonnet::EXT('resource.0.useslots',
                                            $parm_symb,$udom,$uname);
       if (&Apache::lonnet::error($use_slots)) {
           return (0,'error: Unable to determine current status');
       }
       if ($use_slots eq 'map' || $use_slots eq 'map_map') {
           $parm_level = 2;
           if ($passed_resource->is_map()) {
               $map_symb = $passed_resource->symb();
           } else {
               my ($map) = &Apache::lonnet::decode_symb($symb);
               $map_symb = &Apache::lonnet::symbread($map);
           }
       }
   
       #
       # If release is *not* because of a reservation change, i.e., this is a "drop"
       # by a student, or a removal for a single student by an instructor then
       # only remove one entry from slot_reservations.db, where both the user
       # and the symb match the current context.  If useslots was set to map or
       # map_map, then the symb to match in slot_reservations.db is the symb of
       # the enclosing map/folder, not the symb of the resource.
       #
   
       my ($match,$symb_to_check);
       if ($parm_level == 2) {
           $symb_to_check = $map_symb;
       } else {
           $symb_to_check = $parm_symb;
       }
     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],              if ($consumed{$entry}->{'symb'} eq $symb_to_check) {
  $cdom,$cnum);                  if (&Apache::lonnet::del('slot_reservations',[$entry],
  }                                           $cdom,$cnum) eq 'ok') {
                       $match = $symb_to_check;
                   }
                   last;
               }
           }
     }      }
       if ($match) {
           if (&update_selectable($navmap,$slot_name,$symb,$cdom,
                                  $cnum,$udom,$uname,$context) =~ /^error/) {
               if ($mgr eq 'F') {
                   $msg = &mt('Reservation release partially complete for: [_1]',"$uname:$udom").'<br />'.
                          &mt('Update of availablestudent parameter for [_1] was not completed.',"$uname:$udom");
               } else {
                   $msg = &mt('Release partially complete for: [_1]',$description);
               }
               return (0,$msg);
           } else {
               if ($mgr eq 'F') {
                   $msg = &mt('Released Reservation for user: [_1]',"$uname:$udom");
               } 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');
               }
               return (1,$msg);
           }
       } else {
           $msg = &mt('Release failed for: [_1]',$description);
           return (0,$msg);
       }
   }
   
   sub update_selectable {
       my ($navmap,$slot_name,$symb,$cdom,$cnum,$udom,$uname,$context) = @_;
       return 'error: ' unless (ref($navmap));
       my $symb_for_parm = $symb;
       my $passed_resource = $navmap->getBySymb($symb);
       return 'error: invalid symb' unless (ref($passed_resource));
   
       # if the reservation symb is for a map get a resource in that map
       # to check slot parameters on
       if ($passed_resource->is_map()) {
           my ($a_resource) =
               $navmap->retrieveResources($passed_resource,
                                          sub {$_[0]->is_problem() || $_[0]->is_tool() },0,1);
           $symb_for_parm = $a_resource->symb();
       }
       # get parameter string, check for existence, rebuild string with the slot
       my $student = &Apache::lonnet::EXT('resource.0.availablestudent',
                                          $symb_for_parm,$udom,$uname);
   
       # Get value of useslots parameter in effect for this user.
       # If value is map or map_map, then the parm level is 2 (i.e.,
       # non-recursive enclosing map/folder level for specific user)
       # and the symb for this reservation in slot_reservations.db
       # will be the symb of the map itself.
   
     my $use_slots = &Apache::lonnet::EXT("resource.0.useslots");      my $use_slots = &Apache::lonnet::EXT('resource.0.useslots',
                                            $symb_for_parm,$udom,$uname);
     &Apache::lonxml::debug("use_slots is  $use_slots<br />");      &Apache::lonxml::debug("use_slots is  $use_slots<br />");
   
     if (&Apache::lonnet::error($use_slots)) {       if (&Apache::lonnet::error($use_slots)) {
  return (0,'error: Unable to determine current status');          return 'error: Unable to determine current status';
     }      }
   
     my $parm_level = 1;      my $parm_level = 1;
     if ($use_slots eq 'map' || $use_slots eq 'map_map') {      if ($use_slots eq 'map' || $use_slots eq 'map_map') {
  $parm_level = 2;          $parm_level = 2;
     }      }
     # store new parameter string  
     my $result=&Apache::lonparmset::storeparm_by_symb($symb,  
       '0_availablestudent',  
       $parm_level, $new_param,  
       'string', $uname, $udom);  
   
     my $msg;      my @slots = split(/:/,$student);
     if ($mgr eq 'F') {  
  $msg = &mt('Released Reservation for user: [_1]',"$uname:$udom");      my @new_slots;
     } else {      foreach my $exist_slot (@slots) {
  $msg = &mt('Released Reservation: [_1]',$description);          next if ($exist_slot eq $slot_name);
           push(@new_slots,$exist_slot);
     }      }
     return (1,$msg);      my $new_value = join(':',@new_slots);
   
       my $result = &store_slot_parm($symb_for_parm,$symb,$slot_name,$parm_level,
                                     $new_value,$cnum,$cdom,$uname,$udom,'release',
                                     $context,1);
       return $result;
 }  }
   
 sub delete_slot {  sub delete_slot {
Line 525  sub delete_slot { Line 1145  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 class="LC_error">'.&mt('An error occurred when attempting to delete slot: [_1]','<tt>'.$slot_name.'</tt>')." ($ret)</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 543  sub delete_slot { Line 1163  sub delete_slot {
   
 sub return_link {  sub return_link {
     my ($r) = @_;      my ($r) = @_;
     $r->print('<p><a href="/adm/flip?postdata=return:">'.      my $target = &return_target();
       &mt('Return to last resource').'</a></p>');      if (($env{'form.command'} eq 'manageresv') || ($env{'form.context'} eq 'usermanage')) {
    $r->print('<p><a href="/adm/slotrequest?command=manageresv" target="'.$target.'">'.
                     &mt('Return to reservations').'</a></p>');  
       } else {
           $r->print('<p><a href="/adm/flip?postdata=return:" target="'.$target.'">'.
             &mt('Return to last resource').'</a></p>');
       }
   }
   
   sub return_target {
       my ($target,$ltitarget,$deeplinktarget);
       if ($env{'request.lti.login'}) {
            $ltitarget = $env{'request.lti.target'};
       }
       if ($env{'request.deeplink.login'}) {
           $deeplinktarget = $env{'request.deeplink.target'};
       }
       if (($ltitarget eq 'iframe') || ($deeplinktarget eq '_self')) {
           $target = '_self';
       } else {
           $target = '_top';
       }
       return $target;
 }  }
   
 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 class="LC_error">'
                    .&mt('An error occurred while attempting to make a reservation. ([_1])',$1)
                    .'</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);
           my $slottype1=$slot{'type'};
  %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 ($slottype1 eq 'preassigned') {
  if ($slot_name ne $env{'form.slotname'}) {              $r->print('<p>'.&mt('You already have a reservation: "[_1]", assigned by your instructor.',
                                   $description1).'</p>'.
                         '<p>'.&mt('Your instructor must unassign it before you can make a new reservation.').
                         '</p>');
           } elsif ($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'}" />
Line 572  sub get_slot { Line 1221  sub get_slot {
    <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 class="LC_error">'
                        .&mt('An error occurred while attempting to make a reservation. ([_1])',$1)
                        .'</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' => 'Availability 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,$consumed_uniqueperiods)=@_;      my ($slot_name,$slot,$symb,$slots,$consumed_uniqueperiods,$toskip)=@_;
   
     #already started      #already started
     if ($slot->{'starttime'} < time) {      if ($slot->{'starttime'} < time) {
  # all open slot to be schedulable   return 0;
  #return 0;  
     }      }
     &Apache::lonxml::debug("$slot_name starttime good");      &Apache::lonxml::debug("$slot_name starttime good");
   
Line 660  sub allowed_slot { Line 1336  sub allowed_slot {
     if ($slot->{'startreserve'} > time) {      if ($slot->{'startreserve'} > time) {
  return 0;   return 0;
     }      }
       # reserve time ended
       if (($slot->{'endreserve'}) &&
           ($slot->{'endreserve'} < time)) {
           return 0;
       }    
     &Apache::lonxml::debug("$slot_name reserve good");      &Apache::lonxml::debug("$slot_name reserve good");
   
     my $userallowed=0;      my $userallowed=0;
Line 704  sub allowed_slot { Line 1385  sub allowed_slot {
     return 0 if (!$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) {          my $exclude = 1;
  return 0;          my @symbs;
           if ($slot->{'symb'} =~ /,/) {
               @symbs = split(/\s*,\s*/,$slot->{'symb'});
           } else {
               @symbs = ($slot->{'symb'});
           }
           my ($map,$id,$url) = &Apache::lonnet::decode_symb($symb);
           foreach my $reqsymb (@symbs) {
               next if ($reqsymb eq '');
               my ($slotmap,$slotid,$sloturl) = &Apache::lonnet::decode_symb($reqsymb);
               if ($sloturl=~/\.(page|sequence)$/) {
                   if (($map ne '') && ($map eq $sloturl)) {
                       $exclude = 0;
                       last;
                   }
               } elsif ($reqsymb eq $symb) {
                   $exclude = 0;
                   last;
               }
           }
           if ($exclude) {
               unless ((ref($toskip) eq 'HASH') && ($toskip->{'symb'})) {
           return 0;
               }
           }
     }      }
   
     my $conflict = &check_for_conflict($symb,$slot_name,$slot,$slots,      my $conflict = &check_for_conflict($symb,$slot_name,$slot,$slots,
        $consumed_uniqueperiods);         $consumed_uniqueperiods);
     if ($conflict) {      if ($conflict =~ /^error: /) {
           return 0;
       } elsif ($conflict ne '') {
  if ($slots->{$conflict}{'starttime'} < time) {   if ($slots->{$conflict}{'starttime'} < time) {
     return 0;      return 0;
  }   }
Line 732  sub get_description { Line 1439  sub get_description {
 }  }
   
 sub show_choices {  sub show_choices {
     my ($r,$symb)=@_;      my ($symb,$formname,$num,$class,$slots,$consumed_uniqueperiods,$available,$got_slots)=@_;
       my $output;
     my ($cnum,$cdom)=&get_course();  
     my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum);  
     my $consumed_uniqueperiods = &get_consumed_uniqueperiods(\%slots);  
     my $available;  
     $r->print('<table border="1">');  
     &Apache::lonxml::debug("Checking Slots");      &Apache::lonxml::debug("Checking Slots");
     my @got_slots=&check_for_reservation($symb,'allslots');      if (!ref($available) eq 'ARRAY') {
     foreach my $slot (sort           return;
       { return $slots{$a}->{'starttime'} <=> $slots{$b}->{'starttime'} }      }
       (keys(%slots)))  {      if (!@{$available}) {
           $output = '<span class="LC_info">'.&mt('No available times.').'</span>';
  &Apache::lonxml::debug("Checking Slot $slot");          if ($env{'form.command'} ne 'manageresv') {
  next if (!&allowed_slot($slot,$slots{$slot},undef,\%slots,              my $target = &return_target();
  $consumed_uniqueperiods));              $output .= ' <a href="/adm/flip?postdata=return:" target="'.$target.'">'.
                          &mt('Return to last resource').'</a>';
  $available++;          }
           if ($class) {
  my $description=&get_description($slot,$slots{$slot});              return '<div class="'.$class.'">'.$output.'</div>';
           } else {
               return $output;
           }
       }
       if (@{$available} > 1) {
           my $numavailable = scalar(@{$available});
           my $numreserved = 0;
           my $js;
           my $j = 0;
           foreach my $got (@{$got_slots}) {
               unless (($got eq '') || (!defined($got))) {
                   $numreserved ++;
                   if ($env{'form.command'} eq 'manageresv') {
                       $js .= "    currslot[$j]='$got';\n";
                       $j++;
                   }
               }
           }
           my $showfilter = 'none';
           $output .= '<fieldset><legend>'.&mt('Actions').'</legend>'."\n".
                      '<form method="post" name="reservationdisplay_'.$num.
                      '" action="" onsubmit="toggleSlotDisplay(this.form,'."'$num'".');">';
           my @options = ('all','filter');
           if ($numreserved) {
               unshift(@options,'show');
           }
           my %resmenu = &Apache::lonlocal::texthash (
                                            show   => 'Show current reservation',
                                            all    => 'Show all', 
                                            filter => 'Search by date',
                        );
           foreach my $option (@options) {
               my $onclick = "toggleSlotDisplay(this.form,'$num');";
               if (($option eq 'show') && ($env{'form.command'} eq 'manageresv')) {  
                   $onclick .= "currSlotDisplay$num(this.form,'$num');"; 
               }
               $output .= '<span class="LC_nobreak"><label>'.
                          '<input type="radio" class="LC_slotpick_radio" name="slotpick" value="'.
                          $option.'" onclick="'.$onclick.'" />'.
                          $resmenu{$option}.
                          '</label></span>'.('&nbsp;' x3)."\n";
           }
           $output .= '</form>';
           my $chooserform = 'reservationchooser_'.$num;
           my $starttime = $slots->{$available->[0]}->{'starttime'};
           my $endtime = $slots->{$available->[-1]}->{'starttime'};
           if ($env{'form.command'} eq 'manageresv') {
               $output .= <<"ENDSCRIPT";
   
   <script type="text/javascript">
   // <![CDATA[
   function currSlotDisplay$num() {
       var currslot = new Array($numreserved);
   $js    
       for (var j=0; j<$numreserved; j++) {
           if (document.getElementById('LC_slotrow_$num\_'+currslot[j])) {
               document.getElementById('LC_slotrow_$num\_'+currslot[j]).style.display = '';
           }
       }
   }
   // ]]>
   </script>
   
  my $form=&mt('Unavailable');  ENDSCRIPT
  if ((grep(/^\Q$slot\E$/,@got_slots)) ||          }
     &space_available($slot,$slots{$slot},$symb)) {          $output .=
               '<div id="LC_slotfilter_'.$num.'" style="display:'.$showfilter.'">'.
               '<form method="post" name="'.$chooserform.'" action="">'.
               '<table><tr><td>'.&mt('Open after').'</td><td>'.
               &Apache::lonhtmlcommon::date_setter($chooserform,'start',$starttime,'','','','','','','',1,1).
               '</td></tr><tr><td>'.&mt('Closed before').'</td><td>'.
               &Apache::lonhtmlcommon::date_setter($chooserform,'end',$endtime,'','','','','','','',1,1).
               '</td></tr></table><br />'.
               '<input type="button" name="slotfilter" value="Search for reservable slots" onclick="updateSlotDisplay(this.form,'."'$num'".');" />'.
               '</form></div><div id="LC_slotsearch_'.$num.'" style="display:none"><hr />';
       }
       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 $form;
    if ((grep(/^\Q$slot\E$/,@{$got_slots})) ||
       &space_available($slot,$slots->{$slot},$symb)) {
     my $text=&mt('Select');      my $text=&mt('Select');
     my $command='get';      my $command='get';
     if (grep(/^\Q$slot\E$/,@got_slots)) {      if (grep(/^\Q$slot\E$/,@{$got_slots})) {
  $text=&mt('Free Reservation');   $text=&mt('Drop Reservation');
  $command='release';   $command='release';
     } else {      } else {
  my $conflict = &check_for_conflict($symb,$slot,$slots{$slot},   my $conflict = &check_for_conflict($symb,$slot,$slots->{$slot},
    \%slots,     $slots,$consumed_uniqueperiods);
    $consumed_uniqueperiods);                  if ($conflict) {
  if ($conflict) {                      if ($conflict =~ /^error: /) {
     $text=&mt('Change Reservation');                          $form = '<span class="LC_error">'.
     $command='get';                                   &mt('Slot: [_1] has unknown status.',$description).
  }                                   '</span>';
                       } else {
           $text=&mt('Change Reservation');
           $command='get';
       }
                   }
     }      }
     my $escsymb=&escape($symb);      my $escsymb=&escape($symb);
     $form=<<STUFF;              if (!$form) {
    <form method="post" action="/adm/slotrequest">                  my $name;
                   if ($formname) {
                        $name = 'name="'.$formname.'"';
                   }
                   my $context = 'user';
                   if ($env{'form.command'} eq 'manageresv') {
                       $context = 'usermanage';
                   }
           $form=<<STUFF;
      <form method="post" action="/adm/slotrequest" $name>
      <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 id="LC_slotrow_'.$num.'_'.$slot.'" >';
           } else {
       $output .= &Apache::loncommon::start_data_table_row('','LC_slotrow_'.$num.'_'.$slot);
           }
           $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();
       }
       if (@{$available} > 1) {
           $output .= '</div></fieldset>';
       }
       if ($class) {
           return '<div class="'.$class.'">'.$output.'</div>';
       } else {
           return $output;
     }      }
     $r->print('</table>');  
 }  }
   
 sub to_show {  sub to_show {
Line 876  sub remove_link { Line 1692  sub remove_link {
     $symb      = &escape($symb);      $symb      = &escape($symb);
   
     return <<"END_LINK";      return <<"END_LINK";
  <a href="/adm/slotrequest?command=remove_registration&amp;slotname=$slotname&amp;entry=$entry&amp;uname=$uname&amp;udom=$udom&amp;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 886  sub show_table { Line 1702  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);
Line 897  sub show_table { Line 1714  sub show_table {
 <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(&Apache::loncommon::help_open_topic('Slot CommaDelimited'));
  $r->print('<form method="post" action="/adm/helper/newslot.helper">   $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 About'));
  $r->print('</div>');   $r->print('</div>');
     }      }
   
       if (!keys(%slots)) {
           $r->print(
               '<p class="LC_info">'
              .&mt('No slots have been created in this '.lc($crstype).'.')
              .'</p>'
           );
           return;
       }
           
     my %Saveable_Parameters = ('show'              => 'array',      my %Saveable_Parameters = ('show'              => 'array',
        'when'              => 'scalar',         'when'              => 'scalar',
Line 926  sub show_table { Line 1754  sub show_table {
      'starttime'       => 'Start time',       'starttime'       => 'Start time',
      'endtime'         => 'End Time',       'endtime'         => 'End Time',
              'startreserve'    => 'Time students can start reserving',               'startreserve'    => 'Time students can start reserving',
                'endreserve'      => 'Time students can no longer reserve',
                'reservationmsg'  => 'Message triggered by reservation',
      'secret'          => 'Secret Word',       'secret'          => 'Secret Word',
      'maxspace'        => 'Maximum # of students',       'space'           => '# of students/max',
      'ip'              => 'IP or DNS restrictions',       'ip'              => 'IP or DNS restrictions',
      'symb'            => 'Resource slot is restricted to.',       'symb'            => 'Resource(s)/Map(s) slot is restricted to.',
      'allowedsections' => 'Sections slot is restricted to.',       'allowedsections' => 'Sections slot is restricted to.',
      'allowedusers'    => 'Users slot is restricted to.',       'allowedusers'    => 'Users slot is restricted to.',
      'uniqueperiod'    => 'Period of time slot is unique',       'uniqueperiod'    => 'Period of time slot is unique',
      'scheduled'       => 'Scheduled Students',       'scheduled'       => 'Scheduled Students',
      'proctor'         => 'List of proctors');       'proctor'         => 'List of proctors',
        'iptied'          => 'Unique IP each student',);
       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',
     'allowedsections','allowedusers','uniqueperiod',      'ip','iptied','symb','allowedsections','allowedusers','uniqueperiod',
     'scheduled','proctor');      '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')
Line 1003  sub show_table { Line 1839  sub show_table {
           <th>'.&mt('Slot Name Filter').'</th>            <th>'.&mt('Slot Name Filter').'</th>
           <th>'.&mt('Options').'</th>            <th>'.&mt('Options').'</th>
       </tr>        </tr>
       <tr><td>'.&Apache::loncommon::multiple_select_form('show',\@show,6,\%show_fields,\@show_order).        <tr><td valign="top">'.&Apache::loncommon::multiple_select_form('show',\@show,6,\%show_fields,\@show_order).
       '</td>        '</td>
            <td>             <td valign="top">
          '.&Apache::loncommon::multiple_select_form('studisplay',\@stu_display,           '.&Apache::loncommon::multiple_select_form('studisplay',\@stu_display,
     6,\%stu_display_fields,      6,\%stu_display_fields,
     \@stu_display_order).'      \@stu_display_order).'
            </td>             </td>
            <td>'.&Apache::loncommon::select_form($when,'when',%when_fields).             <td valign="top">'.&Apache::loncommon::select_form($when,'when',\%when_fields).
           '</td>            '</td>
            <td>'.&Apache::loncommon::select_form($name_filter_type,             <td valign="top">'.&Apache::loncommon::select_form($name_filter_type,
  'name_filter_type',   'name_filter_type',
  %name_filter_type_fields).   \%name_filter_type_fields).
       '<br />'.        '<br />'.
       &Apache::lonhtmlcommon::textbox('name_filter_value',        &Apache::lonhtmlcommon::textbox('name_filter_value',
       $env{'form.name_filter_value'},        $env{'form.name_filter_value'},
       15).        15).
           '</td>            '</td>
            <td>             <td valign="top">
             <table>              <table>
               <tr>                <tr>
                 <td rowspan="2">Deleted slots:</td>                  <td rowspan="2">'.&mt('Deleted slots:').'</td>
                 <td><label>'.$show_radio.'Show</label></td>                  <td><label>'.$show_radio.&mt('Show').'</label></td>
               </tr>                </tr>
               <tr>                <tr>
                 <td><label>'.$hide_radio.'Hide</label></td>                  <td><label>'.$hide_radio.&mt('Hide').'</label></td>
               </tr>                </tr>
             </table>              </table>
   </td>    </td>
Line 1036  sub show_table { Line 1872  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(&Apache::loncommon::start_data_table().      my $tableheader = &Apache::loncommon::start_data_table().
       &Apache::loncommon::start_data_table_header_row().'                &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>');      $tableheader .= '<th>'.$linkstart.$which.'">'.$show_fields{$which}.'</a></th>';
  }   }
     }      }
     $r->print(&Apache::loncommon::end_data_table_header_row());      $tableheader .= &Apache::loncommon::end_data_table_header_row();
       my $shownheader = 0;
   
     my %name_cache;      my %name_cache;
     my $slotsort = sub {      my $slotsort = sub {
  if ($env{'form.order'}=~/^(type|description|endtime|startreserve|maxspace|ip|symb|allowedsections|allowedusers)$/) {   if ($env{'form.order'}=~/^(type|description|endtime|startreserve|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 1073  sub show_table { Line 1914  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($slot,$slots{$slot},$when,   if (!&to_show($slot,$slots{$slot},$when,
       $env{'form.deleted'},$name_filter)) { next; }        $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 $ids;   my ($id_count,$ids);
  if (exists($show{'scheduled'})) {      
     my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,   if (exists($show{'scheduled'}) || exists($show{'space'}) ) {
        "^$slot\0");      my $re_str = "$slot\0";
     my ($tmp)=%consumed;      my @this_slot = grep(/^\Q$re_str\E/,keys(%consumed));
     if ($tmp !~ /^error: /) {      $id_count = scalar(@this_slot);
       if (exists($show{'scheduled'})) {
  foreach my $entry (sort { $consumed{$a}{name} cmp    foreach my $entry (sort { $consumed{$a}{name} cmp 
       $consumed{$b}{name} }        $consumed{$b}{name} }
    (keys(%consumed))) {     (@this_slot)) {
     my (undef,$id)=split("\0",$entry);      my (undef,$id)=split("\0",$entry);
     my ($uname,$udom) = split(':',$consumed{$entry}{'name'});      my ($uname,$udom) = split(':',$consumed{$entry}{'name'});
     $ids.= '<nobr>';      $ids.= '<span class="LC_nobreak">';
     foreach my $item (@stu_display_order) {      foreach my $item (@stu_display_order) {
  if ($stu_display{$item}) {   if ($stu_display{$item}) {
     if ($item eq 'fullname') {      if ($item eq 'fullname') {
Line 1103  sub show_table { Line 1956  sub show_table {
  }   }
     }      }
     $ids.=&remove_link($slot,$entry,$uname,$udom,      $ids.=&remove_link($slot,$entry,$uname,$udom,
        $consumed{$entry}{'symb'}).'</nobr><br />';         $consumed{$entry}{'symb'}).'</span><br />';
  }   }
     }      }
  }   }
Line 1114  sub show_table { Line 1967  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'})) {
Line 1121  sub show_table { Line 1976  sub show_table {
  localtime($slots{$slot}{'uniqueperiod'}[1]);   localtime($slots{$slot}{'uniqueperiod'}[1]);
  }   }
   
  my $title;   my @titles;
  if (exists($slots{$slot}{'symb'})) {   if (exists($slots{$slot}{'symb'})) {
     my (undef,undef,$res)=              my @symbs;
  &Apache::lonnet::decode_symb($slots{$slot}{'symb'});              if ($slots{$slot}{'symb'} =~ /,/) {
     $res =   &Apache::lonnet::clutter($res);                  @symbs = split(/\s*,\s*/,$slots{$slot}{'symb'});
     $title = &Apache::lonnet::gettitle($slots{$slot}{'symb'});              } else {
     $title='<a href="'.$res.'?symb='.$slots{$slot}{'symb'}.'">'.$title.'</a>';                  @symbs = ($slots{$slot}{'symb'});
               }
               foreach my $reqsymb (@symbs) {
           my (undef,undef,$res) =
       &Apache::lonnet::decode_symb($reqsymb);
           $res = &Apache::lonnet::clutter($res);
           my $title = &Apache::lonnet::gettitle($reqsymb);
           push(@titles,'<a href="'.$res.'?symb='.$reqsymb.'">'.$title.'</a>');
               }
  }   }
   
  my $allowedsections;   my $allowedsections;
Line 1170  sub show_table { Line 2033  sub show_table {
  }   }
  my $proctors=join(', ',@proctors);   my $proctors=join(', ',@proctors);
   
  my $edit=(<<"EDITLINK");          my %lt = &Apache::lonlocal::texthash (
 <a href="/adm/helper/newslot.helper?name=$slot">Edit</a>                                                 edit   => 'Edit',
                                                  delete => 'Delete',
                                                  slotlog => 'History',
           );
           my ($edit,$delete,$showlog,$remove_all);
           if ($mgr) {
       $edit=(<<"EDITLINK");
   <a href="/adm/helper/newslot.helper?name=$slot">$lt{'edit'}</a>
 EDITLINK  EDITLINK
   
  my $delete=(<<"DELETELINK");      $delete=(<<"DELETELINK");
 <a href="/adm/slotrequest?command=delete&amp;slotname=$slot">Delete</a>  <a href="/adm/slotrequest?command=delete&amp;slotname=$slot">$lt{'delete'}</a>
 DELETELINK  DELETELINK
   
         my $remove_all=&remove_link($slot,'remove all').'<br />';              $remove_all=&remove_link($slot,'remove all').'<br />';
   
         if ($ids ne '') { undef($delete); }              if ($ids eq '') {
  if ($slots{$slot}{'type'} ne 'schedulable_student'                   undef($remove_all);
     || $ids eq '') {               } else {
                   undef($delete);
               }
           }
   
           $showlog=(<<"LOGLINK");
   <a href="/adm/slotrequest?command=slotlog&amp;slotname=$slot">$lt{'slotlog'}</a>
   LOGLINK
   
    if ($slots{$slot}{'type'} ne 'schedulable_student') {
               undef($showlog); 
     undef($remove_all);      undef($remove_all);
  }   }
   
           unless ($shownheader) {
               $r->print($tableheader);
               $shownheader = 1;
           }
   
  my $row_start=&Apache::loncommon::start_data_table_row();   my $row_start=&Apache::loncommon::start_data_table_row();
  my $row_end=&Apache::loncommon::end_data_table_row();   my $row_end=&Apache::loncommon::end_data_table_row();
         $r->print($row_start.          $r->print($row_start.
   "\n<td rowspan=\"$rowspan\">$edit $delete</td>\n");    "\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 1208  DELETELINK Line 2093  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");
  }   }
           if (exists($show{'iptied'})) {
               $colspan++;
               if ($slots{$slot}{'iptied'} eq 'yes') {
                   $r->print('<td>'.&mt('Yes')."</td>\n");
               } elsif ($slots{$slot}{'iptied'} eq 'answer') {
                   $r->print('<td>'.&mt('Yes, including post-answer date')."</td>\n");
               } else {
                   $r->print('<td>'.&mt('No')."</td>\n");
               }
           }
  if (exists($show{'symb'})) {   if (exists($show{'symb'})) {
     $colspan++;$r->print("<td>$title</td>\n");      $colspan++;$r->print("<td>".join('<br />',@titles)."</td>\n");
  }   }
  if (exists($show{'allowedsections'})) {   if (exists($show{'allowedsections'})) {
     $colspan++;$r->print("<td>$allowedsections</td>\n");      $colspan++;$r->print("<td>$allowedsections</td>\n");
Line 1241  $row_end Line 2149  $row_end
 STUFF  STUFF
         }          }
     }      }
     $r->print('</table></form>');      if ($shownheader) {
           $r->print(&Apache::loncommon::end_data_table());
       } else {
           $r->print('<p>'.&mt('No slots meet the criteria for display').'</p>');
       }
       $r->print('</form>');
       return;
   }
   
   sub manage_reservations {
       my ($r,$crstype,$slots,$consumed_uniqueperiods,$allavailable) = @_;
       my ($cnum,$cdom)=&get_course();
       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;
       }
       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 (%output,%slotinfo,%statusbymap,%repsymbs,%shownmaps);
       my @possibles = $navmap->retrieveResources(undef,
                                                 sub { $_[0]->is_problem() || $_[0]->is_tool() },1,0);
   
       foreach my $resource (@possibles) {
           my ($useslots) = $resource->slot_control();
           next if (($useslots eq '') || ($useslots =~ /^\s*no\s*$/i));
           my $symb = $resource->symb();
           my ($slot_status,$date,$slot_name) = $resource->check_for_slot('0');
           my ($msg,$get_choices,$slotdescription);
           my $status = $resource->simpleStatus('0');
           my ($msg,$get_choices,$slotdescription);
           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');
               }
           }
           $output{$symb}{'msg'} = $msg;
           if (($status == $resource->OPEN) && ($get_choices)) {
               $output{$symb}{'hasaction'} = 1;
           }
           my ($mapurl,$id,$resurl) = &Apache::lonnet::decode_symb($symb);
           $mapurl = &Apache::lonnet::clutter($mapurl);
           unless ($mapurl =~ /default\.sequence$/) {
               $shownmaps{$mapurl} = 1;
               my $map = $navmap->getResourceByUrl($mapurl);
               if (ref($map)) {
                   my @pcs = split(/,/,$map->map_hierarchy());
                   shift(@pcs);
                   shift(@pcs);
                   if (@pcs) {
                       map { $shownmaps{$navmap->getByMapPc($_)->src()} = 1; } reverse(@pcs);
                   }
               }
           }
           if (($useslots eq 'map_map') || ($useslots eq 'map')) {
               if ($slot_status ne '') {
                   if (ref($statusbymap{$mapurl}{$slot_status}) eq 'ARRAY') {
                       push(@{$statusbymap{$mapurl}{$slot_status}},$symb);
                   } else {
                       $statusbymap{$mapurl}{$slot_status} = [$symb];
                   }
               }
           }
       }
   
       foreach my $mapurl (keys(%statusbymap)) {
           if (ref($statusbymap{$mapurl}) eq 'HASH') {
               if (keys(%{$statusbymap{$mapurl}}) == 1) {
                   my @values = values(%{$statusbymap{$mapurl}});
                   my $repsymb = $values[0][0];
                   if (ref($output{$repsymb}) eq 'HASH') {
                       $output{$mapurl}{'msg'} = $output{$repsymb}{'msg'};
                       $output{$mapurl}{'hasaction'} = $output{$repsymb}{'hasaction'};
                   }
                   $repsymbs{$mapurl} = $repsymb;
               }
           }
       }
   
       my (%parent,%container,%container_title);
       my ($depth,$count,$reservable,$currcontainer,$rownum,$mapnum,$shown) = (0,0,0,0,0,0,0);
       my @backgrounds = ("LC_even_row","LC_odd_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" id="LC_slot_reservations">'."\n";
       my $shownheader = 0;
       my $currmap;
       my $it=$navmap->getIterator(undef,undef,undef,1,undef,undef);
       while (my $resource = $it->next()) {
           if ($resource == $it->BEGIN_MAP()) {
               $depth++;
               $parent{$depth} = $currcontainer;
               if (ref($container{$currcontainer})) {
                   my $currmapres = $container{$currcontainer};
                   my $currmaptitle = $container_title{$currcontainer};
                   $currmap = $currmapres->src();
                   my $currmaptype = 'sequence';
                   if ($currmapres->is_page()) {
                       $currmaptype = 'page';
                   }
                   if ($shownmaps{$currmap}) {
                       $mapnum ++;
                       $rownum ++;
                       $shown ++;
                       if (!$shownheader) {
                           $r->print($slotheader);
                           $shownheader = 1;
                       }
                       my $bgcolor = $backgrounds[$shown % $numcolors];
                       my ($spacers,$icon);
                       my $row = '<tr class="'.$bgcolor.'" id="LC_slotmaprow_'.$rownum.'">';
                       if (ref($statusbymap{$currmap}) eq 'HASH') {
                           my ($spacers,$icon) = &show_map_row($depth-1,$location,$currmaptype,$currmaptitle);
                           my $arrowstate = 'open';
                           if (keys(%{$statusbymap{$currmap}}) == 1) {
                               $arrowstate = 'closed';
                           }
                           $row .= '<td>'.$spacers.'<img src="/adm/lonIcons/arrow.'.$arrowstate.'.gif" '.
                                   'id="arrow'.$mapnum.'" '.'alt="arrow" onmouseover="this.style.cursor=\'pointer\'" '.
                                   'onclick="'."toggleSlotMap('$mapnum','$rownum');".'" />'.
                                   $icon.('&nbsp;' x6).'</td>'."\n";
                           if (ref($output{$currmap}) eq 'HASH') {
                               my $formnum = $mapnum.'_'.$reservable+1;
                               my $class = 'LC_slotmaptext_'.$mapnum;
                               if ($output{$currmap}{'hasaction'}) {
                                   $row .= '<td valign="top"><span class="'.$class.'">'.
                                             $output{$currmap}{'msg'}.
                                             '</span></td><td valign="top">'.
                                             &slot_chooser($repsymbs{$currmap},$class,$formnum,
                                                           $allavailable,$slots,$consumed_uniqueperiods).
                                             '</td>';
                               } else {
                                   $row .= '<td colspan="2" valign="middle"><span class="'.$class.'">'.
                                             $output{$currmap}{'msg'}.
                                             '</span></td>';
                               }
                               $row .= '</tr>'."\n";
                           } else {
                               $row .= '<td colspan="2">&nbsp;</td></tr>'."\n";
                           }
                       } else {
                           my ($spacers,$icon) = &show_map_row($depth,$location,$currmaptype,$currmaptitle);
                           $row .= '<td>'.$spacers.$icon.('&nbsp;' x6).'</td><td colspan="2">&nbsp;</td></tr>'."\n";
                       }
                       $r->print($row);
                   }
               }
           } elsif ($resource == $it->END_MAP()) {
               $depth--;
               $currcontainer = $parent{$depth};
           } elsif (ref($resource)) {
               my $symb = $resource->symb();
               next if (!$resource->is_problem() && !$resource->is_tool() &&
                        !$resource->is_sequence() && !$resource->is_page());
               $count ++;
               if (($resource->is_sequence()) || ($resource->is_page())) {
                   $currcontainer = $count;
                   $container{$currcontainer} = $resource;
                   $container_title{$currcontainer} = $resource->compTitle();
               }
               if ($resource->is_problem() || $resource->is_tool()) {
                   next unless (exists($output{$symb}));
                   $reservable ++;
                   $rownum ++;
                   if (!$shownheader) {
                       $r->print($slotheader);
                       $shownheader = 1;
                   }
                   my $style;
                   if (exists($output{$currmap})) {
                       $style = 'none';
                   } else {
                       $style = 'table-row';
                       $shown ++;
                   }
                   my $title = $resource->compTitle();
                   my $bgcolor = $backgrounds[$shown % $numcolors];
                   $r->print('<tr class="'.$bgcolor.' LC_slotresrow_'.$mapnum.'"'.
                             ' style="display:'.$style.'" id="LC_slotresrow_'.$rownum.'">'.
                             '<td>');
                   for (my $i=0; $i<$depth; $i++) {
                       $r->print('<img src="'.$location.'" alt="" />');
                   }
                   $r->print('<a href="'.$resource->src().'?symb='.$symb.'">'.
                             '<img class="LC_contentImage" src="/adm/lonIcons/');
                   if ($resource->is_task()) {
                       $r->print('task.gif" alt="'.&mt('Task'));
                   } elsif ($resource->is_tool()) {
                       $r->print('unknown.gif" alt="'.&mt('External Tool'));
                   } else {
                       $r->print('problem.gif" alt="'.&mt('Problem'));
                   }
                   $r->print('" /><b>'.$title.'</b></a>'.('&nbsp;' x6).'</td>');
                   my $class = 'LC_slottext_'.$mapnum;
                   if ($output{$symb}{'hasaction'}) {
                       $r->print('<td valign="top"><span class="'.$class.'">'.$output{$symb}{'msg'}.'</span></td>'.
                                 '<td valign="top">'.
                                 &slot_chooser($symb,$class,$reservable,$allavailable,$slots,
                                               $consumed_uniqueperiods).'</td>');
                   } else {
                       $r->print('<td colspan="2" valign="middle">'.
                                 '<span class="'.$class.'">'.$output{$symb}{'msg'}.'</span>'.
                                 '</td>');
                   }
                   $r->print('</tr>'."\n");
               }
           }
       }
       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) = @_;
       my $spacers;
       for (my $i=0; $i<$depth-1; $i++) {
           $spacers .= '<img src="'.$location.'" alt="" />';
       }
       my $icon;
       if ($type eq 'page') {
           $icon = '<img src="/adm/lonIcons/navmap.page.open.gif" alt="" />&nbsp;'."\n";
       } else {
           $icon = '<img src="/adm/lonIcons/navmap.folder.open.gif" alt="" />&nbsp;'."\n";
       }
       $icon .= $title;
       return ($spacers,$icon);
   }
   
   sub slot_chooser {
       my ($symb,$class,$formnum,$allavailable,$slots,$consumed_uniqueperiods) = @_;
       my $output;
       my @got_slots=&check_for_reservation($symb,'allslots');
       if ($got_slots[0] =~ /^error: /) {
           $output = '<span class="'.$class.'"><span class="LC_error">'.
                     &mt('An error occurred determining slot availability.').
                     '</span></span>';
       } else {
           my $formname = 'manageres_'.$formnum;
           if (ref($allavailable) eq 'ARRAY') {
               my @available;
               if (ref($slots) eq 'HASH') {
                   foreach my $slot (@{$allavailable}) {
                       # not allowed for this resource
                       if (ref($slots->{$slot}) eq 'HASH') {
                           if ($slots->{$slot}->{'symb'} ne '') {
                               my ($map,$id,$url) = &Apache::lonnet::decode_symb($symb);
                               my $exclude = 1;
                               my @reqsymbs = split(/\s*,\s*/,$slots->{$slot}->{'symb'});
                               if (@reqsymbs) {
                                   if (grep(/^\Q$symb\E$/,@reqsymbs)) {
                                       $exclude = 0;
                                   } else {
                                       foreach my $reqsymb (@reqsymbs) {
                                           my (undef,undef,$sloturl) = &Apache::lonnet::decode_symb($reqsymb);
                                           if ($sloturl=~/\.(page|sequence)$/) {
                                               if (($map ne '') && ($map eq $sloturl)) {
                                                   $exclude = 0;
                                                   last;
                                               }
                                           }
                                       }
                                   }
                                   next if ($exclude);   
                               }
                           }
                       }
                       push(@available,$slot);
                   }
               }
               $output .= &show_choices($symb,$formname,$formnum,$class,
                                        $slots,$consumed_uniqueperiods,
                                        \@available,\@got_slots);
           }
       }
       return $output;
   }
   
   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 ($cnum,$cdom)=&get_course();
       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('<p>');
               if ($curr{'page'} > 1) {
                   $r->print('<input type="button" onclick="javascript:chgPage('."'previous'".');" value="'.
                             &mt('Previous [_1] changes',$curr{'show'}).'" />');
               }
               if ($more_records) {
                   $r->print('<input type="button" onclick="javascript:chgPage('."'next'".');" value="'.
                             &mt('Next [_1] changes',$curr{'show'}).'" />');
               }
               $r->print('</p>');
               $r->print(<<"ENDSCRIPT");
   <script type="text/javascript">
   // <![CDATA[
   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 ($cnum,$cdom)=&get_course();
       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('<p>');
               if ($curr{'page'} > 1) {
                   $r->print('<input type="button" onclick="javascript:chgPage('."'previous'".');" value="'.
                             &mt('Previous [_1] changes',$curr{'show'}).'" />');
               }
               if ($more_records) {
                   $r->print('<input type="button" onclick="javascript:chgPage('."'next'".');" value="'.
                             &mt('Next [_1] changes',$curr{'show'}).'" />');
               }
               $r->print('</p>');
               $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 Content');
                   } 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></tr></table>'.
                  '<p><input type="submit" value="'.
                  &mt('Update Display').'" /></p>'.
                  '<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>'.         .'<h2>'.&mt('Upload a file containing the slot definitions').'</h2>'
  &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 1278  sub csvuploadmap_header { Line 3061  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 $buttontext = &mt('Reverse Association');
   
       $r->print(
           '<form method="post" enctype="multipart/form-data" action="/adm/slotrequest" name="slotupload">'
          .'<h2>'.&mt('Identify fields in uploaded list').'</h2>'
          .'<div class="LC_columnSection">'
          .&Apache::loncommon::help_open_topic(
               'Slot About',&mt('Help on slots'))
          .' '.&Apache::loncommon::help_open_topic(
               'Slot SelectingField',&mt('Help on selecting Fields'))
          ."</div>\n"
          .'<p class="LC_info">'
          .&mt('Total number of records found in file: [_1]','<b>'.$distotal.'</b>')
          ."</p>\n"
       );
       if ($distotal == 0) {
           $r->print('<p class="LC_warning">'.&mt('None found').'</p>');
       }
       $r->print(
           '<p>'
          .&mt('Enter as many fields as you can.').'<br />'
          .&mt('The system will inform you and bring you back to this page,[_1]if the data selected is insufficient to create the slots.','<br />')
          .'</p>'
       );
       $r->print(
           '<div class="LC_left_float">'
          .'<fieldset><legend>'.&mt('Functions').'</legend>'
          .'<label><input type="checkbox" name="noFirstLine"'.$checked.' />'.$ignore.'</label>'
          .' <input type="button" value="'.$buttontext
              .'" onclick="javascript:this.form.associate.value=\'Reverse Association\';submit(this.form);" />'
          .'</fieldset></div><br clear="all" />'
       );
   
     $r->print(<<ENDPICK);      $r->print(<<ENDPICK);
 <form method="post" enctype="multipart/form-data" action="/adm/slotrequest" name="slotupload">  
 <h3>Identify fields</h3>  
 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  
 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);" />  
 <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 1293  to this page if the data selected is ins Line 3102  to this page if the data selected is ins
 <input type="hidden" name="upfile_associate"   <input type="hidden" name="upfile_associate" 
                                        value="$env{'form.upfile_associate'}" />                                         value="$env{'form.upfile_associate'}" />
 <input type="hidden" name="command"    value="csvuploadassign" />  <input type="hidden" name="command"    value="csvuploadassign" />
 <hr />  
 <script type="text/javascript" language="Javascript">  <script type="text/javascript" language="Javascript">
   // <![CDATA[
 $javascript  $javascript
   // ]]>
 </script>  </script>
 ENDPICK  ENDPICK
     return '';      return '';
Line 1304  ENDPICK Line 3114  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>  
 <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
 }  }
   
 sub csvupload_javascript_reverse_associate {  sub csvupload_javascript_reverse_associate {
     my $error1=&mt('You need to specify the name, starttime, endtime and a type');      my $error1=&mt('You need to specify the name, start time, end time and a type.');
     return(<<ENDPICK);      return(<<ENDPICK);
   function verify(vf) {    function verify(vf) {
     var foundstart=0;      var foundstart=0;
Line 1340  ENDPICK Line 3150  ENDPICK
 }  }
   
 sub csvupload_javascript_forward_associate {  sub csvupload_javascript_forward_associate {
     my $error1=&mt('You need to specify the name, starttime, endtime and a type');      my $error1=&mt('You need to specify the name, start time, end time and a type.');
   return(<<ENDPICK);    return(<<ENDPICK);
   function verify(vf) {    function verify(vf) {
     var foundstart=0;      var foundstart=0;
Line 1372  sub csv_upload_map { Line 3182  sub csv_upload_map {
     if (!$env{'form.datatoken'}) {      if (!$env{'form.datatoken'}) {
  $datatoken=&Apache::loncommon::upfile_store($r);   $datatoken=&Apache::loncommon::upfile_store($r);
     } else {      } else {
  $datatoken=$env{'form.datatoken'};          $datatoken=&Apache::loncommon::valid_datatoken($env{'form.datatoken'});
  &Apache::loncommon::load_tmp_file($r);          if ($datatoken ne '') {
               &Apache::loncommon::load_tmp_file($r,$datatoken);
           }
     }      }
     my @records=&Apache::loncommon::upfile_record_sep();      my @records=&Apache::loncommon::upfile_record_sep();
     if ($env{'form.noFirstLine'}) { shift(@records); }      if ($env{'form.noFirstLine'}) { shift(@records); }
Line 1407  sub csvupload_fields { Line 3219  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'],
               ['iptied','Unique IP each student'],
     ['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(s)/Map(s) 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'],      ['allowedsections','Sections slot is restricted to'],
Line 1421  sub csvupload_fields { Line 3236  sub csvupload_fields {
   
 sub csv_upload_assign {  sub csv_upload_assign {
     my ($r,$mgr)= @_;      my ($r,$mgr)= @_;
     &Apache::loncommon::load_tmp_file($r);      my $datatoken = &Apache::loncommon::valid_datatoken($env{'form.datatoken'});
       if ($datatoken ne '') {
           &Apache::loncommon::load_tmp_file($r,$datatoken);
       }
     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 1479  sub csv_upload_assign { Line 3297  sub csv_upload_assign {
  }   }
   
  if ($entries{$fields{'startreserve'}}) {   if ($entries{$fields{'startreserve'}}) {
     $slot{'startreserve'}=              my $date = &UnixDate($entries{$fields{'startreserve'}},"%s");
  &UnixDate($entries{$fields{'startreserve'}},"%s");              if ($date eq '') {
                   push(@errors,"$name -- No reservation start time set for slot -- value provided had invalid format");
               } else {
                   $slot{'startreserve'} = $date;
               }
  }   }
  if (defined($slot{'startreserve'})   if (defined($slot{'startreserve'})
     && $slot{'startreserve'} > $slot{'starttime'}) {      && $slot{'startreserve'} > $slot{'starttime'}) {
Line 1488  sub csv_upload_assign { Line 3310  sub csv_upload_assign {
     next;      next;
  }   }
   
           if ($entries{$fields{'endreserve'}}) {
               my $date = &UnixDate($entries{$fields{'endreserve'}},"%s");
               if ($date eq '') {
                   push(@errors,"$name -- No reservation end time set for slot -- value provided had invalid format");
               } else {
                   $slot{'endreserve'} = $date;
               }
           }
           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 ($key eq 'maxspace') {
                       $slot{$key} =~ s/\D+//g;
                   }
     }      }
  }   }
           if ($entries{$fields{'iptied'}} =~ /^\s*(yes|1)\s*$/i) {
               $slot{'iptied'}='yes'; 
           } elsif ($entries{$fields{'iptied'}} =~ /^\s*answer\s*$/i) {
               $slot{'iptied'}='answer';
           }
           if ($entries{$fields{'allowedusers'}}) {
               $entries{$fields{'allowedusers'}} =~ s/^\s+//;
               $entries{$fields{'allowedusers'}} =~ s/\s+$//;
               my @allowedusers;
               foreach my $poss (split(/\s*,\s*/,$entries{$fields{'allowedusers'}})) {
                   my ($possuname,$possudom) = split(/:/,$poss);
                   if (($possuname =~ /^$match_username$/) && ($possudom =~ /^$match_domain$/)) {
                       unless (grep(/^\Q$poss\E$/,@allowedusers)) {
                           push(@allowedusers,$poss);
                       }
                   }
               }
               if (@allowedusers > 0) {
                   $slot{'allowedusers'} = join(',',@allowedusers);
               }
           }
           if ($entries{$fields{'allowedsections'}}) {
               $entries{$fields{'allowedsections'}} =~ s/^\s+//;
               $entries{$fields{'allowedsections'}} =~ s/\s+$//;
               my @allowedsections;
               foreach my $poss (split(/\s*,\s*/,$entries{$fields{'allowedsections'}})) {
                   if (($poss !~ /\W/) && ($poss ne 'none')) {
                       unless (grep(/^\Q$poss\E$/,@allowedsections)) {
                           push(@allowedsections,$poss);
                       }
                   }
               }
               if (@allowedsections > 0) {
                   $slot{'allowedsections'} = join(',',@allowedsections);
               }
           }
  if ($entries{$fields{'uniqueperiod'}}) {   if ($entries{$fields{'uniqueperiod'}}) {
     my ($start,$end)=split(',',$entries{$fields{'uniqueperiod'}});              my ($start,$end)= map { &UnixDate($_,"%s"); } split(',',$entries{$fields{'uniqueperiod'}});
     my @times=(&UnixDate($start,"%s"),              if (($start ne '') && ($end ne '')) {
        &UnixDate($end,"%s"));                  $slot{'uniqueperiod'}=[$start,$end];
     $slot{'uniqueperiod'}=\@times;              } else {
                   push(@errors,"$name -- Slot's unique period ignored -- one or both of the comma separated values for start and end had an invalid format");
               }
  }   }
  if (defined($slot{'uniqueperiod'})   if (ref($slot{'uniqueperiod'}) eq 'ARRAY' 
     && $slot{'uniqueperiod'}[0] > $slot{'uniqueperiod'}[1]) {      && $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.");      push(@errors,"$name not created -- Slot's unique period start time is later than the unique period's end time.");
     next;      next;
Line 1512  sub csv_upload_assign { Line 3402  sub csv_upload_assign {
  $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 1531  sub handler { Line 3450  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,$bread_crumbs_component);
   
     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'});
       my (%slots,$consumed_uniqueperiods);
       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.requestattempt'}) || ($env{'form.command'} eq 'manageresv')) {  
           if ($env{'form.command'} eq 'manageresv') {
               $title = 'Manage Reservations';
               $brcrum =[{href=>"/adm/slotrequest?command=manageresv",text=>$title}];
           }
           my ($cnum,$cdom)=&get_course();
           %slots = &Apache::lonnet::get_course_slots($cnum,$cdom);
           $consumed_uniqueperiods = &get_consumed_uniqueperiods(\%slots);
       } 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'},
                          help=>'Slot_Use'}];
       $title = 'Managing Slots';
               $bread_crumbs_component = '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);      my ($symb,$js,$available,$allavailable,$got_slots);
       $available = [];
     if ($env{'form.command'} eq 'showslots' && $vgr eq 'F') {      if ($env{'form.requestattempt'}) {
           $symb=&unescape($env{'form.symb'});
           @{$got_slots}=&check_for_reservation($symb,'allslots');
       }
       if (($env{'form.requestattempt'}) || ($env{'form.command'} eq 'manageresv')) {
           $js = &reservation_js(\%slots,$consumed_uniqueperiods,$available,$got_slots,$symb);
       }
       &start_page($r,$title,$brcrum,$bread_crumbs_component,$js,$mgr);
   
       if ($env{'form.command'} eq 'manageresv') {
           $allavailable = $available;
           undef($available);
           undef($got_slots);
           my $crstype = &Apache::loncommon::course_type();
           &manage_reservations($r,$crstype,\%slots,$consumed_uniqueperiods,$allavailable);
       } elsif ($env{'form.command'} eq 'showresv') {
           &show_reservations($r,$env{'form.uname'},$env{'form.udom'});
       } elsif ($env{'form.command'} eq 'showslots' && $vgr eq 'F') {
  &show_table($r,$mgr);   &show_table($r,$mgr);
     } elsif ($env{'form.command'} eq 'remove_registration' && $mgr eq 'F') {      } elsif ($env{'form.command'} eq 'remove_registration' && $mgr eq 'F') {
  &remove_registration($r);   &remove_registration($r);
Line 1567  sub handler { Line 3556  sub handler {
     }      }
     &csv_upload_map($r);      &csv_upload_map($r);
  }   }
       } elsif (($env{'form.command'} eq 'slotlog') && ($vgr eq 'F')) {
           &show_reservations_log($r);
     } else {      } else {
  my $symb=&unescape($env{'form.symb'});   my $symb=&unescape($env{'form.symb'});
  if (!defined($symb)) {   if (!defined($symb)) {
Line 1587  sub handler { Line 3578  sub handler {
  my ($status) = &Apache::lonhomework::check_slot_access('0',$type);   my ($status) = &Apache::lonhomework::check_slot_access('0',$type);
  if ($status eq 'CAN_ANSWER' ||   if ($status eq 'CAN_ANSWER' ||
     $status eq 'NEEDS_CHECKIN' ||      $status eq 'NEEDS_CHECKIN' ||
     $status eq 'WAITING_FOR_GRADE') {      $status eq 'WAITING_FOR_GRADE' ||
               $status eq 'NEED_DIFFERENT_IP') {
     &fail($r,'not_allowed');      &fail($r,'not_allowed');
     return OK;      return OK;
  }   }
  if ($env{'form.requestattempt'}) {   if ($env{'form.requestattempt'}) {
     &show_choices($r,$symb);              $r->print('<div class="LC_left_float">'); 
       $r->print(&show_choices($symb,undef,undef,undef,\%slots,$consumed_uniqueperiods,$available,$got_slots));
               $r->print('</div><div style="padding:0;clear:both;margin:0;border:0"></div>');
  } elsif ($env{'form.command'} eq 'release') {   } elsif ($env{'form.command'} eq 'release') {
     &release_slot($r,$symb);      &release_slot($r,$symb);
  } 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.69  
changed lines
  Added in v.1.146


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.