--- loncom/interface/slotrequest.pm 2006/03/30 04:34:32 1.54
+++ loncom/interface/slotrequest.pm 2019/06/22 19:07:58 1.140
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Handler for requesting to have slots added to a students record
#
-# $Id: slotrequest.pm,v 1.54 2006/03/30 04:34:32 albertel Exp $
+# $Id: slotrequest.pm,v 1.140 2019/06/22 19:07:58 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -36,12 +36,15 @@ use Apache::lonlocal;
use Apache::lonnet;
use Apache::lonnavmaps();
use Date::Manip;
+use lib '/home/httpd/lib/perl/';
+use LONCAPA qw(:DEFAULT :match);
sub fail {
my ($r,$code)=@_;
if ($code eq 'not_valid') {
$r->print('
'.&mt('Unable to understand what resource you wanted to sign up for.').'
');
+ }
+
+ if (!$inhibit_return_link) { &return_link($r); }
+ return $result;
+}
+
+sub release_reservation {
+ my ($slot_name,$uname,$udom,$symb,$mgr) = @_;
my %slot=&Apache::lonnet::get_slot($slot_name);
- my $description=&get_description($env{'form.slotname'},\%slot);
+ my $description=&get_description($slot_name,\%slot);
if ($mgr ne 'F') {
if ($slot{'starttime'} < time) {
- $r->print("
Not allowed to release Reservation: $description, as it has already ended.
");
- &return_link($r);
- return 0;
+ return (0,&mt('Not allowed to release Reservation: [_1], as it has already ended.',$description));
}
}
- # get parameter string, check for existance, rebuild string with the slot
- my @slots = split(/:/,&Apache::lonnet::EXT("resource.0.availablestudent",
- $symb,$udom,$uname));
+
+ # if the reservation symb is for a map get a resource in that map
+ # to check slot parameters on
+ my $navmap=Apache::lonnavmaps::navmap->new;
+ if (!defined($navmap)) {
+ return (0,'error: Unable to determine current status');
+ }
+ my $passed_resource = $navmap->getBySymb($symb);
+ if (ref($passed_resource)) {
+ if ($passed_resource->is_map()) {
+ my ($a_resource) =
+ $navmap->retrieveResources($passed_resource,
+ sub {$_[0]->is_problem() || $_[0]->is_tool() },0,1);
+ $symb = $a_resource->symb();
+ }
+ } else {
+ unless ($mgr eq 'F') {
+ return (0,'error: Unable to determine current status');
+ }
+ }
+
+ # get parameter string, check for existence, rebuild string with the slot
+ my $student = &Apache::lonnet::EXT("resource.0.availablestudent",
+ $symb,$udom,$uname);
+ my @slots = split(/:/,$student);
my @new_slots;
foreach my $exist_slot (@slots) {
@@ -376,28 +826,70 @@ sub release_slot {
}
my $new_param = join(':',@new_slots);
- # get slot reservations, check if user has one, if so remove reservation
+ # 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",
+ $symb,$udom,$uname);
+ &Apache::lonxml::debug("use_slots is $use_slots ");
+
+ if (&Apache::lonnet::error($use_slots)) {
+ return (0,'error: Unable to determine current status');
+ }
+
+ my $parm_level = 1;
+ my $parm_symb = $passed_resource->symb();
+ if ($use_slots eq 'map' || $use_slots eq 'map_map') {
+ $parm_level = 2;
+ unless ($passed_resource->is_map()) {
+ my ($map) = &Apache::lonnet::decode_symb($parm_symb);
+ $parm_symb = &Apache::lonnet::symbread($map);
+ }
+ }
+
+ my ($cnum,$cdom)=&get_course();
+
+ # get slot reservations, check if user has one for the
+ # correct symb, and if so, remove the reservation
my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
"^$slot_name\0");
foreach my $entry (keys(%consumed)) {
- if ( $consumed{$entry}->{'name'} eq ($uname.'@'.$udom) ) {
+ if (($consumed{$entry}->{'name'} eq $uname.':'.$udom) &&
+ ($consumed{$entry}->{'symb'} eq $parm_symb)) {
&Apache::lonnet::del('slot_reservations',[$entry],
$cdom,$cnum);
+ my %storehash = (
+ symb => $symb,
+ slot => $slot_name,
+ action => 'release',
+ context => $env{'form.context'},
+ );
+ &Apache::lonnet::write_log('course','slotreservationslog',
+ \%storehash,1,$uname,$udom,$cnum,$cdom);
+ &Apache::lonnet::write_log('course',$cdom.'_'.$cnum.'_slotlog',
+ \%storehash,1,$uname,$udom,$uname,$udom);
}
}
# store new parameter string
my $result=&Apache::lonparmset::storeparm_by_symb($symb,
'0_availablestudent',
- 1, $new_param, 'string',
- $uname,$udom);
- $r->print("
Released Reservation: $description
");
+ $parm_level, $new_param,
+ 'string', $uname, $udom);
+ my $msg;
if ($mgr eq 'F') {
- $r->print('
');
+ }
}
sub get_slot {
- my ($r,$symb)=@_;
+ my ($r,$symb,$conflictable_slot,$inhibit_return_link)=@_;
my %slot=&Apache::lonnet::get_slot($env{'form.slotname'});
my $slot_name=&check_for_conflict($symb,$env{'form.slotname'},\%slot);
if ($slot_name =~ /^error: (.*)/) {
- $r->print("
An error occured while attempting to make a reservation. ($1)
");
+ $r->print('
'
+ .&mt('An error occurred while attempting to make a reservation. ([_1])',$1)
+ .'
');
&return_link($r);
- return;
+ return 0;
}
- if ($slot_name) {
+ if ($slot_name && $slot_name ne $conflictable_slot) {
my %slot=&Apache::lonnet::get_slot($slot_name);
my $description1=&get_description($slot_name,\%slot);
+ my $slottype1=$slot{'type'};
%slot=&Apache::lonnet::get_slot($env{'form.slotname'});
my $description2=&get_description($env{'form.slotname'},\%slot);
- $r->print("
Already have a reservation: $description1
");
- if ($slot_name ne $env{'form.slotname'}) {
+ if ($slottype1 eq 'preassigned') {
+ $r->print('
'.&mt('You already have a reservation: "[_1]", assigned by your instructor.',
+ $description1).'
'.
+ '
'.&mt('Your instructor must unassign it before you can make a new reservation.').
+ '
');
+ } elsif ($slot_name ne $env{'form.slotname'}) {
$r->print(<
+
-
-?
-or
-
-
-or
STUFF
- &return_link($r);
- return;
+ if (!$inhibit_return_link) {
+ $r->print(&mt('or').'');
+ &return_link($r);
+ } else {
+ $r->print('');
+ }
+ return 0;
}
sub allowed_slot {
- my ($slot_name,$slot,$symb,$slots,$consumed_uniqueperiods)=@_;
+ my ($slot_name,$slot,$symb,$slots,$consumed_uniqueperiods,$toskip)=@_;
#already started
if ($slot->{'starttime'} < time) {
- # all open slot to be schedulable
- #return 0;
+ return 0;
}
&Apache::lonxml::debug("$slot_name starttime good");
@@ -552,6 +1083,11 @@ sub allowed_slot {
if ($slot->{'startreserve'} > time) {
return 0;
}
+ # reserve time ended
+ if (($slot->{'endreserve'}) &&
+ ($slot->{'endreserve'} < time)) {
+ return 0;
+ }
&Apache::lonxml::debug("$slot_name reserve good");
my $userallowed=0;
@@ -567,6 +1103,16 @@ sub allowed_slot {
split(',',$slot->{'allowedsections'}))) {
$userallowed=1;
}
+ if (defined($env{'request.course.groups'})) {
+ my @groups = split(/:/,$env{'request.course.groups'});
+ my @allowed_sec = split(',',$slot->{'allowedsections'});
+ foreach my $group (@groups) {
+ if (grep {$_ eq $group} (@allowed_sec)) {
+ $userallowed=1;
+ last;
+ }
+ }
+ }
}
&Apache::lonxml::debug("$slot_name sections is $userallowed");
@@ -586,14 +1132,40 @@ sub allowed_slot {
return 0 if (!$userallowed);
# not allowed for this resource
- if (defined($slot->{'symb'})
- && $slot->{'symb'} ne $symb) {
- return 0;
+ if (defined($slot->{'symb'})) {
+ my $exclude = 1;
+ my @symbs;
+ if ($slot->{'symb'} =~ /,/) {
+ @symbs = split(/\s*,\s*/,$slot->{'symb'});
+ } else {
+ @symbs = ($slot->{'symb'});
+ }
+ my ($map,$id,$url) = &Apache::lonnet::decode_symb($symb);
+ foreach my $reqsymb (@symbs) {
+ next if ($reqsymb eq '');
+ my ($slotmap,$slotid,$sloturl) = &Apache::lonnet::decode_symb($reqsymb);
+ if ($sloturl=~/\.(page|sequence)$/) {
+ if (($map ne '') && ($map eq $sloturl)) {
+ $exclude = 0;
+ last;
+ }
+ } elsif ($reqsymb eq $symb) {
+ $exclude = 0;
+ last;
+ }
+ }
+ if ($exclude) {
+ unless ((ref($toskip) eq 'HASH') && ($toskip->{'symb'})) {
+ return 0;
+ }
+ }
}
my $conflict = &check_for_conflict($symb,$slot_name,$slot,$slots,
$consumed_uniqueperiods);
- if ($conflict) {
+ if ($conflict =~ /^error: /) {
+ return 0;
+ } elsif ($conflict ne '') {
if ($slots->{$conflict}{'starttime'} < time) {
return 0;
}
@@ -614,67 +1186,175 @@ sub get_description {
}
sub show_choices {
- my ($r,$symb)=@_;
-
- my ($cnum,$cdom)=&get_course();
- my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum);
- my $consumed_uniqueperiods = &get_consumed_uniqueperiods(\%slots);
- my $available;
- $r->print('
');
+ my ($symb,$formname,$num,$class,$slots,$consumed_uniqueperiods,$available,$got_slots)=@_;
+ my $output;
&Apache::lonxml::debug("Checking Slots");
- my @got_slots=&check_for_reservation($symb,'allslots');
- foreach my $slot (sort
- { return $slots{$a}->{'starttime'} <=> $slots{$b}->{'starttime'} }
- (keys(%slots))) {
-
- &Apache::lonxml::debug("Checking Slot $slot");
- next if (!&allowed_slot($slot,$slots{$slot},undef,\%slots,
- $consumed_uniqueperiods));
-
- $available++;
-
- my $description=&get_description($slot,$slots{$slot});
+ if (!ref($available) eq 'ARRAY') {
+ return;
+ }
+ if (!@{$available}) {
+ $output = ''.&mt('No available times.').'';
+ if ($env{'form.command'} ne 'manageresv') {
+ $output .= ' '.
+ &mt('Return to last resource').'';
+ }
+ if ($class) {
+ return '
'.$output.'
';
+ } else {
+ return $output;
+ }
+ }
+ if (@{$available} > 1) {
+ my $numavailable = scalar(@{$available});
+ my $numreserved = 0;
+ my $js;
+ my $j = 0;
+ foreach my $got (@{$got_slots}) {
+ unless (($got eq '') || (!defined($got))) {
+ $numreserved ++;
+ if ($env{'form.command'} eq 'manageresv') {
+ $js .= " currslot[$j]='$got';\n";
+ $j++;
+ }
+ }
+ }
+ my $showfilter = 'none';
+ $output .= '';
+ }
+ if ($class) {
+ return '
'.$output.'
';
+ } else {
+ return $output;
}
- $r->print('
');
}
sub to_show {
@@ -743,16 +1423,22 @@ sub to_show {
sub remove_link {
my ($slotname,$entry,$uname,$udom,$symb) = @_;
- $slotname = &Apache::lonnet::escape($slotname);
- $entry = &Apache::lonnet::escape($entry);
- $uname = &Apache::lonnet::escape($uname);
- $udom = &Apache::lonnet::escape($udom);
- $symb = &Apache::lonnet::escape($symb);
+ my $remove = &mt('Remove');
- my $remove= &mt('Remove');
+ if ($entry eq 'remove all') {
+ $remove = &mt('Remove All');
+ undef($uname);
+ undef($udom);
+ }
+
+ $slotname = &escape($slotname);
+ $entry = &escape($entry);
+ $uname = &escape($uname);
+ $udom = &escape($udom);
+ $symb = &escape($symb);
return <<"END_LINK";
- ($remove)
END_LINK
@@ -762,22 +1448,38 @@ sub show_table {
my ($r,$mgr)=@_;
my ($cnum,$cdom)=&get_course();
+ my $crstype=&Apache::loncommon::course_type($cdom.'_'.$cnum);
my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum);
if ( (keys(%slots))[0] =~ /^error: 2 /) {
undef(%slots);
}
my $available;
if ($mgr eq 'F') {
+ # FIXME: This line should be deleted once Slots uses breadcrumbs
+ $r->print(' '.&Apache::loncommon::help_open_topic(
+ 'Slot About', &mt('Help on slots')));
+
$r->print('