Diff for /loncom/interface/slotrequest.pm between versions 1.102 and 1.125.2.3.4.2

version 1.102, 2009/08/13 10:24:29 version 1.125.2.3.4.2, 2020/04/08 20:06:59
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,$brcrum)=@_;      my ($r,$title,$brcrum,$js)=@_;
     my $args;      my $args;
     if (ref($brcrum) eq 'ARRAY') {      if (ref($brcrum) eq 'ARRAY') {
         $args = {bread_crumbs => $brcrum};          $args = {bread_crumbs => $brcrum};
     }      }
     $r->print(&Apache::loncommon::start_page($title,undef,$args));      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 };
           }
       }
       $r->print(&Apache::loncommon::start_page($title,$js,$args));
 }  }
   
 sub end_page {  sub end_page {
Line 69  sub end_page { Line 79  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;  
           }
       }
   }
   // ]]>
   </script>
   ENDSCRIPT
   
   }
   
   
 =pod  =pod
   
  slot_reservations db   slot_reservations db
Line 121  sub check_for_reservation { Line 319  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 137  sub check_for_reservation { Line 334  sub check_for_reservation {
  return 'error: Unable to determine current status';   return 'error: Unable to determine current status';
     }          }    
     my @got;      my @got;
     my @sorted_slots = &Apache::loncommon::sorted_slots(\@slots,\%slots);      my @sorted_slots = &Apache::loncommon::sorted_slots(\@slots,\%slots,'starttime');
     foreach my $slot_name (@sorted_slots) {      foreach my $slot_name (@sorted_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 214  sub check_for_conflict { Line 415  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 (ref($consumed_uniqueperiods) eq 'HASH') {              return $consumed_uniqueperiods;
     if (&Apache::lonnet::error(%$consumed_uniqueperiods)) {  
         return 'error: Unable to determine current status';  
     }  
         } else {          } else {
             return 'error: Unable to determine current status';      $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 252  sub make_reservation { Line 456  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 299  sub make_reservation { Line 503  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 311  sub make_reservation { Line 515  sub make_reservation {
  if ($value) {   if ($value) {
     $new_value=$value.':'.$new_value;      $new_value=$value.':'.$new_value;
  }   }
         &store_slot_parm($symb,$slot_name,$parm_level,$new_value,$cnum,$cdom);          my $result = &store_slot_parm($symb,$symb_for_db,$slot_name,$parm_level,
                                         $new_value,$cnum,$cdom,$env{'user.name'},
                                         $env{'user.domain'},'reserve',$env{'form.context'});
  return $wanted;   return $wanted;
     }      }
   
Line 320  sub make_reservation { Line 526  sub make_reservation {
 }  }
   
 sub store_slot_parm {  sub store_slot_parm {
     my ($symb,$slot_name,$parm_level,$new_value,$cnum,$cdom) = @_;      my ($symb_for_parm,$symb_for_db,$slot_name,$parm_level,$new_value,
     my $result=&Apache::lonparmset::storeparm_by_symb($symb,          $cnum,$cdom,$uname,$udom,$action,$context,$delflag) = @_;
                                                   '0_availablestudent',  
                                                    $parm_level, $new_value,      # store new parameter string
                                                    'string',      my $result=&Apache::lonparmset::storeparm_by_symb($symb_for_parm,
                                                    $env{'user.name'},                                                        '0_availablestudent',
                                                    $env{'user.domain'});                                                        $parm_level,$new_value,
                                                         'string',$uname,$udom);
     &Apache::lonxml::debug("hrrm $result");      &Apache::lonxml::debug("hrrm $result");
     my %storehash = (      my %storehash = (
                        symb    => $symb,                         symb    => $symb_for_db,
                        slot    => $slot_name,                         slot    => $slot_name,
                        action  => 'reserve',                         action  => $action,
                        context => $env{'form.context'},                         context => $context,
                     );                      );
   
     &Apache::lonnet::instructor_log('slotreservationslog',\%storehash,      &Apache::lonnet::write_log('course','slotreservationslog',\%storehash,
                                     '',$env{'user.name'},$env{'user.domain'},                                 $delflag,$uname,$udom,$cnum,$cdom);
                                     $cnum,$cdom);      &Apache::lonnet::write_log('course',$cdom.'_'.$cnum.'_slotlog',\%storehash,
     &Apache::lonnet::instructor_log($cdom.'_'.$cnum.'_slotlog',\%storehash,                                 $delflag,$uname,$udom,$uname,$udom);
                                     1,$env{'user.name'},$env{'user.domain'},      return $result;
                                     $env{'user.name'},$env{'user.domain'});  
   
     return;  
 }  }
   
 sub remove_registration {  sub remove_registration {
Line 438  sub release_all_slot { Line 642  sub release_all_slot {
     &release_reservation($slot_name,$uname,$udom,      &release_reservation($slot_name,$uname,$udom,
  $consumed{$entry}{'symb'},$mgr);   $consumed{$entry}{'symb'},$mgr);
         if (!$result) {          if (!$result) {
             $r->print('<p><span class="LC_error">'.&mt($msg).'</span></p>');              $r->print('<p class="LC_error">'.&mt($msg).'</p>');
         } else {          } else {
     $r->print("<p>$msg</p>");      $r->print("<p>$msg</p>");
         }          }
Line 468  sub release_slot { Line 672  sub release_slot {
     my ($result,$msg) =      my ($result,$msg) =
  &release_reservation($slot_name,$uname,$udom,$symb,$mgr);   &release_reservation($slot_name,$uname,$udom,$symb,$mgr);
     if (!$result) {      if (!$result) {
         $r->print('<p><span class="LC_error">'.&mt($msg).'</span></p>');          $r->print('<p class="LC_error">'.&mt($msg).'</p>');
     } else {      } else {
         $r->print("<p>$msg</p>");          $r->print("<p>$msg</p>");
     }      }
Line 486  sub release_reservation { Line 690  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));
  }   }
     }      }
       my $context = $env{'form.context'};
   
     # if the reservation symb is for a map get a resource in that map      # get navmap object
     # to check slot parameters on  
     my $navmap=Apache::lonnavmaps::navmap->new;      my $navmap=Apache::lonnavmaps::navmap->new;
     if (!defined($navmap)) {      if (!defined($navmap)) {
         return (0,'error: Unable to determine current status');          return (0,'error: Unable to determine current status');
     }      }
     my $passed_resource = $navmap->getBySymb($symb);  
     if ($passed_resource->is_map()) {      my ($cnum,$cdom)=&get_course();
  my ($a_resource) =   
     $navmap->retrieveResources($passed_resource,       # get slot reservations, check if user has reservation
        sub {$_[0]->is_problem()},0,1);      my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
  $symb = $a_resource->symb();                                         "^$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);
           }
     }      }
   
     # get parameter string, check for existance, rebuild string with the slot      my $map_symb;
     my $student = &Apache::lonnet::EXT("resource.0.availablestudent",      my $parm_symb = $symb;
                                        $symb,$udom,$uname);      my $passed_resource = $navmap->getBySymb($symb);
     my @slots = split(/:/,$student);  
   
     my @new_slots;      # if the reservation symb is for a map get a resource in that map
     foreach my $exist_slot (@slots) {      # to check slot parameters on
  if ($exist_slot eq $slot_name) { next; }      my $parm_level = 1;
  push(@new_slots,$exist_slot);      if (ref($passed_resource)) {
           if ($passed_resource->is_map()) {
       my ($a_resource) = 
                   $navmap->retrieveResources($passed_resource, 
                                              sub {$_[0]->is_problem()},0,1);
               $parm_symb = $a_resource->symb();
           }
       } else {
           unless ($mgr eq 'F') {
               return (0,'error: Unable to determine current status');
           }
     }      }
     my $new_param = join(':',@new_slots);  
   
     my ($cnum,$cdom)=&get_course();      # 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.
   
     # get slot reservations, check if user has one, if so remove reservation      my $use_slots = &Apache::lonnet::EXT('resource.0.useslots',
     my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,                                           $parm_symb,$udom,$uname);
        "^$slot_name\0");      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],
             my %storehash = (                                           $cdom,$cnum) eq 'ok') {
                                symb    => $symb,                      $match = $symb_to_check;
                                slot    => $slot_name,                  }
                                action  => 'release',                  last;
                                context => $env{'form.context'},              }
                         );          }
             &Apache::lonnet::instructor_log('slotreservationslog',\%storehash,  
                                             1,$uname,$udom,$cnum,$cdom);  
             &Apache::lonnet::instructor_log($cdom.'_'.$cnum.'_slotlog',\%storehash,  
                                             1,$uname,$udom,$uname,$udom);  
  }  
     }      }
       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,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,$udom,$uname);                                           $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,      my @slots = split(/:/,$student);
       '0_availablestudent',  
       $parm_level, $new_param,      my @new_slots;
       'string', $uname, $udom);      foreach my $exist_slot (@slots) {
     my $msg;          next if ($exist_slot eq $slot_name);
     if ($mgr eq 'F') {          push(@new_slots,$exist_slot);
  $msg = &mt('Released Reservation for user: [_1]',"$uname:$udom");  
     } else {  
  $msg = &mt('Released Reservation: [_1]',$description);  
     }      }
     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 586  sub delete_slot { Line 1022  sub delete_slot {
  if ($ret eq 'ok') {   if ($ret eq 'ok') {
     $r->print('<p>'.&mt('Slot [_1] marked as deleted.','<tt>'.$slot_name.'</tt>').'</p>');      $r->print('<p>'.&mt('Slot [_1] marked as deleted.','<tt>'.$slot_name.'</tt>').'</p>');
  } else {   } else {
     $r->print('<p><span class="LC_error">'.&mt('An error occurred when attempting to delete slot: [_1]','<tt>'.$slot_name.'</tt>')." ($ret)</span></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) {
Line 618  sub get_slot { Line 1054  sub get_slot {
     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><span class="LC_error">'   $r->print('<p class="LC_error">'
                  .&mt('An error occurred while attempting to make a reservation. ([_1])',$1)                   .&mt('An error occurred while attempting to make a reservation. ([_1])',$1)
                  .'</span></p>');                   .'</p>');
  &return_link($r);   &return_link($r);
  return 0;   return 0;
     }      }
     if ($slot_name && $slot_name ne $conflictable_slot) {      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>'.&mt('Already have a reservation: [_1].',$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 638  sub get_slot { Line 1079  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>'              $r->print('<p class="LC_error">'.&mt('Reservation currently unchanged').'</p>');
                      .&mt('You can either [_1]Change[_2] your reservation from [_3] to [_4] or'              if ($slot_name ne '') {
                          ,'<input type="submit" name="change" value="'                  $r->print('<p>'.&mt('To complete the transaction you [_1]must confirm[_2] you want to [_3]process the change[_4] to [_5].'
                          ,'" />'                           ,'<b>','</b>','<i>','</i>','<b>'.$description2.'</b>')
                          ,'<b>'.$description1.'</b>'                           .'<br />'
                          ,'<b>'.$description2.'</b>')                           .&mt('Or you can choose to [_1]make no change[_2] and continue[_2] with the reservation you already had: [_3].'
                      .'<br /></p>'                           ,'<i>','</i>','<b>'.$description1.'</b>')
             );                           .'</p><p><span class="LC_nobreak">'
     &return_link($r);                           .'<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 0;   return 0;
Line 663  STUFF Line 1109  STUFF
     if (defined($reserved)) {      if (defined($reserved)) {
  my $retvalue = 0;   my $retvalue = 0;
  if ($slot_name =~ /^error: (.*)/) {   if ($slot_name =~ /^error: (.*)/) {
     $r->print('<p><span class="LC_error">'      $r->print('<p class="LC_error">'
                      .&mt('An error occurred while attempting to make a reservation. ([_1])',$1)                       .&mt('An error occurred while attempting to make a reservation. ([_1])',$1)
                      .'</span></p>');                       .'</p>');
  } elsif ($reserved > -1) {   } elsif ($reserved > -1) {
     $r->print('<p>'.&mt('Success: [_1]',$description).'</p>');      $r->print('<p style="font-weight: bold;">'.&mt('Successfully signed up:  [_1]',$description).'</p>');
     $retvalue = 1;      $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>'.&mt('Already reserved: [_1]',$description).'</p>');      $r->print('<p>'.&mt('Already reserved: [_1]',$description).'</p>');
  }   }
Line 677  STUFF Line 1130  STUFF
     }      }
   
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
         'request' => 'Availibility list',          'request' => 'Availability list',
         'try'     => 'Try again?',          'try'     => 'Try again?',
         'or'      => 'or',          'or'      => 'or',
     );      );
Line 716  STUFF Line 1169  STUFF
 }  }
   
 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) {
Line 741  sub allowed_slot { Line 1194  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 787  sub allowed_slot { Line 1245  sub allowed_slot {
     # not allowed for this resource      # not allowed for this resource
     if (defined($slot->{'symb'})      if (defined($slot->{'symb'})
  && $slot->{'symb'} ne $symb) {   && $slot->{'symb'} ne $symb) {
  return 0;          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,
Line 815  sub get_description { Line 1275  sub get_description {
 }  }
   
 sub show_choices {  sub show_choices {
     my ($r,$symb,$formname)=@_;      my ($r,$symb,$formname,$num,$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);  
     if (ref($consumed_uniqueperiods) eq 'HASH') {  
         if (&Apache::lonnet::error(%$consumed_uniqueperiods)) {  
             $r->print('<span class="LC_error">'.  
                       &mt('An error occurred determining slot availability').  
                       '</span>');  
             return;  
         }  
     } elsif ($consumed_uniqueperiods =~ /^error: /) {  
         $r->print('<span class="LC_error">'.  
                   &mt('An error occurred determining slot availability').  
                   '</span>');  
         return;  
     }  
     my (@available,$output);  
     &Apache::lonxml::debug("Checking Slots");      &Apache::lonxml::debug("Checking Slots");
     my @got_slots=&check_for_reservation($symb,'allslots');      if (!ref($available) eq 'ARRAY') {
     if ($got_slots[0] =~ /^error: /) {  
         $r->print('<span class="LC_error">'.  
                   &mt('An error occurred determining slot availability').  
                   '</span>');  
         return;          return;
     }      }
     foreach my $slot (sort       if (!@{$available}) {
       { return $slots{$a}->{'starttime'} <=> $slots{$b}->{'starttime'} }          $output = '<span class="LC_info">'.&mt('No available times.').'</span>';
       (keys(%slots)))  {  
   
  &Apache::lonxml::debug("Checking Slot $slot");  
  next if (!&allowed_slot($slot,$slots{$slot},undef,\%slots,  
  $consumed_uniqueperiods));  
   
         push(@available,$slot);  
     }  
     if (!@available) {  
         $output = &mt('No available times.');  
         if ($env{'form.command'} ne 'manageresv') {          if ($env{'form.command'} ne 'manageresv') {
             $output .= ' <a href="/adm/flip?postdata=return:">'.              $output .= ' <a href="/adm/flip?postdata=return:">'.
                        &mt('Return to last resource').'</a>';                         &mt('Return to last resource').'</a>';
Line 861  sub show_choices { Line 1290  sub show_choices {
         $r->print($output);          $r->print($output);
         return;          return;
     }      }
       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>
   
   ENDSCRIPT
           }
           $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') {      if ($env{'form.command'} eq 'manageresv') {
         $output = '<table border="0">';          $output .= '<table border="0">';
     } else {      } else {
         $output = &Apache::loncommon::start_data_table();          $output .= &Apache::loncommon::start_data_table();
     }      }
     foreach my $slot (@available) {       foreach my $slot (@{$available}) {
  my $description=&get_description($slot,$slots{$slot});   my $description=&get_description($slot,$slots->{$slot});
  my $form;   my $form;
  if ((grep(/^\Q$slot\E$/,@got_slots)) ||   if ((grep(/^\Q$slot\E$/,@{$got_slots})) ||
     &space_available($slot,$slots{$slot},$symb)) {      &space_available($slot,$slots->{$slot},$symb)) {
     my $text=&mt('Select');      my $text=&mt('Select');
     my $command='get';      my $command='get';
     if (grep(/^\Q$slot\E$/,@got_slots)) {      if (grep(/^\Q$slot\E$/,@{$got_slots})) {
  $text=&mt('Drop 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: /) {                      if ($conflict =~ /^error: /) {
                         $form = '<span class="LC_error">'.                          $form = '<span class="LC_error">'.
                                 &mt('Slot: [_1] has unknown status.',$description).                                   &mt('Slot: [_1] has unknown status.',$description).
                                 '</span>';                                   '</span>';
                     } else {                      } else {
         $text=&mt('Change Reservation');          $text=&mt('Change Reservation');
         $command='get';          $command='get';
Line 893  sub show_choices { Line 1393  sub show_choices {
     }      }
     my $escsymb=&escape($symb);      my $escsymb=&escape($symb);
             if (!$form) {              if (!$form) {
                   my $name;
                 if ($formname) {                  if ($formname) {
                     $formname = 'name="'.$formname.'" ';                       $name = 'name="'.$formname.'"';
                 }                  }
                 my $context = 'user';                  my $context = 'user';
                 if ($env{'form.command'} eq 'manageresv') {                  if ($env{'form.command'} eq 'manageresv') {
                     $context = 'usermanage';                      $context = 'usermanage';
                 }                  }
         $form=<<STUFF;          $form=<<STUFF;
    <form method="post" action="/adm/slotrequest" $formname>     <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" />
Line 914  STUFF Line 1415  STUFF
             $form = &mt('Unavailable');              $form = &mt('Unavailable');
         }          }
         if ($env{'form.command'} eq 'manageresv') {          if ($env{'form.command'} eq 'manageresv') {
             $output .= '<tr>';              $output .= '<tr id="LC_slotrow_'.$num.'_'.$slot.'" >';
         } else {          } else {
     $output .= &Apache::loncommon::start_data_table_row();      $output .= &Apache::loncommon::start_data_table_row('','LC_slotrow_'.$num.'_'.$slot);
         }          }
         $output .= "           $output .= " 
  <td>$form</td>   <td>$form</td>
Line 930  STUFF Line 1431  STUFF
     if ($env{'form.command'} eq 'manageresv') {      if ($env{'form.command'} eq 'manageresv') {
         $output .= '</table>';          $output .= '</table>';
     } else {      } else {
        $output .= &Apache::loncommon::end_data_table();          $output .= &Apache::loncommon::end_data_table();
       }
       if (@{$available} > 1) {
           $output .= '</div></fieldset>';
     }      }
     $r->print($output);      $r->print($output);
       return;
 }  }
   
 sub to_show {  sub to_show {
Line 1026  sub show_table { Line 1531  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 1033  sub show_table { Line 1539  sub show_table {
     my $available;      my $available;
     if ($mgr eq 'F') {      if ($mgr eq 'F') {
     # FIXME: This line should be deleted once Slots uses breadcrumbs      # FIXME: This line should be deleted once Slots uses breadcrumbs
     $r->print(&Apache::loncommon::help_open_topic('Slot About', 'Help on slots'));      $r->print('<br />'.&Apache::loncommon::help_open_topic(
           'Slot About', &mt('Help on slots')));
   
  $r->print('<div>');   $r->print('<div>');
  $r->print('<form method="post" action="/adm/slotrequest">   $r->print('<form method="post" action="/adm/slotrequest">
Line 1049  sub show_table { Line 1556  sub show_table {
     }      }
   
     if (!keys(%slots)) {      if (!keys(%slots)) {
         $r->print('<div>'.&mt('No slots have been created in this course.').'</div>');          $r->print(
               '<p class="LC_info">'
              .&mt('No slots have been created in this '.lc($crstype).'.')
              .'</p>'
           );
         return;          return;
     }      }
           
Line 1076  sub show_table { Line 1587  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',
      'space'           => '# of students/max',       'space'           => '# of students/max',
      'ip'              => 'IP or DNS restrictions',       'ip'              => 'IP or DNS restrictions',
Line 1085  sub show_table { Line 1598  sub show_table {
      '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');
       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','space','ip','symb',      'startreserve','endreserve','reservationmsg','secret','space',
     'allowedsections','allowedusers','uniqueperiod',      'ip','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 1160  sub show_table { Line 1678  sub show_table {
     6,\%stu_display_fields,      6,\%stu_display_fields,
     \@stu_display_order).'      \@stu_display_order).'
            </td>             </td>
            <td valign="top">'.&Apache::loncommon::select_form($when,'when',%when_fields).             <td valign="top">'.&Apache::loncommon::select_form($when,'when',\%when_fields).
           '</td>            '</td>
            <td valign="top">'.&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'},
Line 1173  sub show_table { Line 1691  sub show_table {
            <td valign="top">             <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 1186  sub show_table { Line 1704  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|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'}}) 
Line 1235  sub show_table { Line 1754  sub show_table {
  if ($tmp =~ /^error: /) { undef(%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 ($id_count,$ids);   my ($id_count,$ids);
Line 1277  sub show_table { Line 1799  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 1338  sub show_table { Line 1862  sub show_table {
                                                delete => 'Delete',                                                 delete => 'Delete',
                                                slotlog => 'History',                                                 slotlog => 'History',
         );          );
  my $edit=(<<"EDITLINK");          my ($edit,$delete,$showlog,$remove_all);
           if ($mgr) {
       $edit=(<<"EDITLINK");
 <a href="/adm/helper/newslot.helper?name=$slot">$lt{'edit'}</a>  <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">$lt{'delete'}</a>  <a href="/adm/slotrequest?command=delete&amp;slotname=$slot">$lt{'delete'}</a>
 DELETELINK  DELETELINK
   
         my $showlog=(<<"LOGLINK");              $remove_all=&remove_link($slot,'remove all').'<br />';
   
               if ($ids eq '') {
                   undef($remove_all);
               } else {
                   undef($delete);
               }
           }
   
           $showlog=(<<"LOGLINK");
 <a href="/adm/slotrequest?command=slotlog&amp;slotname=$slot">$lt{'slotlog'}</a>  <a href="/adm/slotrequest?command=slotlog&amp;slotname=$slot">$lt{'slotlog'}</a>
 LOGLINK  LOGLINK
   
         my $remove_all=&remove_link($slot,'remove all').'<br />';  
   
         if ($ids eq '') {  
             undef($remove_all);  
         } else {  
             undef($delete);  
         }  
  if ($slots{$slot}{'type'} ne 'schedulable_student') {   if ($slots{$slot}{'type'} ne 'schedulable_student') {
             undef($showlog);               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.
Line 1384  LOGLINK Line 1917  LOGLINK
  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");
  }   }
Line 1424  $row_end Line 1963  $row_end
 STUFF  STUFF
         }          }
     }      }
     $r->print(&Apache::loncommon::end_data_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;      return;
 }  }
   
 sub manage_reservations {  sub manage_reservations {
     my ($r,$type) = @_;      my ($r,$crstype,$slots,$consumed_uniqueperiods,$allavailable) = @_;
     my $navmap = Apache::lonnavmaps::navmap->new();      my $navmap = Apache::lonnavmaps::navmap->new();
     $r->print('<p>'      $r->print('<p>'
              .&mt('Instructors may use a reservation system to place restrictions on when and where assignments can be worked on.')               .&mt('Instructors may use a reservation system to place restrictions on when and where assignments can be worked on.')
              .'<br />'               .'<br />'
              .&mt('One example is for management of laboratory space, which is only available at certain times, and has a limited number of seats.')               .&mt('One example is for management of laboratory space, which is only available at certain times, and has a limited number of seats.')
              .'</p><p>'  
              .&mt('Your reservation status for any such assignments is listed below:')  
              .'</p>'               .'</p>'
     );      );
     if (!defined($navmap)) {      if (!defined($navmap)) {
         $r->print('<div class="LC_error">'.          $r->print('<div class="LC_error">');
                   &mt('Unable to retrieve information about course contents').          if ($crstype eq 'Community') {
                   '</div>');              $r->print(&mt('Unable to retrieve information about community contents'));
         &Apache::lonnet::logthis('Manage Reservations - could not create navmap object in '.lc($type).':'.$env{'request.course.id'});          } 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;          return;
     }      }
     my (%parent,%shownparent,%container,%container_title,%contents);      my (%parent,%shownparent,%container,%container_title,%contents);
Line 1451  sub manage_reservations { Line 2010  sub manage_reservations {
     my @backgrounds = ("LC_odd_row","LC_even_row");      my @backgrounds = ("LC_odd_row","LC_even_row");
     my $numcolors = scalar(@backgrounds);      my $numcolors = scalar(@backgrounds);
     my $location=&Apache::loncommon::lonhttpdurl("/adm/lonIcons/whitespace_21.gif");      my $location=&Apache::loncommon::lonhttpdurl("/adm/lonIcons/whitespace_21.gif");
     $r->print('<table class="LC_data_table LC_tableOfContent">'."\n");      my $slotheader = '<p>'.
                    &mt('Your reservation status for any such assignments is listed below:').
                    '</p>'.
                    '<table class="LC_data_table LC_tableOfContent">'."\n";
       my $shownheader = 0;
     my $it=$navmap->getIterator(undef,undef,undef,1,undef,undef);      my $it=$navmap->getIterator(undef,undef,undef,1,undef,undef);
     while (my $resource = $it->next()) {      while (my $resource = $it->next()) {
         if ($resource == $it->BEGIN_MAP()) {          if ($resource == $it->BEGIN_MAP()) {
Line 1513  sub manage_reservations { Line 2076  sub manage_reservations {
                 } elsif ($slot_status == $resource->RESERVABLE) {                  } elsif ($slot_status == $resource->RESERVABLE) {
                     $msg=&mt('Reservation needed');                      $msg=&mt('Reservation needed');
                     $get_choices = 1;                      $get_choices = 1;
                   } elsif ($slot_status == $resource->RESERVABLE_LATER) {
                       $msg=&mt('Reservation needed: will be reservable later.');
                 } elsif ($slot_status == $resource->NOTRESERVABLE) {                  } elsif ($slot_status == $resource->NOTRESERVABLE) {
                     $msg=&mt('Reservation needed: none available.');                      $msg=&mt('Reservation needed: none available.');
                 } elsif ($slot_status == $resource->UNKNOWN) {                  } elsif ($slot_status == $resource->UNKNOWN) {
Line 1546  sub manage_reservations { Line 2111  sub manage_reservations {
                     foreach my $item (@maprows) {                      foreach my $item (@maprows) {
                         $rownum ++;                          $rownum ++;
                         my $bgcolor = $backgrounds[$rownum % $numcolors];                          my $bgcolor = $backgrounds[$rownum % $numcolors];
                           if (!$shownheader) {
                               $r->print($slotheader);
                               $shownheader = 1;
                           }
                         $r->print('<tr class="'.$bgcolor.'">'.$item.'</tr>'."\n");                          $r->print('<tr class="'.$bgcolor.'">'.$item.'</tr>'."\n");
                     }                      }
                 }                  }
                 $rownum ++;                  $rownum ++;
                 my $bgcolor = $backgrounds[$rownum % $numcolors];                  my $bgcolor = $backgrounds[$rownum % $numcolors];
                   if (!$shownheader) {
                       $r->print($slotheader);
                       $shownheader = 1;
                   }
                 $r->print('<tr class="'.$bgcolor.'"><td>'."\n");                  $r->print('<tr class="'.$bgcolor.'"><td>'."\n");
                 for (my $i=0; $i<$depth; $i++) {                  for (my $i=0; $i<$depth; $i++) {
                     $r->print('<img src="'.$location.'" alt="" />');                      $r->print('<img src="'.$location.'" alt="" />');
Line 1570  sub manage_reservations { Line 2143  sub manage_reservations {
                     }                      }
                 }                  }
                 if ($hasaction) {                  if ($hasaction) {
                     $result .= '<td valgn="middle">'.$msg.'</td>'.                      $result .= '<td valign="top">'.$msg.'</td>'.
                                '<td valign="middle">'.('&nbsp;' x6);                                 '<td valign="top">';
                 } else {                  } else {
                     $result .= '<td colspan="2" valign="middle">'.$msg.'</td>';                      $result .= '<td colspan="2" valign="middle">'.$msg.'</td>';
                 }                  }
                 $r->print($result);                  $r->print($result);
                 if ($hasaction) {                  if ($hasaction) {
                     my $formname = 'manageres_'.$reservable;                      my @got_slots=&check_for_reservation($symb,'allslots');
                     &show_choices($r,$symb,$formname);                      if ($got_slots[0] =~ /^error: /) {
                           $r->print('<span class="LC_error">'.
                                     &mt('An error occurred determining slot availability.').
                                     '</span>');
                       } else {
                           my $formname = 'manageres_'.$reservable;
                           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 ((defined($slots->{$slot}->{'symb'})) && 
                                               ($slots->{$slot}->{'symb'} ne $symb)) {
                                               next;
                                           }
                                       }
                                       push(@available,$slot);
                                   }
                               }  
                               &show_choices($r,$symb,$formname,$reservable,$slots,$consumed_uniqueperiods,
                                             \@available,\@got_slots);
                           }
                       }
                     $r->print('</td>');                      $r->print('</td>');
                 }                  }
                 $r->print('</tr>');                  $r->print('</tr>');
             }              }
         }          }
     }      }
       if ($shownheader) {
           $r->print('</table>');
       }
     if (!$reservable) {      if (!$reservable) {
         $r->print('<span class="LC_info">'.&mt('No course items currently require a reservation to gain access.').'</span>');          $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('</table>'.      $r->print('<p><a href="/adm/slotrequest?command=showresv">'.
               '<p><a href="/adm/slotrequest?command=showresv">'.  
               &mt('Reservation History').'</a></p>');                &mt('Reservation History').'</a></p>');
 }  }
   
Line 1620  sub show_reservations { Line 2224  sub show_reservations {
     my $formname = 'slotlog';      my $formname = 'slotlog';
     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};      my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};      my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
       my $crstype = &Apache::loncommon::course_type();
     my %log=&Apache::lonnet::dump('nohist_'.$cdom.'_'.$cnum.'_slotlog',$udom,$uname);      my %log=&Apache::lonnet::dump('nohist_'.$cdom.'_'.$cnum.'_slotlog',$udom,$uname);
     if ($env{'form.origin'} eq 'aboutme') {      if ($env{'form.origin'} eq 'aboutme') {
         $r->print('<div class="LC_fontsize_large">'.          $r->print('<div class="LC_fontsize_large">');
                   &mt('History of student-reservable slots for: [_1]',          my $name = &Apache::loncommon::plainname($env{'form.uname'},$env{'form.udom'},
                       &Apache::loncommon::plainname($env{'form.uname'},$env{'form.udom'},                                                      'firstname');
                                                     'firstname')).'</div>');          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.'">');      $r->print('<form action="/adm/slotrequest" method="post" name="'.$formname.'">');
     # set defaults      # set defaults
Line 1674  sub show_reservations { Line 2287  sub show_reservations {
         }          }
     }      }
     my (%titles,%maptitles);      my (%titles,%maptitles);
     my %lt = &reservationlog_contexts();      my %lt = &reservationlog_contexts($crstype);
     foreach my $id (sort { $log{$b}{'exe_time'}<=>$log{$a}{'exe_time'} } (keys(%log))) {      foreach my $id (sort { $log{$b}{'exe_time'}<=>$log{$a}{'exe_time'} } (keys(%log))) {
         next if (($log{$id}{'exe_time'} < $curr{'log_start_date'}) ||          next if (($log{$id}{'exe_time'} < $curr{'log_start_date'}) ||
                  ($log{$id}{'exe_time'} > $curr{'log_end_date'}));                   ($log{$id}{'exe_time'} > $curr{'log_end_date'}));
Line 1711  sub show_reservations { Line 2324  sub show_reservations {
     if ($showntablehdr) {      if ($showntablehdr) {
         $r->print(&Apache::loncommon::end_data_table().'<br />');          $r->print(&Apache::loncommon::end_data_table().'<br />');
         if (($curr{'page'} > 1) || ($more_records)) {          if (($curr{'page'} > 1) || ($more_records)) {
             $r->print('<table><tr>');              $r->print('<p>');
             if ($curr{'page'} > 1) {              if ($curr{'page'} > 1) {
                 $r->print('<td><a href="javascript:chgPage('."'previous'".');">'.&mt('Previous [_1] changes',$curr{'show'}).'</a></td>');                  $r->print('<input type="button" onclick="javascript:chgPage('."'previous'".');" value="'.
                             &mt('Previous [_1] changes',$curr{'show'}).'" />');
             }              }
             if ($more_records) {              if ($more_records) {
                 $r->print('<td><a href="javascript:chgPage('."'next'".');">'.&mt('Next [_1] changes',$curr{'show'}).'</a></td>');                  $r->print('<input type="button" onclick="javascript:chgPage('."'next'".');" value="'.
                             &mt('Next [_1] changes',$curr{'show'}).'" />');
             }              }
             $r->print('</tr></table>');              $r->print('</p>');
             $r->print(<<"ENDSCRIPT");              $r->print(<<"ENDSCRIPT");
 <script type="text/javascript">  <script type="text/javascript">
   // <![CDATA[
 function chgPage(caller) {  function chgPage(caller) {
     if (caller == 'previous') {      if (caller == 'previous') {
         document.$formname.page.value --;          document.$formname.page.value --;
Line 1731  function chgPage(caller) { Line 2347  function chgPage(caller) {
     document.$formname.submit();      document.$formname.submit();
     return;      return;
 }  }
   // ]]>
 </script>  </script>
 ENDSCRIPT  ENDSCRIPT
         }          }
Line 1754  ENDSCRIPT Line 2371  ENDSCRIPT
 sub show_reservations_log {  sub show_reservations_log {
     my ($r) = @_;      my ($r) = @_;
     my $badslot;      my $badslot;
       my $crstype = &Apache::loncommon::course_type();
     if ($env{'form.slotname'} eq '') {      if ($env{'form.slotname'} eq '') {
         $r->print('<div class="LC_warning">'.&mt('No slot name provided').'</div>');          $r->print('<div class="LC_warning">'.&mt('No slot name provided').'</div>');
         $badslot = 1;          $badslot = 1;
Line 1764  sub show_reservations_log { Line 2382  sub show_reservations_log {
             $badslot = 1;              $badslot = 1;
         } elsif ($slot{type} ne 'schedulable_student') {          } elsif ($slot{type} ne 'schedulable_student') {
             my $description = &get_description($env{'form.slotname'},\%slot);              my $description = &get_description($env{'form.slotname'},\%slot);
             $r->print('<div class="LC_warning">'.&mt('Reservation history unavailable for non-student-reservable slot: [_1].',$description).'</div>');              $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;              $badslot = 1;
         }          }
     }      }
Line 1835  sub show_reservations_log { Line 2459  sub show_reservations_log {
   
     my %slot=&Apache::lonnet::get_slot($env{'form.slotname'});      my %slot=&Apache::lonnet::get_slot($env{'form.slotname'});
     my $description = $slot{'description'};      my $description = $slot{'description'};
     $r->print('<span class="LC_fontsize_large">'.      $r->print('<span class="LC_fontsize_large">');
               &mt('Reservation changes for student-reservable slot: [_1]',$description).'</span><br />');      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));      $r->print(&display_filter($formname,$cdom,$cnum,\%curr,$version,\@allsymbs));
     my $showntablehdr = 0;      my $showntablehdr = 0;
     my $tablehdr = &Apache::loncommon::start_data_table().      my $tablehdr = &Apache::loncommon::start_data_table().
Line 1855  sub show_reservations_log { Line 2483  sub show_reservations_log {
             $minshown = 1 + ($curr{'page'} - 1) * $curr{'show'};              $minshown = 1 + ($curr{'page'} - 1) * $curr{'show'};
         }          }
     }      }
     my %lt = &reservationlog_contexts();      my %lt = &reservationlog_contexts($crstype);
     my (%titles,%maptitles);      my (%titles,%maptitles);
     foreach my $id (sort { $log{$b}{'exe_time'}<=>$log{$a}{'exe_time'} } (keys(%log))) {      foreach my $id (sort { $log{$b}{'exe_time'}<=>$log{$a}{'exe_time'} } (keys(%log))) {
         next if (($log{$id}{'exe_time'} < $curr{'log_start_date'}) ||          next if (($log{$id}{'exe_time'} < $curr{'log_start_date'}) ||
Line 1909  sub show_reservations_log { Line 2537  sub show_reservations_log {
     if ($showntablehdr) {      if ($showntablehdr) {
         $r->print(&Apache::loncommon::end_data_table().'<br />');          $r->print(&Apache::loncommon::end_data_table().'<br />');
         if (($curr{'page'} > 1) || ($more_records)) {          if (($curr{'page'} > 1) || ($more_records)) {
             $r->print('<table><tr>');              $r->print('<p>');
             if ($curr{'page'} > 1) {              if ($curr{'page'} > 1) {
                 $r->print('<td><a href="javascript:chgPage('."'previous'".');">'.&mt('Previous [_1] changes',$curr{'show'}).'</a></td>');                  $r->print('<input type="button" onclick="javascript:chgPage('."'previous'".');" value="'.
                             &mt('Previous [_1] changes',$curr{'show'}).'" />');
             }              }
             if ($more_records) {              if ($more_records) {
                 $r->print('<td><a href="javascript:chgPage('."'next'".');">'.&mt('Next [_1] changes',$curr{'show'}).'</a></td>');                  $r->print('<input type="button" onclick="javascript:chgPage('."'next'".');" value="'.
                             &mt('Next [_1] changes',$curr{'show'}).'" />');
             }              }
             $r->print('</tr></table>');              $r->print('</p>');
             $r->print(<<"ENDSCRIPT");              $r->print(<<"ENDSCRIPT");
 <script type="text/javascript">  <script type="text/javascript">
 function chgPage(caller) {  function chgPage(caller) {
Line 1957  sub get_resource_title { Line 2587  sub get_resource_title {
                 $maptitle = $maptitles->{$mapurl};                  $maptitle = $maptitles->{$mapurl};
             } else {              } else {
                 if ($mapurl eq $env{'course.'.$env{'request.course.id'}.'.url'}) {                  if ($mapurl eq $env{'course.'.$env{'request.course.id'}.'.url'}) {
                     $maptitle=&mt('Main Course Documents');                      $maptitle=&mt('Main Content');
                 } else {                  } else {
                     $maptitle=&Apache::lonnet::gettitle($mapurl);                      $maptitle=&Apache::lonnet::gettitle($mapurl);
                 }                  }
Line 1975  sub get_resource_title { Line 2605  sub get_resource_title {
 }  }
   
 sub reservationlog_contexts {  sub reservationlog_contexts {
       my ($crstype) = @_;
     my %lt = &Apache::lonlocal::texthash (      my %lt = &Apache::lonlocal::texthash (
                                              any        => 'Any',                                               any        => 'Any',
                                              user       => 'By student',                                               user       => 'By student',
Line 1984  sub reservationlog_contexts { Line 2615  sub reservationlog_contexts {
                                              release    => 'Dropped reservation',                                               release    => 'Dropped reservation',
                                              usermanage => 'By student',                                                usermanage => 'By student', 
                                          );                                           );
       if ($crstype eq 'Community') {
           $lt{'user'} = &mt('By member');
           $lt{'usermanage'} = $lt{'user'};
       }
     return %lt;      return %lt;
 }  }
   
Line 2004  sub display_filter { Line 2639  sub display_filter {
         &Apache::lonhtmlcommon::date_setter($formname,'log_end_date',          &Apache::lonhtmlcommon::date_setter($formname,'log_end_date',
                                             $curr->{'log_end_date'},undef,                                              $curr->{'log_end_date'},undef,
                                             undef,undef,undef,undef,undef,undef,$nolink);                                              undef,undef,undef,undef,undef,undef,$nolink);
     my %lt = &reservationlog_contexts();      my $crstype = &Apache::loncommon::course_type();
       my %lt = &reservationlog_contexts($crstype);
     $output .= '<td valign="top"><b>'.&mt('Window during which changes occurred:').      $output .= '<td valign="top"><b>'.&mt('Window during which changes occurred:').
                '</b><br /><table><tr><td>'.&mt('After:').                 '</b><br /><table><tr><td>'.&mt('After:').
                '</td><td>'.$startform.'</td></tr><tr><td>'.&mt('Before:').'</td><td>'.                 '</td><td>'.$startform.'</td></tr><tr><td>'.&mt('Before:').'</td><td>'.
Line 2050  sub display_filter { Line 2686  sub display_filter {
         }          }
         $output .= '</select></td>';          $output .= '</select></td>';
     }      }
     $output .= '<td>&nbsp;&nbsp;</td><td valign="middle"><input type="submit" value="'.      $output .= '<td>&nbsp;&nbsp;</td></tr></table>'.
                &mt('Update Display').'" /></tr></table>'.                 '<p><input type="submit" value="'.
                  &mt('Update Display').'" /></p>'.
                '<p class="LC_info">'.                 '<p class="LC_info">'.
                &mt('Only changes made from servers running LON-CAPA [_1] or later are displayed.'                 &mt('Only changes made from servers running LON-CAPA [_1] or later are displayed.'
                   ,'2.8.99.0');                    ,'2.9.0');
     if ($version) {      if ($version) {
         $output .= ' '.&mt('This LON-CAPA server is version [_1]',$version);          $output .= ' '.&mt('This LON-CAPA server is version [_1]',$version);
     }      }
Line 2062  sub display_filter { Line 2699  sub display_filter {
     return $output;      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(      $r->print(
         &Apache::grades::checkforfile_js()          &Apache::grades::checkforfile_js()
        .'<h3>'.&mt('Specify a file containing the slot definitions.').'</h3>'         .'<h2>'.&mt('Upload a file containing the slot definitions').'</h2>'
        .'<form method="post" enctype="multipart/form-data"'         .'<form method="post" enctype="multipart/form-data"'
        .' action="/adm/slotrequest" name="slotupload">'         .' action="/adm/slotrequest" name="slotupload">'
        .'<input type="hidden" name="command" value="csvuploadmap" />'         .'<input type="hidden" name="command" value="csvuploadmap" />'
Line 2100  sub csvuploadmap_header { Line 2773  sub csvuploadmap_header {
   
     my $checked=(($env{'form.noFirstLine'})?' checked="checked"':'');      my $checked=(($env{'form.noFirstLine'})?' checked="checked"':'');
     my $ignore=&mt('Ignore First Line');      my $ignore=&mt('Ignore First Line');
  my $help_field = &Apache::loncommon::help_open_topic('Slot SelectingField');      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 $help_field</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 2117  to this page if the data selected is ins Line 2814  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 2130  sub csvuploadmap_footer { Line 2828  sub csvuploadmap_footer {
     my ($request,$i,$keyfields) =@_;      my ($request,$i,$keyfields) =@_;
     my $buttontext = &mt('Create Slots');      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="$buttontext" /><br />  <input type="button" onclick="javascript:verify(this.form)" value="$buttontext" /><br />
Line 2139  ENDPICK Line 2836  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 2165  ENDPICK Line 2862  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 2232  sub csvupload_fields { Line 2929  sub csvupload_fields {
     ['starttime','Start Time of slot'],      ['starttime','Start Time of slot'],
     ['endtime','End Time of slot'],      ['endtime','End Time of slot'],
     ['startreserve','Reservation Start Time'],      ['startreserve','Reservation Start Time'],
               ['endreserve','Reservation End Time'],
               ['reservationmsg','Message when reservation changed'],
     ['ip','IP or DNS restriction'],      ['ip','IP or DNS restriction'],
     ['proctor','List of proctor ids'],      ['proctor','List of proctor ids'],
     ['description','Slot Description'],      ['description','Slot Description'],
Line 2304  sub csv_upload_assign { Line 3003  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 2313  sub csv_upload_assign { Line 3016  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 ($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 2337  sub csv_upload_assign { Line 3100  sub csv_upload_assign {
  $r->rflush();   $r->rflush();
  $countdone++;   $countdone++;
     }      }
       if ($countdone) {
           &Apache::lonnet::devalidate_slots_cache($cname,$cdom); 
       }
     $r->print('<p>'.&mt('Created [quant,_1,slot]',$countdone)."\n".'</p>');      $r->print('<p>'.&mt('Created [quant,_1,slot]',$countdone)."\n".'</p>');
     foreach my $error (@errors) {      foreach my $error (@errors) {
  $r->print('<p><span class="LC_warning">'.$error.'</span></p>'."\n");   $r->print('<p><span class="LC_warning">'.$error.'</span></p>'."\n");
Line 2362  sub slot_command_titles { Line 3128  sub slot_command_titles {
     return %titles;      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 2379  sub handler { Line 3154  sub handler {
   
     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 ($env{'form.command'} eq 'showslots') {
         if (($vgr ne 'F') && ($mgr ne 'F')) {          if (($vgr ne 'F') && ($mgr ne 'F')) {
             $env{'form.command'} = 'manageresv';               $env{'form.command'} = 'manageresv'; 
Line 2399  sub handler { Line 3175  sub handler {
         if (ref($brcrum) eq 'ARRAY') {          if (ref($brcrum) eq 'ARRAY') {
             push(@{$brcrum},{href=>"/adm/slotrequest?command=showresv",text=>$title});              push(@{$brcrum},{href=>"/adm/slotrequest?command=showresv",text=>$title});
         }          }
     } elsif ($env{'form.command'} eq 'manageresv') {      } elsif (($env{'form.requestattempt'}) || ($env{'form.command'} eq 'manageresv')) {  
         $title = 'Manage Reservations';          if ($env{'form.command'} eq 'manageresv') {
         $brcrum =[{href=>"/adm/slotrequest?command=manageresv",text=>$title}];              $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') {      } elsif ($vgr eq 'F') {
         if ($env{'form.command'} =~ /^(slotlog|showslots|uploadstart|csvuploadmap|csvuploadassign|delete|release|remove_registration)$/) {          if ($env{'form.command'} =~ /^(slotlog|showslots|uploadstart|csvuploadmap|csvuploadassign|delete|release|remove_registration)$/) {
             $brcrum =[{href=>"/adm/slotrequest?command=showslots",              $brcrum =[{href=>"/adm/slotrequest?command=showslots",
Line 2421  sub handler { Line 3202  sub handler {
             if (ref($brcrum) eq 'ARRAY') {              if (ref($brcrum) eq 'ARRAY') {
                 push(@{$brcrum},{href=>"/adm/slotrequest?command=$env{'form.command'}",text=>$crumb_titles{$env{'form.command'}}});                  push(@{$brcrum},{href=>"/adm/slotrequest?command=$env{'form.command'}",text=>$crumb_titles{$env{'form.command'}}});
             }              }
               
         }          }
       } else {
           $brcrum =[];
     }      }
     &start_page($r,$title,$brcrum);      my ($symb,$js,$available,$allavailable,$got_slots);
       $available = [];
       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,$js);
   
     if ($env{'form.command'} eq 'manageresv') {      if ($env{'form.command'} eq 'manageresv') {
           $allavailable = $available;
           undef($available);
           undef($got_slots);
         my $crstype = &Apache::loncommon::course_type();          my $crstype = &Apache::loncommon::course_type();
         &manage_reservations($r,$crstype);          &manage_reservations($r,$crstype,\%slots,$consumed_uniqueperiods,$allavailable);
     } elsif ($env{'form.command'} eq 'showresv') {      } elsif ($env{'form.command'} eq 'showresv') {
         &show_reservations($r,$env{'form.uname'},$env{'form.udom'});          &show_reservations($r,$env{'form.uname'},$env{'form.udom'});
     } elsif ($env{'form.command'} eq 'showslots' && $vgr eq 'F') {      } elsif ($env{'form.command'} eq 'showslots' && $vgr eq 'F') {
Line 2458  sub handler { Line 3252  sub handler {
     }      }
     &csv_upload_map($r);      &csv_upload_map($r);
  }   }
     } elsif ($env{'form.command'} eq 'slotlog' && $mgr eq 'F') {      } elsif (($env{'form.command'} eq 'slotlog') && ($vgr eq 'F')) {
         &show_reservations_log($r);          &show_reservations_log($r);
     } else {      } else {
  my $symb=&unescape($env{'form.symb'});   my $symb=&unescape($env{'form.symb'});
Line 2485  sub handler { Line 3279  sub handler {
     return OK;      return OK;
  }   }
  if ($env{'form.requestattempt'}) {   if ($env{'form.requestattempt'}) {
     &show_choices($r,$symb);              $r->print('<div class="LC_left_float">'); 
       &show_choices($r,$symb,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 (&get_slot($r,$symb,$env{'form.releaseslot'},1)) {              if ($env{'form.nochange'}) {
                   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'});   &release_slot($r,$symb,$env{'form.releaseslot'});
     }      }
  } else {   } else {

Removed from v.1.102  
changed lines
  Added in v.1.125.2.3.4.2


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