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

version 1.113, 2012/06/09 15:41:26 version 1.126, 2015/09/23 23:04:53
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 enddate = endm+"/"+endd+"/"+endy;
                   var endtime = new Date(enddate).getTime();
                   endtime = endtime/1000;
                   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 304  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 218  sub check_for_conflict { Line 400  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 339  sub store_slot_parm { Line 524  sub store_slot_parm {
                        context => $env{'form.context'},                         context => $env{'form.context'},
                     );                      );
   
     &Apache::lonnet::instructor_log('slotreservationslog',\%storehash,      &Apache::lonnet::write_log('course','slotreservationslog',\%storehash,
                                     '',$env{'user.name'},$env{'user.domain'},                                 '',$env{'user.name'},$env{'user.domain'},
                                     $cnum,$cdom);                                 $cnum,$cdom);
     &Apache::lonnet::instructor_log($cdom.'_'.$cnum.'_slotlog',\%storehash,      &Apache::lonnet::write_log('course',$cdom.'_'.$cnum.'_slotlog',\%storehash,
                                     1,$env{'user.name'},$env{'user.domain'},                                 1,$env{'user.name'},$env{'user.domain'},
                                     $env{'user.name'},$env{'user.domain'});                                 $env{'user.name'},$env{'user.domain'});
   
     return;      return;
 }  }
Line 504  sub release_reservation { Line 689  sub release_reservation {
         return (0,'error: Unable to determine current status');          return (0,'error: Unable to determine current status');
     }      }
     my $passed_resource = $navmap->getBySymb($symb);      my $passed_resource = $navmap->getBySymb($symb);
     if ($passed_resource->is_map()) {      if (ref($passed_resource)) {
  my ($a_resource) =           if ($passed_resource->is_map()) {
     $navmap->retrieveResources($passed_resource,       my ($a_resource) = 
        sub {$_[0]->is_problem()},0,1);                  $navmap->retrieveResources($passed_resource, 
  $symb = $a_resource->symb();                                             sub {$_[0]->is_problem()},0,1);
               $symb = $a_resource->symb();
           }
       } else {
           unless ($mgr eq 'F') {
               return (0,'error: Unable to determine current status');
           }
     }      }
   
     # get parameter string, check for existance, rebuild string with the slot      # get parameter string, check for existence, rebuild string with the slot
     my $student = &Apache::lonnet::EXT("resource.0.availablestudent",      my $student = &Apache::lonnet::EXT("resource.0.availablestudent",
                                        $symb,$udom,$uname);                                         $symb,$udom,$uname);
     my @slots = split(/:/,$student);      my @slots = split(/:/,$student);
Line 538  sub release_reservation { Line 729  sub release_reservation {
                                action  => 'release',                                 action  => 'release',
                                context => $env{'form.context'},                                 context => $env{'form.context'},
                         );                          );
             &Apache::lonnet::instructor_log('slotreservationslog',\%storehash,              &Apache::lonnet::write_log('slotreservationslog',\%storehash,
                                             1,$uname,$udom,$cnum,$cdom);                                         1,$uname,$udom,$cnum,$cdom);
             &Apache::lonnet::instructor_log($cdom.'_'.$cnum.'_slotlog',\%storehash,              &Apache::lonnet::write_log($cdom.'_'.$cnum.'_slotlog',\%storehash,
                                             1,$uname,$udom,$uname,$udom);                                         1,$uname,$udom,$uname,$udom);
  }   }
     }      }
   
