[LON-CAPA-cvs] cvs: loncom(version_2_11_2_uiuc) /homework bridgetask.pm inputtags.pm lonhomework.pm structuretags.pm /interface lonmenu.pm lonnavmaps.pm lonparmset.pm /lonnet/perl lonnet.pm

raeburn raeburn at source.lon-capa.org
Tue Jun 13 12:20:48 EDT 2017


raeburn		Tue Jun 13 16:20:48 2017 EDT

  Modified files:              (Branch: version_2_11_2_uiuc)
    /loncom/homework	bridgetask.pm inputtags.pm lonhomework.pm 
                    	structuretags.pm 
    /loncom/interface	lonmenu.pm lonnavmaps.pm lonparmset.pm 
    /loncom/lonnet/perl	lonnet.pm 
  Log:
  - For 2.11.2 (modified).
    Use 2.12 feature ("done" button for timed exms) pre-release, in modified
    2.11.2. Domain's configuration must be set to prohibit hosting of sessions
    for user's domains outside own domain, and modification must be in place 
    on all nodes in domain. 
  
  
-------------- next part --------------
Index: loncom/homework/bridgetask.pm
diff -u loncom/homework/bridgetask.pm:1.264 loncom/homework/bridgetask.pm:1.264.2.1
--- loncom/homework/bridgetask.pm:1.264	Sun May 18 09:59:57 2014
+++ loncom/homework/bridgetask.pm	Tue Jun 13 16:20:40 2017
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA 
 # definition of tags that give a structure to a document
 #
-# $Id: bridgetask.pm,v 1.264 2014/05/18 09:59:57 raeburn Exp $
+# $Id: bridgetask.pm,v 1.264.2.1 2017/06/13 16:20:40 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -681,7 +681,8 @@
         $target eq 'tex') {
         if ($env{'form.markaccess'}) {
             my @interval=&Apache::lonnet::EXT("resource.0.interval");
-            &Apache::lonnet::set_first_access($interval[1],$interval[0]);
+            my ($timelimit) = ($interval[0] =~ /^(\d+)/);
+            &Apache::lonnet::set_first_access($interval[1],$timelimit);  
         }
     }
 
