--- rat/lonpage.pm 2019/08/12 15:36:40 1.111.2.8 +++ rat/lonpage.pm 2020/01/22 15:02:22 1.111.2.10.2.1 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Page Handler # -# $Id: lonpage.pm,v 1.111.2.8 2019/08/12 15:36:40 raeburn Exp $ +# $Id: lonpage.pm,v 1.111.2.10.2.1 2020/01/22 15:02:22 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -41,6 +41,7 @@ use Apache::lonxml(); use Apache::lonlocal; use Apache::lonmenu; use Apache::lonhomework; +use Apache::lonparmset; use Apache::lonenc(); use HTML::TokeParser; use GDBM_File; @@ -193,16 +194,24 @@ sub handler { if (($firstres) && ($lastres)) { # ------------------------------------------------------------- Countdown Timer my $now = time; - my ($pagefirstaccess,%hastimeleft,%countdowndisp); + my ($pagefirstaccess,%hastimeleft,%countdowndisp,%donebutton, + %donebtnextra,%buttonbytime,$donetime,$symbtosetdone); my ($pagesymb,$courseid,$domain,$name)=&Apache::lonnet::whichuser(); + unless ($pagesymb) { + $pagesymb=&Apache::lonnet::symbread($requrl); + } if ($pagesymb && ($courseid ne '') && ($domain ne '') && ($name ne '')) { my %times=&Apache::lonnet::get('firstaccesstimes', [$courseid."\0".$pagesymb], $domain,$name); if ($times{$courseid."\0".$pagesymb} =~ /^\d+$/) { $pagefirstaccess = $times{$courseid."\0".$pagesymb}; + if ($pagefirstaccess && $env{'form.LC_interval_done'} eq 'true') { + $donetime = $now - $pagefirstaccess; + } } } + # ----------------------------------------------------------------- Render page @rows=(); @@ -220,6 +229,27 @@ sub handler { my ($mapid,$resid)=split(/\./,$rid); $symbhash{$hash{'src_'.$rid}}= [$hash{'src_'.$rid},$resid]; + if (($donetime) && ($symbtosetdone eq '')) { + my $src = $hash{'src_'.$rid}; + if ($hash{'encrypted_'.$rid}) { + $src=&Apache::lonenc::encrypted($src); + } + my ($mapid,$resid)=split(/\./,$rid); + my $symb=&Apache::lonnet::encode_symb($hash{'map_id_'.$mapid},$resid,$src); + if ($src =~ /$LONCAPA::assess_re/) { + my @interval=&Apache::lonnet::EXT("resource.0.interval",$symb); + if (@interval > 1) { + if (($interval[1] eq 'map') && ($pagefirstaccess)) { + my ($timelimit) = ($interval[0] =~ /^(\d+)/); + if ($timelimit) { + if ($pagefirstaccess + $timelimit > $now) { + $symbtosetdone = $symb; + } + } + } + } + } + } } } } @@ -254,6 +284,16 @@ sub handler { my $xmlheader=''; my $xmlbody=''; +# ---------------------------------------------------------- Handle Done button + + # Set the event timer to zero if the "done button" was clicked. + if ($donetime && $symbtosetdone) { + &Apache::lonparmset::storeparm_by_symb_inner($symbtosetdone,'0_interval', + 2,$donetime,'date_interval', + $name,$domain); + undef($env{'form.LC_interval_done'}); + } + # --------------------------------------------- Get SSI output, post parameters for ($i=0;$i<=$#rows;$i++) { @@ -320,7 +360,9 @@ ENDEXT if ($env{'form.all_submit_pressed'}) { $posthash{'all_submit'}='yes'; } - } + } elsif ($env{'form.'.$prefix.'markaccess'} eq 'yes') { + $posthash{'markaccess'} = $env{'form.'.$prefix.'markaccess'}; + } if ($env{'environment.remote'} eq 'on') { $posthash{'inhibitmenu'} = 'yes'; } @@ -455,7 +497,8 @@ ENDEXT undef(%Apache::lonhomework::history); my $probstatus = &Apache::lonnet::EXT("resource.0.problemstatus",$symb); if (($status eq 'CAN_ANSWER') || (($status eq 'CANNOT_ANSWER') && - (($probstatus eq 'no') || ($probstatus eq 'no_feedback_ever')))) { + (($probstatus eq 'no') || ($probstatus eq 'no_feedback_ever'))) || + (($status eq 'NOT_YET_VIEWED') && ($posthash{'markaccess'} eq 'yes'))) { my ($slothastime,$timerhastime); if ($slot_name ne '') { if (ref($slot) eq 'HASH') { @@ -468,11 +511,26 @@ ENDEXT my $duedate = &Apache::lonnet::EXT("resource.0.duedate",$symb); my @interval=&Apache::lonnet::EXT("resource.0.interval",$symb); if (@interval > 1) { - my $first_access=&Apache::lonnet::get_first_access($interval[1],$symb); + my $first_access; + if ($interval[1] eq 'map') { + my $ignorecache; + if ($env{'form.'.$prefix.'markaccess'} eq 'yes') { + $ignorecache = 1; + } + $first_access=&Apache::lonnet::get_first_access($interval[1],undef,$pagesymb,$ignorecache); + if (($first_access) && (!$pagefirstaccess)) { + $pagefirstaccess = $first_access; + } + } else { + $first_access=&Apache::lonnet::get_first_access($interval[1],$symb); + } if ($first_access > 0) { - my $timeremains = $first_access+$interval[0] - $now; - if ($timeremains > 0) { - $timerhastime = $timeremains; + my ($timelimit) = ($interval[0] =~ /^(\d+)/); + if ($timelimit) { + my $timeremains = $timelimit + $first_access - $now; + if ($timeremains > 0) { + $timerhastime = $timeremains; + } } } } @@ -484,6 +542,28 @@ ENDEXT $countdowndisp{$symb} = 'inline'; if ((@interval > 1) && ($timerhastime)) { $hastimeleft{$symb} = $timerhastime; + if ($pagefirstaccess) { + my ($timelimit,$usesdone,$donebuttontext,$proctor,$secret); + ($timelimit,my $donesuffix) = split(/_/,$interval[0],2); + if ($donesuffix =~ /^done\:([^\:]+)\:(.*)$/) { + $usesdone = 'done'; + $donebuttontext = $1; + (undef,$proctor,$secret) = split(/_/,$2); + } elsif ($donesuffix =~ /^done(|_.+)$/) { + $donebuttontext = &mt('Done'); + ($usesdone,$proctor,$secret) = split(/_/,$donesuffix); + } + if ($usesdone eq 'done') { + $donebutton{$symb} = $timelimit; + push(@{$buttonbytime{$timelimit}},$symb); + $donebtnextra{$symb} = { + text => $donebuttontext, + proctor => $proctor, + secret => $secret, + type => $interval[1], + }; + } + } } else { $hastimeleft{$symb} = $slothastime; } @@ -491,6 +571,9 @@ ENDEXT $hastimeleft{$symb} = $duedate - $now; $countdowndisp{$symb} = 'none'; } + unless ($donebutton{$symb}) { + $donebutton{$symb} = 0; + } } } } @@ -572,8 +655,9 @@ ENDEXT $uniquetimes{$item} = 1; } } - if (keys(%uniquetimes) == 1) { - my (%uniquedisplays,%uniquedones,$currdisp); + if (scalar(keys(%uniquetimes)) == 1) { + my (%uniquedisplays,%uniquedones,$currdisp,$donebuttontime, + $donebuttonextras); if (keys(%countdowndisp)) { foreach my $item (values(%countdowndisp)) { if (exists($uniquedisplays{$item})) { @@ -587,7 +671,25 @@ ENDEXT $currdisp = $countdowndisplay[0]; } } - &add_countdown_timer($currdisp); + if (keys(%donebutton)) { + foreach my $item (values(%donebutton)) { + if (exists($uniquedones{$item})) { + $uniquedones{$item} ++; + } else { + $uniquedones{$item} = 1; + } + } + my @donebuttons = sort { $ <=> $b } (keys(%uniquedones)); + if (scalar(@donebuttons) == 1) { + if ($donebuttons[0]) { + $donebuttontime = $donebuttons[0]; + if (ref($buttonbytime{$donebuttontime}) eq 'ARRAY') { + $donebuttonextras = $donebtnextra{$buttonbytime{$donebuttontime}->[0]}; + } + } + } + } + &add_countdown_timer($currdisp,$donebuttontime,$donebuttonextras); } } my $pagebuttonshide; @@ -867,8 +969,8 @@ sub get_buttons { if ($cfile ne '') { my $jscall = &Apache::lonhtmlcommon::jump_to_editres($cfile,$home,$switchserver, $forceedit,1,$symb,undef, - &escape($env{'form.title'}, - $hostname)); + &escape($env{'form.title'}), + $hostname); if ($jscall) { $editbutton = 1; my $icon = 'pcstr.png'; @@ -918,19 +1020,33 @@ sub get_buttons { } sub add_countdown_timer { - my ($currdisp) = @_; - my ($collapse,$expand,$alttxt,$title); + my ($currdisp,$donebuttontime,$donebuttonextras) = @_; + my ($collapse,$expand,$alttxt,$title,$donebutton); if ($currdisp eq 'inline') { $collapse = '► '; } else { $expand = '◄ '; } + if ($donebuttontime) { + my ($type,$proctor,$donebuttontext); + if (ref($donebuttonextras) eq 'HASH') { + $proctor = $donebuttonextras->{'proctor'}; + $donebuttontext = $donebuttonextras->{'text'}; + $type = $donebuttonextras->{'type'}; + } else { + $donebuttontext = &mt('Done'); + $type = 'map'; + } + $donebutton = + &Apache::lonmenu::done_button_js($type,'','',$proctor,$donebuttontext); + } unless ($env{'environment.icons'} eq 'iconsonly') { $alttxt = &mt('Timer'); $title = $alttxt.' '; } my $desc = &mt('Countdown to due date/time'); my $output = < $collapse 500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.