Line 696  STUFF Line 887  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 735  STUFF Line 926  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 809  sub allowed_slot { Line 1000  sub allowed_slot {
     return 0 if (!$userallowed);      return 0 if (!$userallowed);
   
     # not allowed for this resource      # not allowed for this resource
     if (defined($slot->{'symb'})      if (defined($slot->{'symb'})) {
  && $slot->{'symb'} ne $symb) {          my $exclude = 1;
  return 0;          my ($slotmap,$slotid,$sloturl) = &Apache::lonnet::decode_symb($slot->{'symb'});
           if ($sloturl=~/\.(page|sequence)$/) {
               my ($map,$id,$url) = &Apache::lonnet::decode_symb($symb);
               if (($map ne '') && ($map eq $slotmap)) {
                   $exclude = 0;
               }
           } elsif ($slot->{'symb'} eq $symb) {
               $exclude = 0;
           }
           if ($exclude) {
               unless ((ref($toskip) eq 'HASH') && ($toskip->{'symb'})) {
           return 0;
               }
           }
     }      }
   
     my $conflict = &check_for_conflict($symb,$slot_name,$slot,$slots,      my $conflict = &check_for_conflict($symb,$slot_name,$slot,$slots,
Line 839  sub get_description { Line 1043  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::get_course_slots($cnum,$cdom);  
     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},$symb,\%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>';
         }          }
         $r->print('<p class="LC_info">'.$output.'</p>');          $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 917  sub show_choices { Line 1161  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 938  STUFF Line 1183  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 954  STUFF Line 1199  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 1058  sub show_table { Line 1307  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 1074  sub show_table { Line 1324  sub show_table {
     }      }
   
     if (!keys(%slots)) {      if (!keys(%slots)) {
         if ($crstype eq 'Community') {          $r->print(
             $r->print('<div>'.&mt('No slots have been created in this community.').'</div>');              '<p class="LC_info">'
         } else {             .&mt('No slots have been created in this '.lc($crstype).'.')
             $r->print('<div>'.&mt('No slots have been created in this course.').'</div>');             .'</p>'
         }          );
         return;          return;
     }      }
           
Line 1110  sub show_table { Line 1360  sub show_table {
      'secret'          => 'Secret Word',       'secret'          => 'Secret Word',
      'space'           => '# of students/max',       'space'           => '# of students/max',
      'ip'              => 'IP or DNS restrictions',       'ip'              => 'IP or DNS restrictions',
      'symb'            => 'Resource slot is restricted to.',       'symb'            => 'Resource/Map slot is restricted to.',
      'allowedsections' => 'Sections slot is restricted to.',       'allowedsections' => 'Sections slot is restricted to.',
      'allowedusers'    => 'Users slot is restricted to.',       'allowedusers'    => 'Users slot is restricted to.',
      'uniqueperiod'    => 'Period of time slot is unique',       'uniqueperiod'    => 'Period of time slot is unique',
Line 1209  sub show_table { Line 1459  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 1476  STUFF Line 1726  STUFF
 }  }
   
 sub manage_reservations {  sub manage_reservations {
     my ($r,$crstype) = @_;      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.')
Line 1495  sub manage_reservations { Line 1745  sub manage_reservations {
         &Apache::lonnet::logthis('Manage Reservations - could not create navmap object in '.lc($crstype).':'.$env{'request.course.id'});          &Apache::lonnet::logthis('Manage Reservations - could not create navmap object in '.lc($crstype).':'.$env{'request.course.id'});
         return;          return;
     }      }
       if (ref($consumed_uniqueperiods) eq 'HASH') {
           if (&Apache::lonnet::error(%$consumed_uniqueperiods)) {
               $r->print('<span class="LC_error">'.
                         &mt('An error occurred determining slot availability.').
                         '</span>');
               return;
           }
       } elsif ($consumed_uniqueperiods =~ /^error: /) {
           $r->print('<span class="LC_error">'.
                     &mt('An error occurred determining slot availability.').
                     '</span>');
           return;
       }
     my (%parent,%shownparent,%container,%container_title,%contents);      my (%parent,%shownparent,%container,%container_title,%contents);
     my ($depth,$count,$reservable,$lastcontainer,$rownum) = (0,0,0,0,0);      my ($depth,$count,$reservable,$lastcontainer,$rownum) = (0,0,0,0,0);
     my @backgrounds = ("LC_odd_row","LC_even_row");      my @backgrounds = ("LC_odd_row","LC_even_row");
Line 1633  sub manage_reservations { Line 1896  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>');
Line 1801  sub show_reservations { Line 2087  sub show_reservations {
             $r->print('</tr></table>');              $r->print('</tr></table>');
             $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 1811  function chgPage(caller) { Line 2098  function chgPage(caller) {
     document.$formname.submit();      document.$formname.submit();
     return;      return;
 }  }
   // ]]>
 </script>  </script>
 ENDSCRIPT  ENDSCRIPT
         }          }
Line 2048  sub get_resource_title { Line 2336  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 2199  sub upload_start { Line 2487  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 2233  sub csvuploadmap_header { Line 2521  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 2250  to this page if the data selected is ins Line 2562  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 2263  sub csvuploadmap_footer { Line 2576  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 2272  ENDPICK Line 2584  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 2298  ENDPICK Line 2610  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 2371  sub csvupload_fields { Line 2683  sub csvupload_fields {
     ['proctor','List of proctor ids'],      ['proctor','List of proctor ids'],
     ['description','Slot Description'],      ['description','Slot Description'],
     ['maxspace','Maximum number of reservations'],      ['maxspace','Maximum number of reservations'],
     ['symb','Resource Restriction'],      ['symb','Resource/Map Restriction'],
     ['uniqueperiod','Date range of slot exclusion'],      ['uniqueperiod','Date range of slot exclusion'],
     ['secret','Secret word proctor uses to validate'],      ['secret','Secret word proctor uses to validate'],
     ['allowedsections','Sections slot is restricted to'],      ['allowedsections','Sections slot is restricted to'],
Line 2478  sub csv_upload_assign { Line 2790  sub csv_upload_assign {
  $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)=split(',',$entries{$fields{'uniqueperiod'}});
     my @times=(&UnixDate($start,"%s"),      my @times=(&UnixDate($start,"%s"),
Line 2550  sub handler { Line 2892  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 2570  sub handler { Line 2913  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 2596  sub handler { Line 2944  sub handler {
     } else {      } else {
         $brcrum =[];          $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 2657  sub handler { Line 3017  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') {

Removed from v.1.113  
changed lines
  Added in v.1.126


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