@@ -1407,7 +1408,7 @@
             if ($canstore) {
 	        &Apache::structuretags::finalize_storage();
                 my @interval = &Apache::lonnet::EXT("resource.0.interval");
-                if ($interval[0] =~ /^\d+$/ && $interval[1] eq 'resource') {
+                if ($interval[0] =~ /^\d+/ && $interval[1] eq 'resource') {
                     my $key=$courseid."\0".$symb;
                     my %times=&Apache::lonnet::get('firstaccesstimes',
                                                    [$key],$domain,$name);
Index: loncom/homework/inputtags.pm
diff -u loncom/homework/inputtags.pm:1.333.2.4 loncom/homework/inputtags.pm:1.333.2.4.2.1
--- loncom/homework/inputtags.pm:1.333.2.4	Fri Aug  5 23:17:10 2016
+++ loncom/homework/inputtags.pm	Tue Jun 13 16:20:40 2017
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # input  definitons
 #
-# $Id: inputtags.pm,v 1.333.2.4 2016/08/05 23:17:10 raeburn Exp $
+# $Id: inputtags.pm,v 1.333.2.4.2.1 2017/06/13 16:20:40 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1318,11 +1318,12 @@
 	&& &hide_award($award)) {
         $message = &mt("Answer Submitted: Your final submission will be graded after the due date.");
         my @interval= &Apache::lonnet::EXT("resource.$part.interval");
-        if ($interval[0] =~ /\d+/) {
+        if ($interval[0]) {
             my $first_access=&Apache::lonnet::get_first_access($interval[1]);
             if (defined($first_access)) {
                 my $due_date= &Apache::lonnet::EXT("resource.$part.duedate");
-                unless (($due_date) && ($due_date < $first_access + $interval[0])) { 
+                my ($timelimit) = ($interval[0] =~ /^(\d+)/);
+                unless (($due_date) && ($due_date < $first_access + $timelimit)) { 
                     $message = &mt("Answer Submitted: Your final submission will be graded when the time limit is reached.");
                 }
             }
Index: loncom/homework/lonhomework.pm
diff -u loncom/homework/lonhomework.pm:1.344.2.8 loncom/homework/lonhomework.pm:1.344.2.8.2.1
--- loncom/homework/lonhomework.pm:1.344.2.8	Mon Apr  3 13:11:47 2017
+++ loncom/homework/lonhomework.pm	Tue Jun 13 16:20:40 2017
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # The LON-CAPA Homework handler
 #
-# $Id: lonhomework.pm,v 1.344.2.8 2017/04/03 13:11:47 raeburn Exp $
+# $Id: lonhomework.pm,v 1.344.2.8.2.1 2017/06/13 16:20:40 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1460,6 +1460,41 @@
     }
 }
 
+#
+# Sets interval for current user so time left will be zero, either for the entire folder
+# containing the current resource, or just the resource, depending on value of first item
+# in interval array retrieved from EXT("resource.0.interval");
+#
+sub zero_timer {
+    my ($symb) = @_;
+    my ($hastimeleft,$first_access,$now);
+    my @interval=&Apache::lonnet::EXT("resource.0.interval");
+    if (@interval > 1) {
+        if ($interval[1] eq 'course') {
+            return;
+        } else {
+            my $now = time;
+            my $first_access=&Apache::lonnet::get_first_access($interval[1],$symb);
+            if ($first_access > 0) {
+                if ($first_access+$interval[0] > $now) {
+                    my $done_time = $now - $first_access;
+                    my $snum = 1;
+                    if ($interval[1] eq 'map') {
+                        $snum = 2;
+                    }
+                    my $result =
+                        &Apache::lonparmset::storeparm_by_symb_inner($symb,'0_interval',
+                                                                     $snum,$done_time,
+                                                                     'date_interval',
+                                                                     $env{'user.name'},
+                                                                     $env{'user.domain'});
+                    return $result;
+                }
+            }
+        }
+    }
+    return;
+}
 
 sub handler {
     #my $t0 = [&gettimeofday()];
@@ -1516,6 +1551,12 @@
 	    &newproblem($request);
 	}
     } else {
+        # Set the event timer to zero if the "done button" was clicked.  The button is
+        # part of the LCdoneButton form created in lonmenu.pm
+        if ($symb && $env{'form.LC_interval_done'} eq 'true') {
+            &zero_timer($symb);
+            undef($env{'form.LC_interval_done'});
+        }
 	# just render the page normally outside of construction space
 	&Apache::lonxml::debug("not construct");
 	&renderpage($request,$file);
Index: loncom/homework/structuretags.pm
diff -u loncom/homework/structuretags.pm:1.512.2.13 loncom/homework/structuretags.pm:1.512.2.13.2.1
--- loncom/homework/structuretags.pm:1.512.2.13	Tue Mar 14 12:20:57 2017
+++ loncom/homework/structuretags.pm	Tue Jun 13 16:20:41 2017
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA 
 # definition of tags that give a structure to a document
 #
-# $Id: structuretags.pm,v 1.512.2.13 2017/03/14 12:20:57 raeburn Exp $
+# $Id: structuretags.pm,v 1.512.2.13.2.1 2017/06/13 16:20:41 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1525,7 +1525,8 @@
         $target eq 'tex') {
         if ($env{'form.markaccess'}) {
             my @interval=&Apache::lonnet::EXT("resource.0.interval");
-            &Apache::lonnet::set_first_access($interval[1],$interval[0]);
+            my ($timelimit) = ($interval[0] =~ /^(\d+)/);
+            &Apache::lonnet::set_first_access($interval[1],$timelimit);
         }
 
         ($status,$accessmsg,$slot_name,$slot) =
Index: loncom/interface/lonmenu.pm
diff -u loncom/interface/lonmenu.pm:1.369.2.71 loncom/interface/lonmenu.pm:1.369.2.71.2.1
--- loncom/interface/lonmenu.pm:1.369.2.71	Mon Apr 10 05:37:47 2017
+++ loncom/interface/lonmenu.pm	Tue Jun 13 16:20:43 2017
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Routines to control the menu
 #
-# $Id: lonmenu.pm,v 1.369.2.71 2017/04/10 05:37:47 raeburn Exp $
+# $Id: lonmenu.pm,v 1.369.2.71.2.1 2017/06/13 16:20:43 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -546,7 +546,7 @@
             my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'};
             ($escurl = $env{'request.filename'}) =~ s{^\Q$londocroot\E}{};
             $escurl  = &escape($escurl);
-        }    
+        }
         $menu =~ s/\[url\]/$escurl/g;
         $menu =~ s/\[symb\]/$escsymb/g;
     }
@@ -2098,6 +2098,217 @@
 END
 }
 
