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

version 1.125.2.3.4.2, 2020/04/08 20:06:59 version 1.125.2.4, 2018/06/27 14:26:28
Line 456  sub make_reservation { Line 456  sub make_reservation {
  return 'error: Unable to determine current status';   return 'error: Unable to determine current status';
     }      }
   
     my $symb_for_db = $symb;      my $parm_symb  = $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);
  $symb_for_db = &Apache::lonnet::symbread($map);   $parm_symb = &Apache::lonnet::symbread($map);
  $parm_level = 2;   $parm_level = 2;
     }      }
   
Line 503  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'      => $symb_for_db);       'symb'      => $parm_symb);
   
     my $success=&Apache::lonnet::newput('slot_reservations',      my $success=&Apache::lonnet::newput('slot_reservations',
  {"$slot_name\0$wanted" =>   {"$slot_name\0$wanted" =>
Line 515  sub make_reservation { Line 515  sub make_reservation {
  if ($value) {   if ($value) {
     $new_value=$value.':'.$new_value;      $new_value=$value.':'.$new_value;
  }   }
         my $result = &store_slot_parm($symb,$symb_for_db,$slot_name,$parm_level,          &store_slot_parm($symb,$slot_name,$parm_level,$new_value,$cnum,$cdom);
                                       $new_value,$cnum,$cdom,$env{'user.name'},  
                                       $env{'user.domain'},'reserve',$env{'form.context'});  
  return $wanted;   return $wanted;
     }      }
   
Line 526  sub make_reservation { Line 524  sub make_reservation {
 }  }
   
 sub store_slot_parm {  sub store_slot_parm {
     my ($symb_for_parm,$symb_for_db,$slot_name,$parm_level,$new_value,      my ($symb,$slot_name,$parm_level,$new_value,$cnum,$cdom) = @_;
         $cnum,$cdom,$uname,$udom,$action,$context,$delflag) = @_;      my $result=&Apache::lonparmset::storeparm_by_symb($symb,
                                                     '0_availablestudent',
     # store new parameter string                                                     $parm_level, $new_value,
     my $result=&Apache::lonparmset::storeparm_by_symb($symb_for_parm,                                                     'string',
                                                       '0_availablestudent',                                                     $env{'user.name'},
                                                       $parm_level,$new_value,                                                     $env{'user.domain'});
                                                       'string',$uname,$udom);  
     &Apache::lonxml::debug("hrrm $result");      &Apache::lonxml::debug("hrrm $result");
     my %storehash = (      my %storehash = (
                        symb    => $symb_for_db,                         symb    => $symb,
                        slot    => $slot_name,                         slot    => $slot_name,
                        action  => $action,                         action  => 'reserve',
                        context => $context,                         context => $env{'form.context'},
                     );                      );
   
     &Apache::lonnet::write_log('course','slotreservationslog',\%storehash,      &Apache::lonnet::write_log('course','slotreservationslog',\%storehash,
                                $delflag,$uname,$udom,$cnum,$cdom);                                 '',$env{'user.name'},$env{'user.domain'},
                                  $cnum,$cdom);
     &Apache::lonnet::write_log('course',$cdom.'_'.$cnum.'_slotlog',\%storehash,      &Apache::lonnet::write_log('course',$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 642  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 class="LC_error">'.&mt($msg).'</p>');              $r->print('<p><span class="LC_error">'.&mt($msg).'</span></p>');
         } else {          } else {
     $r->print("<p>$msg</p>");      $r->print("<p>$msg</p>");
         }          }
Line 672  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 class="LC_error">'.&mt($msg).'</p>');          $r->print('<p><span class="LC_error">'.&mt($msg).'</span></p>');
     } else {      } else {
         $r->print("<p>$msg</p>");          $r->print("<p>$msg</p>");
     }      }
Line 690  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 started.',$description));      return (0,&mt('Not allowed to release Reservation: [_1], as it has already ended.',$description));
  }   }
     }      }
     my $context = $env{'form.context'};  
   
     # get navmap object      # if the reservation symb is for a map get a resource in that map
       # to check slot parameters on
     my $navmap=Apache::lonnavmaps::navmap->new;      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 ($cnum,$cdom)=&get_course();  
   
     # get slot reservations, check if user has reservation  
     my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,  
                                        "^$slot_name\0");  
   
     #  
     # If release is because of a reservation *change*, symb(s) associated with reservation  
     # being dropped may differ from the current symb.  
     #  
     # We need to get symb(s) from slot_reservations.db, and for each symb, update  
     # the value of the availablestudent parameter, at the appropriate level  
     # (as dictated by the value of the useslots parameter for the symb and user).  
     #  
     # We also delete all entries for the slot being released, for the specific user.  
     #  
   
     my $conflict;  
   
     if (($env{'form.command'} eq 'change') && ($slot_name eq $env{'form.releaseslot'}) &&  
         ($env{'form.slotname'} ne $slot_name)) {  
         my %changedto = &Apache::lonnet::get_slot($env{'form.slotname'});  
   
         # check for conflicts  
         my ($to_uniq_start,$to_uniq_end,$from_uniq_start,$from_uniq_end);  
         if (ref($changedto{'uniqueperiod'}) eq 'ARRAY') {  
             ($to_uniq_start,$to_uniq_end) = @{$changedto{'uniqueperiod'}};  
         }  
         if (ref($slot{'uniqueperiod'}) eq 'ARRAY') {  
             ($from_uniq_start,$from_uniq_end) = @{$slot{'uniqueperiod'}};  
         }  
         my $to_start = $changedto{'starttime'};  
         my $to_end = $changedto{'endtime'};  
         my $from_start = $slot{'starttime'};  
         my $from_end = $slot{'endtime'};  
   
         if (!  
              ($from_start < $to_uniq_start && $from_end < $to_uniq_start) ||  
              ($from_start > $to_uniq_end   && $from_end > $to_uniq_end  )) {  
             $conflict = 1;  
         }  
         if (!  
              ($to_start < $from_uniq_start && $to_end < $from_uniq_start) ||  
              ($to_start > $from_uniq_end   && $to_end > $from_uniq_end  )) {  
             $conflict = 1;  
         }  
   
         if ($conflict) {  
             my %symbs_for_slot;  
             my (%to_delete,%failed,%released);  
             foreach my $entry (keys(%consumed)) {  
                 if ( $consumed{$entry}->{'name'} eq ($uname.':'.$udom) ) {  
                     $symbs_for_slot{$consumed{$entry}->{'symb'}} = 1;  
                     $to_delete{$entry} = 1;  
                 }  
             }  
             if (keys(%to_delete)) {  
                 my @removals = keys(%to_delete);  
                 if (&Apache::lonnet::del('slot_reservations',\@removals,  
                                      $cdom,$cnum) eq 'ok') {  
                     foreach my $item (keys(%symbs_for_slot)) {  
                         my $result = &update_selectable($navmap,$slot_name,$item,$cdom,  
                                                         $cnum,$udom,$uname,$context);  
                         if ($result =~ /^error/) {  
                             $failed{$item} = 1;  
                         } else {  
                             $released{$item} = 1;  
                         }  
                     }  
                 }  
             }  
             if (keys(%released)) {  
                 $msg = '<span style="font-weight: bold;">'.  
                        &mt('Released Reservation: [_1]',$description).'</span>&nbsp;&nbsp;'.  
                        &mt('The following items had their reservation status change').':';  
                 my (%folders,%pages,%container,%titles);  
                 foreach my $item (keys(%released)) {  
                     my $res = $navmap->getBySymb($item);  
                     if (ref($res)) {  
                         $titles{$item} = $res->title();  
                         if ($res->is_map()) {  
                             $folders{$item}{'title'} = $titles{$item};  
                             if ($res->is_page()) {  
                                 $pages{$item}{'title'} = $titles{$item};  
                             } else {  
                                 $folders{$item}{'title'} = $titles{$item};  
                             }  
                         } else {  
                             my $mapsrc = $res->enclosing_map_src();  
                             my $map = $navmap->getResourceByUrl($mapsrc);  
                             if (ref($map)) {  
                                 if ($map->id() eq '0.0') {  
                                     $container{$mapsrc}{'title'} &mt('Top level of course');  
                                 } else {  
                                     $container{$mapsrc}{'title'} = $map->title();  
                                     if ($map->is_page()) {  
                                         $container{$mapsrc}{'page'} = 1;  
                                     }  
                                 }  
                             }  
                             $container{$mapsrc}{'resources'}{$item} = 1;  
                         }  
                     }  
                 }  
                 $msg .= '<ul>';  
                 if (keys(%folders)) {  
                     $msg .= '<li>'.&mt('Folders').': '.  
                             join(', ', map { $folders{$_}{'title'} } (sort { $folders{$b}{'title'} cmp $folders{$a}{'title'} } (keys(%folders)))).  
                             '</li>';  
                 }  
                 if (keys(%pages)) {  
                     $msg .= '<li>'.&mt('Composite Pages').': '.  
                             join(', ', map { $pages{$_}{'title'} } (sort { $pages{$b}{'title'} cmp $pages{$a}{'title'} } (keys(%pages)))).  
                             '</li>';  
                 }  
                 if (keys(%container)) {  
                     $msg .= '<li>'.&mt('Resources').':<ul>';  
                     foreach my $key (sort { $container{$b}{'title'} cmp $container{$a}{'title'} } (keys(%container))) {  
                         if (ref($container{$key}{'resources'}) eq 'HASH') {  
                             $msg .= '<li>'.  
                                     join(', ', map { $titles{$_} } (sort(keys(%{$container{$key}{'resources'}}))));  
                             if ($container{$key}{'page'}) {  
                                 $msg .= ' '.&mt('(in composite page [_1])',$container{$key}{'title'}).'</li>';  
                             } else {  
                                 $msg .= ' '.&mt('(in folder [_1])',$container{$key}{'title'}).'</li>';  
                             }  
                         }  
                     }  
                     $msg .= '</ul></li>';  
                 }  
                 $msg .= '</ul>';  
                 my $person = &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'});  
                 my $subject = &mt('Reservation change: [_1]',$description);  
                 my $msgbody = &mt('Reservation released by [_1] for [_2].',$person,$description);  
                 $msg .= &slot_change_messaging($slot{'reservationmsg'},$subject,$msgbody,'release');  
                 return (1,$msg);  
             } else {  
                 if (keys(%to_delete)) {  
                     $msg = &mt('Reservation release partially complete for [_1]',$description);  
                 } else {  
                     $msg = &mt('No entries found for this user to release for [_1].',$description);  
                 }  
                 return (0,$msg);  
             }  
         } else {  
             $msg = &mt('No conflict found; not releasing: [_1].',$description);  
             return (0,$msg);  
         }  
     }  
   
     my $map_symb;  
     my $parm_symb = $symb;  
     my $passed_resource = $navmap->getBySymb($symb);      my $passed_resource = $navmap->getBySymb($symb);
   
     # if the reservation symb is for a map get a resource in that map  
     # to check slot parameters on  
     my $parm_level = 1;  
     if (ref($passed_resource)) {      if (ref($passed_resource)) {
         if ($passed_resource->is_map()) {          if ($passed_resource->is_map()) {
     my ($a_resource) =       my ($a_resource) = 
                 $navmap->retrieveResources($passed_resource,                   $navmap->retrieveResources($passed_resource, 
                                            sub {$_[0]->is_problem()},0,1);                                             sub {$_[0]->is_problem()},0,1);
             $parm_symb = $a_resource->symb();              $symb = $a_resource->symb();
         }          }
     } else {      } else {
         unless ($mgr eq 'F') {          unless ($mgr eq 'F') {
Line 875  sub release_reservation { Line 717  sub release_reservation {
         }          }
     }      }
   
     # Get value of useslots parameter in effect for this user.      # get parameter string, check for existence, rebuild string with the slot
     # If value is map or map_map, then the parm level is 2 (i.e.,      my $student = &Apache::lonnet::EXT("resource.0.availablestudent",
     # non-recursive enclosing map/folder level for specific user)                                         $symb,$udom,$uname);
     # and the symb for this reservation in slot_reservations.db      my @slots = split(/:/,$student);
     # will be the symb of the map itself.  
   
     my $use_slots = &Apache::lonnet::EXT('resource.0.useslots',  
                                          $parm_symb,$udom,$uname);  
     if (&Apache::lonnet::error($use_slots)) {  
         return (0,'error: Unable to determine current status');  
     }  
     if ($use_slots eq 'map' || $use_slots eq 'map_map') {  
         $parm_level = 2;  
         if ($passed_resource->is_map()) {  
             $map_symb = $passed_resource->symb();  
         } else {  
             my ($map) = &Apache::lonnet::decode_symb($symb);  
             $map_symb = &Apache::lonnet::symbread($map);  
         }  
     }  
   
     #      my @new_slots;
     # If release is *not* because of a reservation change, i.e., this is a "drop"      foreach my $exist_slot (@slots) {
     # by a student, or a removal for a single student by an instructor then   if ($exist_slot eq $slot_name) { next; }
     # only remove one entry from slot_reservations.db, where both the user   push(@new_slots,$exist_slot);
     # 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)) {  
         if ( $consumed{$entry}->{'name'} eq ($uname.':'.$udom) ) {  
             if ($consumed{$entry}->{'symb'} eq $symb_to_check) {  
                 if (&Apache::lonnet::del('slot_reservations',[$entry],  
                                          $cdom,$cnum) eq 'ok') {  
                     $match = $symb_to_check;  
                 }  
                 last;  
             }  
         }  
     }  
     if ($match) {  
         if (&update_selectable($navmap,$slot_name,$symb,$cdom,  
                                $cnum,$udom,$uname,$context) =~ /^error/) {  
             if ($mgr eq 'F') {  
                 $msg = &mt('Reservation release partially complete for: [_1]',"$uname:$udom").'<br />'.  
                        &mt('Update of availablestudent parameter for [_1] was not completed.',"$uname:$udom");  
             } else {  
                 $msg = &mt('Release partially complete for: [_1]',$description);  
             }  
             return (0,$msg);  
         } else {  
             if ($mgr eq 'F') {  
                 $msg = &mt('Released Reservation for user: [_1]',"$uname:$udom");  
             } else {  
                 $msg = '<span style="font-weight: bold;">'.&mt('Released reservation: [_1]',$description).'</span><br /><br />';  
                 my $person = &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'});  
                 my $subject = &mt('Reservation change: [_1]',$description);  
                 my $msgbody = &mt('Reservation released by [_1] for [_2].',$person,$description);  
                 $msg .= &slot_change_messaging($slot{'reservationmsg'},$subject,$msgbody,'release');  
             }  
             return (1,$msg);  
         }  
     } else {  
         $msg = &mt('Release failed for: [_1]',$description);  
         return (0,$msg);  
     }      }
 }      my $new_param = join(':',@new_slots);
   
 sub update_selectable {      my ($cnum,$cdom)=&get_course();
     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      # get slot reservations, check if user has one, if so remove reservation
     # to check slot parameters on      my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
     if ($passed_resource->is_map()) {         "^$slot_name\0");
         my ($a_resource) =      foreach my $entry (keys(%consumed)) {
             $navmap->retrieveResources($passed_resource,   if ( $consumed{$entry}->{'name'} eq ($uname.':'.$udom) ) {
                                        sub {$_[0]->is_problem()},0,1);      &Apache::lonnet::del('slot_reservations',[$entry],
         $symb_for_parm = $a_resource->symb();   $cdom,$cnum);
               my %storehash = (
                                  symb    => $symb,
                                  slot    => $slot_name,
                                  action  => 'release',
                                  context => $env{'form.context'},
                           );
               &Apache::lonnet::write_log('slotreservationslog',\%storehash,
                                          1,$uname,$udom,$cnum,$cdom);
               &Apache::lonnet::write_log($cdom.'_'.$cnum.'_slotlog',\%storehash,
                                          1,$uname,$udom,$uname,$udom);
    }
     }      }
     # 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.      my $use_slots = &Apache::lonnet::EXT("resource.0.useslots",
     # If value is map or map_map, then the parm level is 2 (i.e.,   $symb,$udom,$uname);
     # 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',  
                                          $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 'error: Unable to determine current status';   return (0,'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 @slots = split(/:/,$student);      my $result=&Apache::lonparmset::storeparm_by_symb($symb,
         '0_availablestudent',
     my @new_slots;        $parm_level, $new_param,
     foreach my $exist_slot (@slots) {        'string', $uname, $udom);
         next if ($exist_slot eq $slot_name);      my $msg;
         push(@new_slots,$exist_slot);      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');
     }      }
     my $new_value = join(':',@new_slots);      return (1,$msg);
   
     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 1022  sub delete_slot { Line 800  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 class="LC_error">'.&mt('An error occurred when attempting to delete slot: [_1]','<tt>'.$slot_name.'</tt>')." ($ret)</p>");      $r->print('<p><span class="LC_error">'.&mt('An error occurred when attempting to delete slot: [_1]','<tt>'.$slot_name.'</tt>')." ($ret)</span></p>");
  }   }
     } else {      } else {
  if (%consumed) {   if (%consumed) {
Line 1054  sub get_slot { Line 832  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 class="LC_error">'   $r->print('<p><span 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)
                  .'</p>');                   .'</span></p>');
  &return_link($r);   &return_link($r);
  return 0;   return 0;
     }      }
Line 1109  STUFF Line 887  STUFF
     if (defined($reserved)) {      if (defined($reserved)) {
  my $retvalue = 0;   my $retvalue = 0;
  if ($slot_name =~ /^error: (.*)/) {   if ($slot_name =~ /^error: (.*)/) {
     $r->print('<p class="LC_error">'      $r->print('<p><span 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)
                      .'</p>');                       .'</span></p>');
  } elsif ($reserved > -1) {   } elsif ($reserved > -1) {
     $r->print('<p style="font-weight: bold;">'.&mt('Successfully signed up:  [_1]',$description).'</p>');      $r->print('<p style="font-weight: bold;">'.&mt('Successfully signed up:  [_1]',$description).'</p>');
     $retvalue = 1;      $retvalue = 1;

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


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