--- loncom/interface/slotrequest.pm 2005/11/08 03:13:20 1.29 +++ loncom/interface/slotrequest.pm 2005/12/14 22:26:10 1.37 @@ -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.29 2005/11/08 03:13:20 albertel Exp $ +# $Id: slotrequest.pm,v 1.37 2005/12/14 22:26:10 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -231,17 +231,55 @@ sub make_reservation { return undef; } +sub remove_registration { + my ($r) = @_; + my $name = &Apache::loncommon::plainname($env{'form.uname'}, + $env{'form.udom'}); + + my $title = &Apache::lonnet::gettitle($env{'form.symb'}); + + my $hidden_input; + foreach my $parm ('uname','udom','slotname','entry','symb') { + $hidden_input .= + '&\'').'" />'."\n"; + } + $r->print(<<"END_CONFIRM"); +

Remove $name from slot $env{'form.slotname'} for $title

+
+ + $hidden_input + +
+
+ + +
+END_CONFIRM + +} + sub release_slot { - my ($r,$symb,$slot_name,$inhibit_return_link)=@_; + my ($r,$symb,$slot_name,$inhibit_return_link,$mgr)=@_; if ($slot_name eq '') { $slot_name=$env{'form.slotname'}; } my ($cnum,$cdom)=&get_course(); + my ($uname,$udom) = ($env{'user.name'}, $env{'user.domain'}); + if ($mgr eq 'F' + && defined($env{'form.uname'}) && defined($env{'form.udom'})) { + ($uname,$udom) = ($env{'form.uname'}, $env{'form.udom'}); + } + + if ($mgr eq 'F' + && defined($env{'form.symb'})) { + $symb = $env{'form.symb'}; + } + # get parameter string, check for existance, rebuild string with the slot - my @slots = split(/:/,&Apache::lonnet::EXT("resource.0.availablestudent", - $symb,$env{'user.domain'}, - $env{'user.name'})); + $symb,$udom,$uname)); + my @new_slots; foreach my $exist_slot (@slots) { if ($exist_slot eq $slot_name) { next; } @@ -253,21 +291,24 @@ sub release_slot { my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum, "^$slot_name\0"); foreach my $entry (keys(%consumed)) { - if ( $consumed{$entry}->{'name'} eq - ($env{'user.name'}.'@'.$env{'user.domain'}) ) { + if ( $consumed{$entry}->{'name'} eq ($uname.'@'.$udom) ) { &Apache::lonnet::del('slot_reservations',[$entry], $cdom,$cnum); } } + # store new parameter string my $result=&Apache::lonparmset::storeparm_by_symb($symb, '0_availablestudent', 1, $new_param, 'string', - $env{'user.name'}, - $env{'user.domain'}); + $uname,$udom); my %slot=&Apache::lonnet::get_slot($slot_name); my $description=&get_description($env{'form.slotname'},\%slot); $r->print("

Released Reservation: $description

"); + if ($mgr eq 'F') { + $r->print('

'. + &mt('Return to slot list').'

'); + } if (!$inhibit_return_link) { $r->print('

'. &mt('Return to last resource').'

'); @@ -275,6 +316,38 @@ sub release_slot { return 1; } +sub delete_slot { + my ($r)=@_; + + my $slot_name = $env{'form.slotname'}; + my %slot=&Apache::lonnet::get_slot($slot_name); + + my ($cnum,$cdom)=&get_course(); + my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum, + "^$slot_name\0"); + + if (%slot && !%consumed) { + $slot{'type'} = 'deleted'; + my $ret = &Apache::lonnet::cput('slots', {$slot_name => \%slot}, + $cdom, $cnum); + if ($ret eq 'ok') { + $r->print("

Slot $slot_name marked as deleted.

"); + } else { + $r->print("

An error ($ret) occurse when attempting to delete Slot $slot_name.

"); + } + } else { + if (%consumed) { + $r->print("

Slot $slot_name has active reservations.

"); + } else { + $r->print("

Slot $slot_name does not exist.

"); + } + } + $r->print('

'. + &mt('Return to slot list').'

'); + $r->print('

'. + &mt('Return to last resource').'

'); +} + sub get_slot { my ($r,$symb)=@_; @@ -450,6 +523,72 @@ STUFF $r->print(''); } +sub to_show { + my ($slot,$when,$deleted) = @_; + my $time=time; + my $week=60*60*24*7; + if ($deleted eq 'hide' && $slot->{'type'} eq 'deleted') { + return 0; + } + if ($when eq 'any') { + return 1; + } elsif ($when eq 'now') { + if ($time > $slot->{'starttime'} && + $time < $slot->{'endtime'}) { + return 1; + } + return 0; + } elsif ($when eq 'nextweek') { + if ( ($time < $slot->{'starttime'} && + ($time+$week) > $slot->{'starttime'}) + || + ($time < $slot->{'endtime'} && + ($time+$week) > $slot->{'endtime'}) ) { + return 1; + } + return 0; + } elsif ($when eq 'lastweek') { + if ( ($time > $slot->{'starttime'} && + ($time-$week) < $slot->{'starttime'}) + || + ($time > $slot->{'endtime'} && + ($time-$week) < $slot->{'endtime'}) ) { + return 1; + } + return 0; + } elsif ($when eq 'willopen') { + if ($time < $slot->{'starttime'}) { + return 1; + } + return 0; + } elsif ($when eq 'wereopen') { + if ($time > $slot->{'endtime'}) { + return 1; + } + return 0; + } + + return 1; +} + +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'); + + return <<"END_LINK"; + ($remove) +END_LINK + +} + sub show_table { my ($r,$mgr)=@_; @@ -460,6 +599,7 @@ sub show_table { } my $available; if ($mgr eq 'F') { + $r->print('
'); $r->print('
@@ -467,14 +607,18 @@ sub show_table { $r->print('
'); + $r->print('
'); } - my %Saveable_Parameters = ('show' => 'array'); - - &Apache::loncommon::store_course_settings('chart',\%Saveable_Parameters); - &Apache::loncommon::restore_course_settings('chart',\%Saveable_Parameters); + my %Saveable_Parameters = ('show' => 'array', + 'when' => 'scalar', + 'order' => 'scalar', + 'deleted' => 'scalar', + ); + &Apache::loncommon::store_course_settings('slotrequest',\%Saveable_Parameters); + &Apache::loncommon::restore_course_settings('slotrequest',\%Saveable_Parameters); - my %fields=&Apache::lonlocal::texthash( + my %show_fields=&Apache::lonlocal::texthash( 'name' => 'Slot Name', 'description' => 'Description', 'type' => 'Type', @@ -482,31 +626,71 @@ sub show_table { 'endtime' => 'End Time', 'startreserve' => 'Time students can start reserving', 'secret' => 'Secret Word', - 'maxspace' => 'Maxium # of students', + 'maxspace' => 'Maximum # of students', 'ip' => 'IP or DNS restrictions', 'symb' => 'Resource slot is restricted to.', 'uniqueperiod' => 'Period of time slot is unique', 'proctor' => 'List of proctors'); - my @order=('name','description','type','starttime','endtime', + my @show_order=('name','description','type','starttime','endtime', 'startreserve','secret','maxspace','ip','symb', 'uniqueperiod','proctor'); - my @sel = + my @show = (exists($env{'form.show'})) ? &Apache::loncommon::get_env_multiple('form.show') - : keys(%fields); - my %sel = map { $_ => 1 } (@sel); + : keys(%show_fields); + my %show = map { $_ => 1 } (@show); + my %when_fields=&Apache::lonlocal::texthash( + 'now' => 'Open now', + 'nextweek' => 'Open within the next week', + 'lastweek' => 'Were open last week', + 'willopen' => 'Will open later', + 'wereopen' => 'Were open', + 'any' => 'Anytime', + ); + my @when_order=('any','now','nextweek','lastweek','willopen','wereopen'); + $when_fields{'select_form_order'} = \@when_order; + my $when = (exists($env{'form.when'})) ? $env{'form.when'} + : 'now'; + + my $hide_radio = + &Apache::lonhtmlcommon::radio('deleted',$env{'form.deleted'},'hide'); + my $show_radio = + &Apache::lonhtmlcommon::radio('deleted',$env{'form.deleted'},'show'); + $r->print('
- -'); - $r->print('
Show: '.&Apache::loncommon::multiple_select_form('show',\@sel,6,\%fields,\@order). - '
'); +'); + $r->print('
'); + $r->print(' + + + + + + + + +
'.&mt('Show').''.&mt('Open').''.&mt('Options').'
'.&Apache::loncommon::multiple_select_form('show',\@show,6,\%show_fields,\@show_order). + ''.&Apache::loncommon::select_form($when,'when',%when_fields). + ' + + + + + + + + +
Deleted slots:
+
'); + $r->print('
'); + $r->print('

'); my $linkstart=' + $r->print(''); - foreach my $which (@order) { - if ($which ne 'proctor' && exists($sel{$which})) { - $r->print(''); + foreach my $which (@show_order) { + if ($which ne 'proctor' && exists($show{$which})) { + $r->print(''); } } $r->print(''); @@ -539,6 +723,7 @@ sub show_table { return $slots{$a}->{'starttime'} <=> $slots{$b}->{'starttime'}; }; foreach my $slot (sort $slotsort (keys(%slots))) { + if (!&to_show($slots{$slot},$when,$env{'form.deleted'})) { next; } if (defined($slots{$slot}->{'type'}) && $slots{$slot}->{'type'} ne 'schedulable_student') { #next; @@ -549,8 +734,13 @@ sub show_table { my $ids; foreach my $entry (sort(keys(%consumed))) { my (undef,$id)=split("\0",$entry); - $ids.= $id.'-> '.$consumed{$entry}->{'name'}.'
'; + my ($uname,$udom) = split('@',$consumed{$entry}{'name'}); + my $name = &Apache::loncommon::plainname($uname,$udom); + $ids.= ''.$name.&remove_link($slot,$entry,$uname,$udom, + $consumed{$entry}{'symb'}) + .'
'; } + my $start=($slots{$slot}->{'starttime'}? &Apache::lonlocal::locallocaltime($slots{$slot}->{'starttime'}):''); my $end=($slots{$slot}->{'endtime'}? @@ -563,6 +753,7 @@ sub show_table { $unique=localtime($slots{$slot}{'uniqueperiod'}[0]).','. localtime($slots{$slot}{'uniqueperiod'}[1]); } + my $title; if (exists($slots{$slot}{'symb'})) { my (undef,undef,$res)= @@ -571,10 +762,11 @@ sub show_table { $title = &Apache::lonnet::gettitle($slots{$slot}{'symb'}); $title=''.$title.''; } + my @proctors; my $rowspan=1; my $colspan=1; - if (exists($sel{'proctor'})) { + if (exists($show{'proctor'})) { $rowspan=2; @proctors= map { my ($uname,$udom)=split(/@/,$_); @@ -590,49 +782,51 @@ sub show_table { } my $proctors=join(', ',@proctors); - my $edit=(< - - - -EDITFORM - - $r->print("\n\n"); - if (exists($sel{'name'})) { + my $edit=(<<"EDITLINK"); +Edit +EDITLINK + + my $delete=(<<"DELETELINK"); +Delete +DELETELINK + if ($ids ne '') { undef($delete); } + + $r->print("\n\n"); + if (exists($show{'name'})) { $colspan++;$r->print(""); } - if (exists($sel{'type'})) { - $colspan++;$r->print("\n"); - } - if (exists($sel{'description'})) { + if (exists($show{'description'})) { $colspan++;$r->print("\n"); } - if (exists($sel{'starttime'})) { + if (exists($show{'type'})) { + $colspan++;$r->print("\n"); + } + if (exists($show{'starttime'})) { $colspan++;$r->print("\n"); } - if (exists($sel{'endtime'})) { + if (exists($show{'endtime'})) { $colspan++;$r->print("\n"); } - if (exists($sel{'startreserve'})) { + if (exists($show{'startreserve'})) { $colspan++;$r->print("\n"); } - if (exists($sel{'secret'})) { + if (exists($show{'secret'})) { $colspan++;$r->print("\n"); } - if (exists($sel{'maxspace'})) { + if (exists($show{'maxspace'})) { $colspan++;$r->print("\n"); } - if (exists($sel{'ip'})) { + if (exists($show{'ip'})) { $colspan++;$r->print("\n"); } - if (exists($sel{'symb'})) { + if (exists($show{'symb'})) { $colspan++;$r->print("\n"); } - if (exists($sel{'uniqueperiod'})) { + if (exists($show{'uniqueperiod'})) { $colspan++;$r->print("\n"); } $colspan++;$r->print("\n\n"); - if (exists($sel{'proctor'})) { + if (exists($show{'proctor'})) { $r->print(< @@ -825,16 +1019,34 @@ sub csv_upload_assign { my $cname=$env{'course.'.$env{'request.course.id'}.'.num'}; my $cdom=$env{'course.'.$env{'request.course.id'}.'.domain'}; my $countdone=0; + my @errors; foreach my $slot (@slotdata) { my %slot; my %entries=&Apache::loncommon::record_sep($slot); my $domain; my $name=$entries{$fields{'name'}}; + if ($name=~/^\s*$/) { + push(@errors,"Did not create slot with no name"); + next; + } + if ($name=~/\s/) { + push(@errors,"$name not created -- Name must not contain spaces"); + next; + } + if ($name=~/\W/) { + push(@errors,"$name not created -- Name must contain only letters, numbers and _"); + next; + } if ($entries{$fields{'type'}}) { $slot{'type'}=$entries{$fields{'type'}}; } else { $slot{'type'}='preassigned'; } + if ($slot{'type'} ne 'preassigned' && + $slot{'type'} ne 'schedulable_student') { + push(@errors,"$name not created -- invalid type ($slot{'type'}) must be either preassigned or schedulable_student"); + next; + } if ($entries{$fields{'starttime'}}) { $slot{'starttime'}=&UnixDate($entries{$fields{'starttime'}},"%s"); } @@ -863,8 +1075,10 @@ sub csv_upload_assign { $r->rflush(); $countdone++; } - $r->print("
Created $countdone slots\n"); - $r->print("
\n"); + $r->print("

Created $countdone slots\n

"); + foreach my $error (@errors) { + $r->print("

$error\n

"); + } &show_table($r,$mgr); return ''; } @@ -872,6 +1086,13 @@ sub csv_upload_assign { sub handler { my $r=shift; + &Apache::loncommon::content_type($r,'text/html'); + &Apache::loncommon::no_cache($r); + if ($r->header_only()) { + $r->send_http_header(); + return OK; + } + &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}); my $vgr=&Apache::lonnet::allowed('vgr',$env{'request.course.id'}); @@ -884,6 +1105,12 @@ sub handler { if ($env{'form.command'} eq 'showslots' && $vgr eq 'F') { &show_table($r,$mgr); + } elsif ($env{'form.command'} eq 'remove_registration' && $mgr eq 'F') { + &remove_registration($r); + } elsif ($env{'form.command'} eq 'release' && $mgr eq 'F') { + &release_slot($r,undef,undef,undef,$mgr); + } elsif ($env{'form.command'} eq 'delete' && $mgr eq 'F') { + &delete_slot($r); } elsif ($env{'form.command'} eq 'uploadstart' && $mgr eq 'F') { &upload_start($r); } elsif ($env{'form.command'} eq 'csvuploadmap' && $mgr eq 'F') { @@ -902,12 +1129,15 @@ sub handler { } else { my $symb=&Apache::lonnet::unescape($env{'form.symb'}); my (undef,undef,$res)=&Apache::lonnet::decode_symb($symb); - if ($res !~ /\.task$/) { + my $useslots = &Apache::lonnet::EXT("resource.0.useslots",$symb); + if ($useslots ne 'resource') { &fail($r,'not_valid'); return OK; } $env{'request.symb'}=$symb; - my ($status) = &Apache::lonhomework::check_task_access('0'); + my $type = ($res =~ /\.task$/) ? 'Task' + : 'problem'; + my ($status) = &Apache::lonhomework::check_slot_access('0',$type); if ($status eq 'CAN_ANSWER' || $status eq 'NEEDS_CHECKIN' || $status eq 'WAITING_FOR_GRADE') {
'.$linkstart.$which.'">'.$fields{$which}.''.$linkstart.$which.'">'.$show_fields{$which}.'Scheduled Students
$edit
$edit $delete$slot$slots{$slot}->{'type'}$description$slots{$slot}->{'type'}$start$end$start_reserve$slots{$slot}{'secret'}$slots{$slot}{'maxspace'}$slots{$slot}{'ip'}$title$unique$ids
$proctors