+# This creates a "done button" for timed events.  The confirmation box is a jQuery
+# dialog widget. If the interval parameter requires a proctor key for the timed
+# event to be marked done, there will also be a textbox where that can be entered.
+# Clicking OK will set the value of LC_interval_done to 'true', and, if needed will
+# set the value of LC_interval_done_proctorpass to the text entered in that box,
+# and submit the corresponding form.
+#
+# The &zero_time() routine in lonhomework.pm is called when a page is rendered if
+# LC_interval_done is true.
+#
+sub done_button_js {
+    my ($type,$width,$height,$proctor,$donebuttontext) = @_;
+    return unless (($type eq 'map') || ($type eq 'resource'));
+    my %lt = &Apache::lonlocal::texthash(
+                 title    => 'WARNING!',
+                 preamble => 'You are trying to end this timed event early.',
+                 map      => 'Confirming that you are done will cause the time to expire and prevent you from changing any answers in the current folder.',
+                 resource => 'Confirming that you are done will cause the time to expire for this question, and prevent you from changing your answer(s).',
+                 okdone   => 'Click "OK" if you are completely finished.',
+                 cancel   => 'Click "Cancel" to continue working.',
+                 proctor  => 'Ask a proctor to enter the key, then click "OK" if you are completely finished.',
+                 ok       => 'OK',
+                 exit     => 'Cancel',
+                 key      => 'Key:',
+                 nokey    => 'A proctor key is required',
+    );
+    my $navmap = Apache::lonnavmaps::navmap->new();
+    my ($missing,$tried) = (0,0);
+    if (ref($navmap)) {
+        my @resources=();
+        if ($type eq 'map') {
+            my ($mapurl,$rid,$resurl)=&Apache::lonnet::decode_symb($env{'request.symb'});
+            if ($env{'request.symb'} =~ /\.page$/) {
+                @resources=$navmap->retrieveResources($resurl,sub { $_[0]->is_problem() });
+            } else {
+                @resources=$navmap->retrieveResources($mapurl,sub { $_[0]->is_problem() });
+            }
+        } else {
+            my $res = $navmap->getBySymb($env{'request.symb'});
+            if (ref($res)) {
+                if ($res->is_problem()) {
+                    push(@resources,$res);
+                }
+            }
+        }
+        foreach my $res (@resources) {
+            if (ref($res->parts()) eq 'ARRAY') {
+                foreach my $part (@{$res->parts()}) {
+                    if (!$res->tries($part)) {
+                        $missing++;
+                    } else {
+                        $tried++;
+                    }
+                }
+            }
+        }
+    }
+    if ($missing) {
+        $lt{'miss'} .= '<p class="LC_error">';
+        if ($type eq 'map') {
+            $lt{'miss'} .= &mt('Submissions are missing for [quant,_1,question part,question parts] in this folder.',$missing);
+        } else {
+            $lt{'miss'} .= &mt('Submissions are missing for [quant,_1,part] in this question.',$missing);
+        }
+        if ($missing > 1) {
+            $lt{'miss'} .= ' '.&mt('If you confirm you are done you will be unable to submit answers for them.').'</span>';
+        } else {
+            $lt{'miss'} .= ' '.&mt('If you confirm you are done you will be unable to submit an answer for it.').'</p>';
+        }
+    }
+    $donebuttontext = &HTML::Entities::encode($donebuttontext,'<>&"');
+    if ($proctor) {
+        if ($height !~ /^\d+$/) {
+            $height = 400;
+            if ($missing) {
+                $height += 60;
+            }
+        }
+        if ($width !~ /^\d+$/) {
+            $width = 400;
+            if ($missing) {
+                $width += 60;
+            }
+        }
+        return <<END;
+<form method="post" name="LCdoneButton" action="">
+    <input type="hidden" name="LC_interval_done" value="" />
+    <input type="hidden" name="LC_interval_done_proctorpass" value="" />
+    <button id="LC_done-confirm-opener" type="button">$donebuttontext</button>
+</form>
+
+<div id="LC_done-confirm" title="$lt{'title'}">
+  <p>$lt{'preamble'} $lt{$type}</p>
+  $lt{'miss'}
+  <p>$lt{'proctor'}</p>
+  <form name="LCdoneButtonProctor" action="">
+    <label>$lt{'key'}<input type="password" name="LC_interval_done_proctorkey" value="" /></label>
+    <input type="submit" tabindex="-1" style="position:absolute; top:-1000px" />
+  </form>
+  <p>$lt{'cancel'}</p>
+</div>
+
+<script type="text/javascript">
+// <![CDATA[
+    \$( "#LC_done-confirm" ).dialog({ autoOpen: false });
+    \$( "#LC_done-confirm-opener" ).on("click", function() {
+        \$( "#LC_done-confirm" ).dialog("open");
+        \$( "#LC_done-confirm" ).dialog({
+            height: $height,
+            width: $width,
+            modal: true,
+            resizable: false,
+            buttons: [
+                {
+                    text: "$lt{'ok'}",
+                    click: function() {
+                        var proctorkey = \$( '[name="LC_interval_done_proctorkey"]' )[0].value;
+                        if ((proctorkey == '') || (proctorkey == null)) {
+                            alert("$lt{'nokey'}");
+                        } else {
+                            \$( '[name="LC_interval_done"]' )[0].value = 'true';
+                            \$( '[name="LC_interval_done_proctorpass"]' )[0].value = proctorkey;
+                            \$( '[name="LCdoneButton"]' )[0].submit();
+                        }
+                    },
+                },
+                {
+                    text: "$lt{'exit'}",
+                    click: function() {
+                        \$("#LC_done-confirm").dialog( "close" );
+                    }
+                }
+            ],
+            close: function() {
+                \$( '[name="LC_interval_done_proctorkey"]' )[0].value = '';
+            }
+        });
+        \$( "#LC_done-confirm" ).find( "form" ).on( "submit", function( event ) {
+            event.preventDefault();
+            \$( '[name="LC_interval_done"]' )[0].value = 'true';
+            \$( '[name="LC_interval_done_proctorpass"]' )[0].value = \$( '[name="LC_interval_done_proctorkey"]' )[0].value;
+            \$( '[name="LCdoneButton"]' )[0].submit();
+        });
+});
+
+// ]]>
+</script>
+
+END
+    } else {
+        if ($height !~ /^\d+$/) {
+            $height = 320;
+            if ($missing) {
+                $height += 60;
+            }
+        }
+        if ($width !~ /^\d+$/) {
+            $width = 320;
+            if ($missing) {
+                $width += 60;
+            }
+        }
+        if ($missing) {
+            $lt{'miss'} = '</p>'.$lt{'miss'}.'<p>';
+        }
+        return <<END;
+
+<form method="post" name="LCdoneButton" action="">
+    <input type="hidden" name="LC_interval_done" value="" />
+    <button id="LC_done-confirm-opener" type="button">$donebuttontext</button>
+</form>
+
+<div id="LC_done-confirm" title="$lt{'title'}">
+    <p>$lt{'preamble'} $lt{$type} $lt{'miss'} $lt{'okdone'} $lt{'cancel'}</p>
+</div>
+
+<script type="text/javascript">
+// <![CDATA[
+\$( "#LC_done-confirm" ).dialog({ autoOpen: false });
+\$( "#LC_done-confirm-opener" ).click(function() {
+    \$( "#LC_done-confirm" ).dialog( "open" );
+    \$( "#LC_done-confirm" ).dialog({
+      resizable: false,
+      height: $height,
+      width: $width,
+      modal: true,
+      buttons: [
+                 {
+                    text: "$lt{'ok'}",
+                    click: function() {
+                        \$( this ).dialog( "close" );
+                        \$( '[name="LC_interval_done"]' )[0].value = 'true';
+                        \$( '[name="LCdoneButton"]' )[0].submit();
+                    },
+                 },
+                 {
+                     text: "$lt{'exit'}",
+                     click: function() {
+                         \$( this ).dialog( "close" );
+                     },
+                  },
+               ],
+       });
+});
+// ]]>
+</script>
+
+END
+    }
+}
+
 sub utilityfunctions {
     my ($httphost) = @_;
     my $currenturl=&Apache::lonnet::clutter(&Apache::lonnet::fixversion((split(/\?/,$env{'request.noversionuri'}))[0]));
@@ -2876,10 +3087,20 @@
         }
         my $duedate = &Apache::lonnet::EXT("resource.0.duedate");
         my @interval=&Apache::lonnet::EXT("resource.0.interval");
