--- loncom/interface/slotrequest.pm 2018/07/02 20:34:52 1.139 +++ loncom/interface/slotrequest.pm 2023/07/07 03:52:40 1.145 @@ -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.139 2018/07/02 20:34:52 raeburn Exp $ +# $Id: slotrequest.pm,v 1.145 2023/07/07 03:52:40 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -56,10 +56,13 @@ sub fail { } sub start_page { - my ($r,$title,$brcrum,$js)=@_; + my ($r,$title,$brcrum,$bread_crumbs_component,$js,$mgr)=@_; my $args; if (ref($brcrum) eq 'ARRAY') { $args = {bread_crumbs => $brcrum}; + if ($bread_crumbs_component) { + $args->{bread_crumbs_component} = $bread_crumbs_component; + } } if (($env{'form.requestattempt'}) || ($env{'form.command'} eq 'manageresv')) { my %loaditems = ( @@ -71,6 +74,31 @@ sub start_page { $args = { 'add_entries' => \%loaditems }; } } + unless (($env{'form.context'} eq 'usermanage') || (($mgr eq 'F') && + (($env{'form.command'} eq 'release') || + ($env{'form.command'} eq 'remove_registration')))) { + if ($env{'form.symb'}) { + my $symb=&unescape($env{'form.symb'}); + my ($mapurl,$id,$resurl) = &Apache::lonnet::decode_symb($symb); + if ($resurl =~ /ext\.tool$/) { + my $target; + my ($marker,$exttool) = (split(m{/},$resurl))[3,4]; + $marker=~s/\D//g; + if (($marker) && ($exttool) && ($env{'request.course.id'})) { + my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + my ($idx,$crstool,$is_tool,%toolhash,%toolsettings); + if ($resurl eq "adm/$cdom/$cnum/$marker/$exttool") { + my %toolsettings=&Apache::lonnet::dump('exttool_'.$marker,$cdom,$cnum); + $target = $toolsettings{'target'}; + } + } + if ($target eq 'iframe') { + $args->{'only_body'} = 1; + } + } + } + } $r->print(&Apache::loncommon::start_page($title,$js,$args)); } @@ -553,11 +581,11 @@ sub make_reservation { return 'error: Unable to determine current status'; } - my $parm_symb = $symb; + my $symb_for_db = $symb; my $parm_level = 1; if ($use_slots eq 'map' || $use_slots eq 'map_map') { my ($map) = &Apache::lonnet::decode_symb($symb); - $parm_symb = &Apache::lonnet::symbread($map); + $symb_for_db = &Apache::lonnet::symbread($map); $parm_level = 2; } @@ -600,7 +628,7 @@ sub make_reservation { my %reservation=('name' => $env{'user.name'}.':'.$env{'user.domain'}, 'timestamp' => time, - 'symb' => $parm_symb); + 'symb' => $symb_for_db); my $success=&Apache::lonnet::newput('slot_reservations', {"$slot_name\0$wanted" => @@ -612,7 +640,9 @@ sub make_reservation { if ($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; } @@ -621,29 +651,27 @@ sub make_reservation { } sub store_slot_parm { - my ($symb,$slot_name,$parm_level,$new_value,$cnum,$cdom) = @_; - my $result=&Apache::lonparmset::storeparm_by_symb($symb, - '0_availablestudent', - $parm_level, $new_value, - 'string', - $env{'user.name'}, - $env{'user.domain'}); + my ($symb_for_parm,$symb_for_db,$slot_name,$parm_level,$new_value, + $cnum,$cdom,$uname,$udom,$action,$context,$delflag) = @_; + + # store new parameter string + my $result=&Apache::lonparmset::storeparm_by_symb($symb_for_parm, + '0_availablestudent', + $parm_level,$new_value, + 'string',$uname,$udom); &Apache::lonxml::debug("hrrm $result"); my %storehash = ( - symb => $symb, + symb => $symb_for_db, slot => $slot_name, - action => 'reserve', - context => $env{'form.context'}, + action => $action, + context => $context, ); &Apache::lonnet::write_log('course','slotreservationslog',\%storehash, - '',$env{'user.name'},$env{'user.domain'}, - $cnum,$cdom); + $delflag,$uname,$udom,$cnum,$cdom); &Apache::lonnet::write_log('course',$cdom.'_'.$cnum.'_slotlog',\%storehash, - 1,$env{'user.name'},$env{'user.domain'}, - $env{'user.name'},$env{'user.domain'}); - - return; + $delflag,$uname,$udom,$uname,$udom); + return $result; } sub remove_registration { @@ -739,7 +767,7 @@ sub release_all_slot { &release_reservation($slot_name,$uname,$udom, $consumed{$entry}{'symb'},$mgr); if (!$result) { - $r->print('
'.&mt($msg).'
'); + $r->print(''.&mt($msg).'
'); } else { $r->print("$msg
"); } @@ -769,7 +797,7 @@ sub release_slot { my ($result,$msg) = &release_reservation($slot_name,$uname,$udom,$symb,$mgr); if (!$result) { - $r->print(''.&mt($msg).'
'); + $r->print(''.&mt($msg).'
'); } else { $r->print("$msg
"); } @@ -787,26 +815,184 @@ sub release_reservation { my ($slot_name,$uname,$udom,$symb,$mgr) = @_; my %slot=&Apache::lonnet::get_slot($slot_name); my $description=&get_description($slot_name,\%slot); + my $msg; if ($mgr ne 'F') { 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 - # to check slot parameters on + # get navmap object my $navmap=Apache::lonnavmaps::navmap->new; if (!defined($navmap)) { 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 = ''. + &mt('Released Reservation: [_1]',$description).' '. + &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 .= ''.&mt('Slot [_1] marked as deleted.',''.$slot_name.'').'
'); } else { - $r->print(''.&mt('An error occurred when attempting to delete slot: [_1]',''.$slot_name.'')." ($ret)
"); + $r->print(''.&mt('An error occurred when attempting to delete slot: [_1]',''.$slot_name.'')." ($ret)
"); } } else { if (%consumed) { @@ -913,15 +1163,32 @@ sub delete_slot { sub return_link { my ($r) = @_; + my $target = &return_target(); if (($env{'form.command'} eq 'manageresv') || ($env{'form.context'} eq 'usermanage')) { - $r->print(''.
- &mt('Return to reservations'));
+ $r->print(' '.
+ &mt('Return to reservations').' '.
+ $r->print(' '.
&mt('Return to last resource').' '
+ $r->print(' '
.&mt('An error occurred while attempting to make a reservation. ([_1])',$1)
- .' '
+ $r->print(' '
.&mt('An error occurred while attempting to make a reservation. ([_1])',$1)
- .'
'.&mt('Successfully signed up: [_1]',$description).'
'); $retvalue = 1; @@ -1181,7 +1448,8 @@ sub show_choices { if (!@{$available}) { $output = ''.&mt('No available times.').''; if ($env{'form.command'} ne 'manageresv') { - $output .= ' '. + my $target = &return_target(); + $output .= ' '. &mt('Return to last resource').''; } if ($class) { @@ -1441,10 +1709,6 @@ sub show_table { } my $available; if ($mgr eq 'F') { - # FIXME: This line should be deleted once Slots uses breadcrumbs - $r->print(''.
''.&mt('Changes/page:').' '. - &Apache::lonmeta::selectbox('show',$curr->{'show'},undef, + &Apache::lonmeta::selectbox('show',$curr->{'show'},'',undef, (&mt('all'),5,10,20,50,100,1000,10000)). ' | '; my $startform = @@ -3078,6 +3342,9 @@ sub csv_upload_assign { 'secret','symb') { if ($entries{$fields{$key}}) { $slot{$key}=$entries{$fields{$key}}; + if ($key eq 'maxspace') { + $slot{$key} =~ s/\D+//g; + } } } if ($entries{$fields{'iptied'}} =~ /^\s*(yes|1)\s*$/i) { @@ -3185,7 +3452,7 @@ sub handler { &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}); my %crumb_titles = &slot_command_titles(); - my $brcrum; + my ($brcrum,$bread_crumbs_component); my $vgr=&Apache::lonnet::allowed('vgr',$env{'request.course.id'}); my $mgr=&Apache::lonnet::allowed('mgr',$env{'request.course.id'}); @@ -3221,8 +3488,10 @@ sub handler { } elsif ($vgr eq 'F') { if ($env{'form.command'} =~ /^(slotlog|showslots|uploadstart|csvuploadmap|csvuploadassign|delete|release|remove_registration)$/) { $brcrum =[{href=>"/adm/slotrequest?command=showslots", - text=>$crumb_titles{'showslots'}}]; + text=>$crumb_titles{'showslots'}, + help=>'Slot_Use'}]; $title = 'Managing Slots'; + $bread_crumbs_component = 'Slots'; unless ($env{'form.command'} eq 'showslots') { if (ref($brcrum) eq 'ARRAY') { push(@{$brcrum},{href=>"/adm/slotrequest?command=$env{'form.command'}",text=>$crumb_titles{$env{'form.command'}}}); @@ -3250,7 +3519,7 @@ sub handler { 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); + &start_page($r,$title,$brcrum,$bread_crumbs_component,$js,$mgr); if ($env{'form.command'} eq 'manageresv') { $allavailable = $available; |