+        my ($timelimit,$usesdone,$donebuttontext,$proctor,$secret);
         if (@interval > 1) {
+            ($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);
+            }
             my $first_access=&Apache::lonnet::get_first_access($interval[1]);
             if ($first_access > 0) {
-                if ($first_access+$interval[0] > time) {
+                if ($first_access+$timelimit > time) {
                     $hastimeleft = 1;
                 }
             }
@@ -2887,11 +3108,16 @@
         if (($duedate && $duedate > time) ||
             (!$duedate && $hastimeleft) ||
             ($slot_name ne '' && $slothastime)) {
-            my ($collapse,$expand,$alttxt,$title,$currdisp);
+            my ($collapse,$expand,$alttxt,$title,$currdisp,$donebutton);
             if ((@interval > 1 && $hastimeleft) ||
                 ($type eq 'Task' && $slothastime)) {
                 $currdisp = 'inline';
                 $collapse = '► ';
+                if ((@interval > 1) && ($hastimeleft)) {
+                    if ($usesdone eq 'done') {
+                        $donebutton = &done_button_js($interval[1],'','',$proctor,$donebuttontext);
+                    }
+                }
             } else {
                 $currdisp = 'none';
                 $expand = '◄ ';
@@ -2902,7 +3128,7 @@
             }
             my $desc = &mt('Countdown to due date/time');
             return <<END;
-
+$donebutton
 <a href="javascript:toggleCountdown();" class="LC_menubuttons_link">
 <span id="ddcountcollapse" class="LC_menubuttons_inline_text">
 $collapse
Index: loncom/interface/lonnavmaps.pm
diff -u loncom/interface/lonnavmaps.pm:1.509.2.5 loncom/interface/lonnavmaps.pm:1.509.2.5.2.1
--- loncom/interface/lonnavmaps.pm:1.509.2.5	Tue Nov 29 15:13:19 2016
+++ loncom/interface/lonnavmaps.pm	Tue Jun 13 16:20:43 2017
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Navigate Maps Handler
 #
-# $Id: lonnavmaps.pm,v 1.509.2.5 2016/11/29 15:13:19 raeburn Exp $
+# $Id: lonnavmaps.pm,v 1.509.2.5.2.1 2017/06/13 16:20:43 raeburn Exp $
 
 #
 # Copyright Michigan State University Board of Trustees
@@ -4632,11 +4632,12 @@
     my $date;
     my @interval=$self->parmval("interval", $part);
     my $due_date=$self->parmval("duedate", $part);
-    if ($interval[0] =~ /\d+/) {
-       my $first_access=&Apache::lonnet::get_first_access($interval[1],
+    if ($interval[0] =~ /^(\d+)/) {
+        my $timelimit = $1;
+        my $first_access=&Apache::lonnet::get_first_access($interval[1],
                                                           $self->{SYMB});
 	if (defined($first_access)) {
-           my $interval = $first_access+$interval[0];
+            my $interval = $first_access+$timelimit;
 	    $date = (!$due_date || $interval < $due_date) ? $interval 
                                                           : $due_date;
 	} else {
Index: loncom/interface/lonparmset.pm
diff -u loncom/interface/lonparmset.pm:1.522.2.23 loncom/interface/lonparmset.pm:1.522.2.23.2.1
--- loncom/interface/lonparmset.pm:1.522.2.23	Sun Apr  2 13:39:05 2017
+++ loncom/interface/lonparmset.pm	Tue Jun 13 16:20:44 2017
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Handler to set parameters for assessments
 #
-# $Id: lonparmset.pm,v 1.522.2.23 2017/04/02 13:39:05 raeburn Exp $
+# $Id: lonparmset.pm,v 1.522.2.23.2.1 2017/06/13 16:20:44 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -752,7 +752,7 @@
 
 
 sub valout {
-    my ($value,$type,$editable)=@_;
+    my ($value,$type,$name,$editable)=@_;
     my $result = '';
     # Values of zero are valid.
     if (! $value && $value ne '0') {
@@ -766,7 +766,17 @@
         }
     } else {
         if ($type eq 'date_interval') {
-            my ($sec,$min,$hour,$mday,$mon,$year)=gmtime($value);
+            my ($totalsecs,$donesuffix) = split(/_/,$value,2);
+            my ($usesdone,$donebuttontext,$proctor,$secretkey);
+            if ($donesuffix =~ /^done\:([^\:]+)\:(.*)$/) {
+                $donebuttontext = $1;
+                (undef,$proctor,$secretkey) = split(/_/,$2);
+                $usesdone = 'done';
+            } elsif ($donesuffix =~ /^done(|_.+)$/) {
+                $donebuttontext = &mt('Done');
+                ($usesdone,$proctor,$secretkey) = split(/_/,$donesuffix);
+            }
+            my ($sec,$min,$hour,$mday,$mon,$year)=gmtime($totalsecs);
             my @timer;
             $year=$year-70;
             $mday--;
@@ -799,6 +809,13 @@
                 push(@timer,&mt('[quant,_1,sec]',0));
             }
             $result.=join(", ", at timer);
+            if ($usesdone eq 'done') {
+                if ($secretkey) {
+                    $result .= ' '.&mt('+ "[_1]" with proctor key: [_2]',$donebuttontext,$secretkey);
+                } else {
+                    $result .= ' + "'.$donebuttontext.'"';
+                }
+            }
         } elsif (&isdateparm($type)) {
             $result = &Apache::lonlocal::locallocaltime($value).
         &date_sanity_info($value);
@@ -825,7 +842,7 @@
     my ($parmname)=((split(/\&/,$marker))[1]=~/\_([^\_]+)$/);
     my ($hour,$min,$sec,$val)=&preset_defaults($parmname);
     unless (defined($winvalue)) { $winvalue=$val; }
-    my $valout = &valout($value,$type,1);
+    my $valout = &valout($value,$type,$parmname,1);
     my $unencmarker = $marker;
     foreach my $item (\$type, \$dis, \$winvalue, \$marker, \$return, \$call,
               \$hour, \$min, \$sec) {
@@ -905,6 +922,31 @@
 COURSECONTENTSCRIPT
 }
 
+sub done_proctor_js {
+    return <<"END";
+function toggleSecret(form,radio,key) {
+    var radios = form[radio+key];
+    if (radios.length) {
+        for (var i=0; i<radios.length; i++) {
+            if (radios[i].checked) {
+                if (radios[i].value == '_done_proctor') {
+                    if (document.getElementById('done_'+key+'_proctorkey')) {
+                        document.getElementById('done_'+key+'_proctorkey').type='text';
+                    }
+                } else {
+                    if (document.getElementById('done_'+key+'_proctorkey')) {
+                        document.getElementById('done_'+key+'_proctorkey').type='hidden';
+                        document.getElementById('done_'+key+'_proctorkey').value='';
+                    }
+                }
+            }
+        }
+    }
+}
+END
+
+}
+
 sub startpage {
     my ($r,$psymb) = @_;
 
@@ -994,7 +1036,7 @@
     my $thismarker=$which;
     $thismarker=~s/^parameter\_//;
     my $mprefix=$rid.'&'.$thismarker.'&';
-    my $effective_parm = &valout($outpar[$result],$typeoutpar[$result]);
+    my $effective_parm = &valout($outpar[$result],$typeoutpar[$result],$thismarker);
     my ($othergrp,$grp_parm,$controlgrp);
 
     if ($parmlev eq 'general') {
@@ -1074,7 +1116,7 @@
         my $sessionvaltype=$typeoutpar[$result];
         if (!defined($sessionvaltype)) { $sessionvaltype=$$defaulttype{$which}; }
         $r->print('<td style="background-color:#999999;" align="center"><font color="#FFFFFF">'.
-                  &valout($sessionval,$sessionvaltype).' '.
+                  &valout($sessionval,$sessionvaltype,$$name{$which}).' '.
                   '</font></td>');
     }
     $r->print('</tr>');
@@ -1102,7 +1144,7 @@
         }
     }
     if ($nolink) {
-        $r->print(&valout($$outpar[$which],$$typeoutpar[$which]));
+        $r->print(&valout($$outpar[$which],$$typeoutpar[$which],$mprefix));
     } else {
         $r->print(&plink($$typeoutpar[$which],
                          $$display{$value},$$outpar[$which],
@@ -1127,9 +1169,9 @@
     if (($coursereply) && ($cgroup ne $resultgroup)) {
         if ($result > 3) {
             $bgcolor = '#AAFFAA';
-            $grp_parm = &valout($coursereply,$resulttype);
+            $grp_parm = &valout($coursereply,$resulttype,$what);
         }
-        $grp_parm = &valout($coursereply,$resulttype);
+        $grp_parm = &valout($coursereply,$resulttype,$what);
         $output = '<td style="background-color:'.$bgcolor.';" align="center">';
         if ($resultgroup && $resultlevel) {
             $output .= '<small><b>'.$resultgroup.'</b> ('.$resultlevel.'): </small>'.$grp_parm;
@@ -3159,7 +3201,7 @@
               );
             }
         } elsif ($thistype eq 'date_interval') {
-            $r->print(&date_interval_selector($thiskey,
+            $r->print(&date_interval_selector($thiskey,$name,
                       $$resourcedata{$thiskey},$readonly));
         } elsif ($thistype =~ m/^string/) {
             $r->print(&string_selector($thistype,$thiskey,
@@ -3179,8 +3221,9 @@
 
 
 sub date_interval_selector {
-    my ($thiskey, $showval, $readonly) = @_;
-    my $result;
+    my ($thiskey, $pname, $showval, $readonly) = @_;
+    my ($result,%skipval);
+    my $currval = $showval;
     foreach my $which (['days', 86400, 31],
                ['hours', 3600, 23],
                ['minutes', 60, 59],
@@ -3194,6 +3237,51 @@
                            \%select,'',$readonly);
     $result .= ' '.&mt($name);
     }
+    if ($pname eq 'interval') {
+        unless ($skipval{'done'}) {
+            my $checkedon = '';
+            my $checkedproc = '';
+            my $currproctorkey = '';
+            my $currprocdisplay = 'hidden';
+            my $currdonetext = &mt('Done');
+            my $checkedoff = ' checked="checked"';
+            if ($currval =~ /^(?:\d+)_done$/) {
+                $checkedon = ' checked="checked"';
+                $checkedoff = '';
+            } elsif ($currval =~ /^(?:\d+)_done\:([^\:]+)\:$/) {
+                $currdonetext = $1;
+                $checkedon = ' checked="checked"';
+                $checkedoff = '';
+            } elsif ($currval =~ /^(?:\d+)_done_proctor_(.+)$/) {
+                $currproctorkey = $1;
+                $checkedproc = ' checked="checked"';
+                $checkedoff = '';
+                $currprocdisplay = 'text';
+            } elsif ($currval =~ /^(?:\d+)_done\:([^\:]+)\:_proctor_(.+)$/) {
+                $currdonetext = $1;
+                $currproctorkey = $2;
+                $checkedproc = ' checked="checked"';
+                $checkedoff = '';
+                $currprocdisplay = 'text';
+            }
+            my $onclick = ' onclick="toggleSecret(this.form,'."'done_','$thiskey'".');"';
+            my $disabled;
+            if ($readonly) {
+                $disabled = ' disabled="disabled"';
+            }
+            $result .= '<br /><span class="LC_nobreak">'.&mt('Include "done" button').
+                       '<label><input type="radio" value="" name="done_'.$thiskey.'"'.$checkedoff.$onclick.$disabled.' />'.
+                       &mt('No').'</label>'.(' 'x2).
+                       '<label><input type="radio" value="_done" name="done_'.$thiskey.'"'.$checkedon.$onclick.$disabled.' />'.
+                       &mt('Yes').'</label>'.(' 'x2).
+                       '<label><input type="radio" value="_done_proctor" name="done_'.$thiskey.'"'.$checkedproc.$onclick.$disabled.' />'.
+                       &mt('Yes, with proctor key').'</label>'.
+                       '<input type="'.$currprocdisplay.'" id="done_'.$thiskey.'_proctorkey" '.
+                       'name="done_'.$thiskey.'_proctorkey" value="'.&HTML::Entities::encode($currproctorkey,'"<>&').'"'.$disabled.' /></span><br />'.
+                       '<span class="LC_nobreak">'.&mt('Button text').': '.
+                       '<input type="text" name="done_'.$thiskey.'_buttontext" value="'.&HTML::Entities::encode($currdonetext,'"<>&').'"'.$disabled.' /></span>';
+        }
+    }
     unless ($readonly) {
         $result .= '<input type="hidden" name="dateinterval_'.$thiskey.'" />';
     }
@@ -3403,6 +3491,7 @@
 '.
             &Apache::lonhtmlcommon::resize_scrollbox_js('params')."\n".
             &showhide_js()."\n".
+            &done_proctor_js()."\n".
 '// ]]>
 </script>
 ';
@@ -3579,13 +3668,19 @@
     my ($r,$parm_permission) = @_;
     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
+    my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
+    my $js = '<script type="text/javascript">'."\n".
+             '// <![CDATA['."\n".
+             &done_proctor_js()."\n".
+             '// ]]>'."\n".
+             '</script>'."\n";
     my $readonly = 1;
     if ($parm_permission->{'edit'}) {
         undef($readonly);
     }
     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview',
     text=>"Overview Mode"});
-    my $start_page=&Apache::loncommon::start_page('Modify Parameters');
+    my $start_page=&Apache::loncommon::start_page('Modify Parameters'.$js);
     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview');
     $r->print($start_page.$breadcrumbs);
     $r->print('<form method="post" action="/adm/parmset?action=setoverview" name="parmform">');
Index: loncom/lonnet/perl/lonnet.pm
diff -u loncom/lonnet/perl/lonnet.pm:1.1172.2.93 loncom/lonnet/perl/lonnet.pm:1.1172.2.93.2.1
--- loncom/lonnet/perl/lonnet.pm:1.1172.2.93	Sat May 13 13:58:49 2017
+++ loncom/lonnet/perl/lonnet.pm	Tue Jun 13 16:20:47 2017
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # TCP networking package
 #
-# $Id: lonnet.pm,v 1.1172.2.93 2017/05/13 13:58:49 raeburn Exp $
+# $Id: lonnet.pm,v 1.1172.2.93.2.1 2017/06/13 16:20:47 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1829,7 +1829,7 @@
 			   &escape($srch->{'srchtype'}),$homeserver);
 	my $host=&hostname($homeserver);
 	if ($queryid !~/^\Q$host\E\_/) {
-	    &logthis('institutional directory search invalid queryid: '.$queryid.' for host: '.$homeserver.'in domain '.$udom);
+	    &logthis('institutional directory search invalid queryid: '.$queryid.' for host: '.$homeserver.' in domain '.$udom);
 	    return;
 	}
 	my $response = &get_query_reply($queryid);
@@ -3037,8 +3037,9 @@
                     $cfile = &clutter($res);
                 } else {
                     $cfile = $env{'form.suppurl'};
-                    $cfile =~ s{^http://}{};
-                    $cfile = '/adm/wrapper/ext/'.$cfile;
+                    my $escfile = &unescape($cfile);
+                    $escfile =~ s{^http://}{};
+                    $cfile = &escape("/adm/wrapper/ext/$escfile");
                 }
             } elsif ($resurl =~ m{^/?adm/viewclasslist$}) {
                 if ($env{'form.forceedit'}) {
@@ -4752,9 +4753,10 @@
 my $cachedtime='';
 
 sub load_all_first_access {
-    my ($uname,$udom)=@_;
+    my ($uname,$udom,$ignorecache)=@_;
     if (($cachedkey eq $uname.':'.$udom) &&
-        (abs($cachedtime-time)<5) && (!$env{'form.markaccess'})) {
+        (abs($cachedtime-time)<5) && (!$env{'form.markaccess'}) &&
+        (!$ignorecache)) {
         return;
     }
     $cachedtime=time;
@@ -4763,7 +4765,7 @@
 }
 
 sub get_first_access {
-    my ($type,$argsymb,$argmap)=@_;
+    my ($type,$argsymb,$argmap,$ignorecache)=@_;
     my ($symb,$courseid,$udom,$uname)=&whichuser();
     if ($argsymb) { $symb=$argsymb; }
     my ($map,$id,$res)=&decode_symb($symb);
@@ -4775,7 +4777,7 @@
     } else {
 	$res=$symb;
     }
-    &load_all_first_access($uname,$udom);
+    &load_all_first_access($uname,$udom,$ignorecache);
     return $cachedtimes{"$courseid\0$res"};
 }
 
@@ -6181,7 +6183,7 @@
    #
    my %returnhash=();
    #
-   if ($rep eq "unknown_cmd") { 
+   if ($rep eq 'unknown_cmd') {
        # an old lond will not know currentdump
        # Do a dump and make it look like a currentdump
        my @tmp = &dumpstore($courseid,$sdom,$sname,'.');
@@ -7775,7 +7777,8 @@
                             }
                         }
                     }
-                    if ($interval[0] =~ /^\d+$/) {
+                    if ($interval[0] =~ /^(\d+)/) {
+                        my $timelimit = $1;
                         my $first_access;
                         if ($type eq 'resource') {
                             $first_access=&get_first_access($interval[1],$item);
@@ -7785,7 +7788,7 @@
                             $first_access=&get_first_access($interval[1]);
                         }
                         if ($first_access) {
-                            my $timesup = $first_access+$interval[0];
+                            my $timesup = $first_access+$timelimit;
                             if ($timesup > $now) {
                                 my $activeblock;
                                 foreach my $res (@to_test) {
@@ -10473,7 +10476,7 @@
 #  Parameters:
 #     $name      - Course/user name.
 #     $domain    - Name of the domain the user/course is registered on.
-#     $type      - Type of thing $name is (must be 'course' or 'user'
+#     $type      - Type of thing $name is (must be 'course' or 'user')
 #     @which     - Array of names of resources desired.
 #  Returns:
 #     The value of the first reasource in @which that is found in the
@@ -10492,9 +10495,11 @@
     }
     if (!ref($result)) { return $result; }    
     foreach my $item (@which) {
-	if (defined($result->{$item->[0]})) {
-	    return [$result->{$item->[0]},$item->[1]];
-	}
+        if (ref($item) eq 'ARRAY') {
+	    if (defined($result->{$item->[0]})) {
+	        return [$result->{$item->[0]},$item->[1]];
+	    }
+        }
     }
     return undef;
 }


More information about the LON-CAPA-cvs mailing list