--- loncom/interface/lonparmset.pm 2016/07/12 20:30:20 1.560
+++ loncom/interface/lonparmset.pm 2016/10/25 16:38:54 1.569
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Handler to set parameters for assessments
#
-# $Id: lonparmset.pm,v 1.560 2016/07/12 20:30:20 damieng Exp $
+# $Id: lonparmset.pm,v 1.569 2016/10/25 16:38:54 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -336,6 +336,10 @@ use LONCAPA qw(:DEFAULT :match);
##################################################
# Page header
+#
+# @param {Apache2::RequestRec} $r - Apache request object
+# @param {string} $mode - selected tab, 'parmset' for course and problem settings, or 'coursepref' for course settings
+# @param {string} $crstype - course type ('Community' for community settings)
sub startSettingsScreen {
my ($r,$mode,$crstype)=@_;
@@ -363,22 +367,47 @@ sub endSettingsScreen {
##################################################
-# TABLE MODE
+# (mostly) TABLE MODE
# (parmval is also used for the log of parameter changes)
##################################################
+# Calls parmval_by_symb, getting the symb from $id with &symbcache.
+#
+# @param {string} $what - part info and parameter name separated by a dot, e.g. '0.weight'
+# @param {string} $id - resource id or map pc
+# @param {string} $def - the resource's default value for this parameter
+# @param {string} $uname - user name
+# @param {string} $udom - user domain
+# @param {string} $csec - section name
+# @param {string} $cgroup - group name
+# @param {hash reference} $courseopt - course parameters hash (result of lonnet::get_courseresdata, dump of course's resourcedata.db)
+# @returns {Array}
sub parmval {
my ($what,$id,$def,$uname,$udom,$csec,$cgroup,$courseopt)=@_;
return &parmval_by_symb($what,&symbcache($id),$def,$uname,$udom,$csec,
$cgroup,$courseopt);
}
+# Returns an array containing
+# - the most specific level that is defined for that parameter (integer)
+# - an array with the level as index and the parameter value as value (when defined)
+# (level 1 is the most specific and will have precedence)
+#
+# @param {string} $what - part info and parameter name separated by a dot, e.g. '0.weight'
+# @param {string} $symb - resource symb or map src
+# @param {string} $def - the resource's default value for this parameter
+# @param {string} $uname - user name
+# @param {string} $udom - user domain
+# @param {string} $csec - section name
+# @param {string} $cgroup - group name
+# @param {hash reference} $courseopt - course parameters hash (result of lonnet::get_courseresdata, dump of course's resourcedata.db)
+# @returns {Array}
sub parmval_by_symb {
my ($what,$symb,$def,$uname,$udom,$csec,$cgroup,$courseopt)=@_;
my $useropt;
if ($uname ne '' && $udom ne '') {
- $useropt = &Apache::lonnet::get_userresdata($uname,$udom);
+ $useropt = &Apache::lonnet::get_userresdata($uname,$udom);
}
my $result='';
@@ -386,7 +415,10 @@ sub parmval_by_symb {
# ----------------------------------------------------- Cascading lookup scheme
my $map=(&Apache::lonnet::decode_symb($symb))[0];
$map = &Apache::lonnet::deversion($map);
-
+
+ # NOTE: some of that code looks redondant with code in lonnavmaps::parmval_real,
+ # any change should be reflected there.
+
my $symbparm=$symb.'.'.$what;
my $recurseparm=$map.'___(rec).'.$what;
my $mapparm=$map.'___(all).'.$what;
@@ -409,16 +441,19 @@ sub parmval_by_symb {
# --------------------------------------------------------- first, check course
+# 18 - General Course
if (defined($$courseopt{$courselevel})) {
$outpar[18]=$$courseopt{$courselevel};
$result=18;
}
+# 17 - Map or Folder level in course (recursive)
if (defined($$courseopt{$courseleveli})) {
$outpar[17]=$$courseopt{$courseleveli};
$result=17;
}
+# 16 - Map or Folder level in course (non-recursive)
if (defined($$courseopt{$courselevelm})) {
$outpar[16]=$$courseopt{$courselevelm};
$result=16;
@@ -426,14 +461,17 @@ sub parmval_by_symb {
# ------------------------------------------------------- second, check default
+# 15 - resource default
if (defined($def)) { $outpar[15]=$def; $result=15; }
# ------------------------------------------------------ third, check map parms
+# 14 - map default
my $thisparm=&parmhash($symbparm);
if (defined($thisparm)) { $outpar[14]=$thisparm; $result=14; }
+# 13 - resource level in course
if (defined($$courseopt{$courselevelr})) {
$outpar[13]=$$courseopt{$courselevelr};
$result=13;
@@ -441,18 +479,22 @@ sub parmval_by_symb {
# ------------------------------------------------------ fourth, back to course
if ($csec ne '') {
+# 12 - General for section
if (defined($$courseopt{$seclevel})) {
$outpar[12]=$$courseopt{$seclevel};
$result=12;
}
+# 11 - Map or Folder level for section (recursive)
if (defined($$courseopt{$secleveli})) {
$outpar[11]=$$courseopt{$secleveli};
$result=11;
}
+# 10 - Map or Folder level for section (non-recursive)
if (defined($$courseopt{$seclevelm})) {
$outpar[10]=$$courseopt{$seclevelm};
$result=10;
}
+# 9 - resource level in section
if (defined($$courseopt{$seclevelr})) {
$outpar[9]=$$courseopt{$seclevelr};
$result=9;
@@ -460,18 +502,22 @@ sub parmval_by_symb {
}
# ------------------------------------------------------ fifth, check course group
if ($cgroup ne '') {
+# 8 - General for group
if (defined($$courseopt{$grplevel})) {
$outpar[8]=$$courseopt{$grplevel};
$result=8;
}
+# 7 - Map or Folder level for group (recursive)
if (defined($$courseopt{$grpleveli})) {
$outpar[7]=$$courseopt{$grpleveli};
$result=7;
}
+# 6 - Map or Folder level for group (non-recursive)
if (defined($$courseopt{$grplevelm})) {
$outpar[6]=$$courseopt{$grplevelm};
$result=6;
}
+# 5 - resource level in group
if (defined($$courseopt{$grplevelr})) {
$outpar[5]=$$courseopt{$grplevelr};
$result=5;
@@ -481,25 +527,29 @@ sub parmval_by_symb {
# ---------------------------------------------------------- sixth, check user
if ($uname ne '') {
- if (defined($$useropt{$courselevel})) {
- $outpar[4]=$$useropt{$courselevel};
- $result=4;
- }
+# 4 - General for specific student
+ if (defined($$useropt{$courselevel})) {
+ $outpar[4]=$$useropt{$courselevel};
+ $result=4;
+ }
- if (defined($$useropt{$courseleveli})) {
- $outpar[3]=$$useropt{$courseleveli};
- $result=3;
- }
+# 3 - Map or Folder level for specific student (recursive)
+ if (defined($$useropt{$courseleveli})) {
+ $outpar[3]=$$useropt{$courseleveli};
+ $result=3;
+ }
- if (defined($$useropt{$courselevelm})) {
- $outpar[2]=$$useropt{$courselevelm};
- $result=2;
- }
+# 2 - Map or Folder level for specific student (non-recursive)
+ if (defined($$useropt{$courselevelm})) {
+ $outpar[2]=$$useropt{$courselevelm};
+ $result=2;
+ }
- if (defined($$useropt{$courselevelr})) {
- $outpar[1]=$$useropt{$courselevelr};
- $result=1;
- }
+# 1 - resource level for specific student
+ if (defined($$useropt{$courselevelr})) {
+ $outpar[1]=$$useropt{$courselevelr};
+ $result=1;
+ }
}
return ($result,@outpar);
}
@@ -509,20 +559,25 @@ sub parmval_by_symb {
# --- Caches local to lonparmset
+# Reset lonparmset caches (called at the beginning and end of the handler).
sub reset_caches {
&resetparmhash();
&resetsymbcache();
&resetrulescache();
}
+# cache for map parameters, stored temporarily in $env{'request.course.fn'}_parms.db
+# (these parameters come from param elements in .sequence files created with the advanced RAT)
{
- my $parmhashid;
- my %parmhash;
+ my $parmhashid; # course identifier, to initialize the cache only once for a course
+ my %parmhash; # the parameter cache
+ # reset map parameter hash
sub resetparmhash {
undef($parmhashid);
undef(%parmhash);
}
+ # dump the _parms.db database into %parmhash
sub cacheparmhash {
if ($parmhashid eq $env{'request.course.fn'}) { return; }
my %parmhashfile;
@@ -534,6 +589,7 @@ sub reset_caches {
}
}
+ # returns a parameter value for an identifier symb.parts.parameter, using the map parameter cache
sub parmhash {
my ($id) = @_;
&cacheparmhash();
@@ -541,14 +597,18 @@ sub reset_caches {
}
}
+# cache resource id or map pc -> resource symb or map src, using lonnavmaps to find association
{
- my $symbsid;
- my %symbs;
+ my $symbsid; # course identifier, to initialize the cache only once for a course
+ my %symbs; # hash id->symb
+ # reset the id->symb cache
sub resetsymbcache {
undef($symbsid);
undef(%symbs);
}
+ # returns the resource symb or map src corresponding to a resource id or map pc
+ # (using lonnavmaps and a cache)
sub symbcache {
my $id=shift;
if ($symbsid ne $env{'request.course.id'}) {
@@ -569,14 +629,16 @@ sub reset_caches {
}
}
+# cache for parameter default actions (stored in parmdefactions.db)
{
- my $rulesid;
- my %rules;
+ my $rulesid; # course identifier, to initialize the cache only once for a course
+ my %rules; # parameter default actions hash
sub resetrulescache {
undef($rulesid);
undef(%rules);
}
+ # returns the value for a given key in the parameter default action hash
sub rulescache {
my $id=shift;
if ($rulesid ne $env{'request.course.id'}
@@ -591,7 +653,12 @@ sub reset_caches {
}
-
+# Returns the values of the parameter type default action
+# "default value when manually setting".
+# If none is defined, ('','','','','') is returned.
+#
+# @param {string} $type - parameter type
+# @returns {Array} - (hours, min, sec, value)
sub preset_defaults {
my $type=shift;
if (&rulescache($type.'_action') eq 'default') {
@@ -607,8 +674,13 @@ sub preset_defaults {
}
-
-
+# Checks that a date is after enrollment start date and before
+# enrollment end date.
+# Returns HTML with a warning if it is not, or the empty string otherwise.
+# This is used by both overview and table modes.
+#
+# @param {integer} $checkdate - the date to check.
+# @returns {string} - HTML possibly containing a localized warning message.
sub date_sanity_info {
my $checkdate=shift;
unless ($checkdate) { return ''; }
@@ -643,26 +715,39 @@ sub date_sanity_info {
# }
return $result;
}
-##################################################
-##################################################
-#
-# Store a parameter by ID
-#
-# Takes
-# - resource id
-# - name of parameter
-# - level
-# - new value
-# - new type
-# - username
-# - userdomain
+
+# Store a parameter value and type by ID, also triggering more parameter changes based on parameter default actions.
+#
+# @param {string} $sresid - resource id or map pc
+# @param {string} $spnam - part info and parameter name separated by a dot or underscore, e.g. '0.weight'
+# @param {integer} $snum - level
+# @param {string} $nval - new value
+# @param {string} $ntype - new type
+# @param {string} $uname - username
+# @param {string} $udom - userdomain
+# @param {string} $csec - section name
+# @param {string} $cgroup - group name
sub storeparm {
my ($sresid,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$cgroup)=@_;
&storeparm_by_symb(&symbcache($sresid),$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,'',$cgroup);
}
-my %recstack;
+my %recstack; # hash parameter name -> 1 when a parameter was used before in a recursive call to storeparm_by_symb
+
+# Store a parameter value and type by symb, also triggering more parameter changes based on parameter default actions.
+# Uses storeparm_by_symb_inner to actually store the parameter, ignoring any returned error.
+#
+# @param {string} $symb - resource symb or map src
+# @param {string} $spnam - part info and parameter name separated by a dot or underscore, e.g. '0.weight'
+# @param {integer} $snum - level
+# @param {string} $nval - new value
+# @param {string} $ntype - new type
+# @param {string} $uname - username
+# @param {string} $udom - userdomain
+# @param {string} $csec - section name
+# @param {boolean} $recflag - should be true for recursive calls to storeparm_by_symb, false otherwise
+# @param {string} $cgroup - group name
sub storeparm_by_symb {
my ($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$recflag,$cgroup)=@_;
unless ($recflag) {
@@ -692,8 +777,7 @@ sub storeparm_by_symb {
# are there restrictions?
if (&rulescache($triggered.'_triggervalue')=~/\w/) {
$active=0;
- foreach my $possiblevalue (split(/\s*\,
- \s*/,&rulescache($triggered.'_triggervalue'))) {
+ foreach my $possiblevalue (split(/\s*\,\s*/,&rulescache($triggered.'_triggervalue'))) {
if (lc($possiblevalue) eq lc($nval)) { $active=1; }
}
}
@@ -715,10 +799,25 @@ sub storeparm_by_symb {
return '';
}
+# Adds all given arguments to the course parameter log.
+# @returns {string} - the answer to the lonnet query.
sub log_parmset {
return &Apache::lonnet::write_log('course','parameterlog',@_);
}
+# Store a parameter value and type by symb, without using the parameter default actions.
+# Expire related sheets.
+#
+# @param {string} $symb - resource symb or map src
+# @param {string} $spnam - part info and parameter name separated by a dot, e.g. '0.weight'
+# @param {integer} $snum - level
+# @param {string} $nval - new value
+# @param {string} $ntype - new type
+# @param {string} $uname - username
+# @param {string} $udom - userdomain
+# @param {string} $csec - section name
+# @param {string} $cgroup - group name
+# @returns {string} - HTML code with an error message if the parameter could not be stored.
sub storeparm_by_symb_inner {
# ---------------------------------------------------------- Get symb, map, etc
my ($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$cgroup)=@_;
@@ -826,6 +925,16 @@ sub storeparm_by_symb_inner {
}
+# Returns HTML with the value of the given parameter,
+# using a readable format for dates, and
+# a warning if there is a problem with a date.
+# Used by table mode.
+# Returns HTML for the editmap.png image if no value is defined and $editable is true.
+#
+# @param {string} $value - the parameter value
+# @param {string} $type - the parameter type
+# @param {string} $name - the parameter name (unused)
+# @param {boolean} $editable - Set to true to get an icon when no value is defined.
sub valout {
my ($value,$type,$name,$editable)=@_;
my $result = '';
@@ -904,6 +1013,15 @@ sub valout {
}
+# Returns HTML containing a link on a parameter value, for table mode.
+# The link uses the javascript function 'pjump'.
+#
+# @param {string} $type - parameter type
+# @param {string} $dis - dialog title for editing the parameter value and type
+# @param {string} $value - parameter value
+# @param {string} $marker - identifier for the parameter, "resource id&part_parameter name&level", will be passed as pres_marker when the user submits a change.
+# @param {string} $return - prefix for the name of the form and field names that will be used to submit the form ('parmform.pres')
+# @param {string} $call - javascript function to call to submit the form ('psub')
sub plink {
my ($type,$dis,$value,$marker,$return,$call)=@_;
my $winvalue=$value;
@@ -930,6 +1048,7 @@ sub plink {
$valout.'';
}
+# Javascript for table mode.
sub page_js {
my $selscript=&Apache::loncommon::studentbrowser_javascript();
@@ -946,16 +1065,16 @@ sub page_js {
document.parmform.action+='#'+document.parmform.pres_marker.value;
var typedef=new Array();
typedef=document.parmform.pres_type.value.split('_');
- if (document.parmform.pres_type.value!='') {
- if (typedef[0]=='date') {
- eval('document.parmform.recent_'+
- document.parmform.pres_type.value+
- '.value=document.parmform.pres_value.value;');
- } else {
- eval('document.parmform.recent_'+typedef[0]+
- '.value=document.parmform.pres_value.value;');
+ if (document.parmform.pres_type.value!='') {
+ if (typedef[0]=='date') {
+ eval('document.parmform.recent_'+
+ document.parmform.pres_type.value+
+ '.value=document.parmform.pres_value.value;');
+ } else {
+ eval('document.parmform.recent_'+typedef[0]+
+ '.value=document.parmform.pres_value.value;');
+ }
}
- }
document.parmform.submit();
} else {
document.parmform.pres_value.value='';
@@ -979,6 +1098,8 @@ ENDJS
}
+# Javascript to show or hide the map selection (function showHide_courseContent),
+# for table and overview modes.
sub showhide_js {
return <<"COURSECONTENTSCRIPT";
@@ -999,6 +1120,7 @@ function showHide_courseContent() {
COURSECONTENTSCRIPT
}
+# Javascript functions showHideLenient and toggleParmTextbox, for overview mode
sub toggleparmtextbox_js {
return <<"ENDSCRIPT";
@@ -1058,6 +1180,7 @@ function toggleParmTextbox(form,key) {
ENDSCRIPT
}
+# Javascript function validateParms, for overview mode
sub validateparms_js {
return <<'ENDSCRIPT';
@@ -1131,6 +1254,7 @@ function validateParms() {
ENDSCRIPT
}
+# Javascript initialization, for overview mode
sub ipacc_boxes_js {
my $remove = &mt('Remove');
return <<"END";
@@ -1155,6 +1279,7 @@ sub ipacc_boxes_js {
END
}
+# Javascript function toggleSecret, for overview mode.
sub done_proctor_js {
return <<"END";
function toggleSecret(form,radio,key) {
@@ -1180,6 +1305,10 @@ END
}
+# Prints HTML page start for table mode.
+# @param {Apache2::RequestRec} $r - the Apache request
+# @param {string} $psymb - resource symb
+# @param {string} $crstype - course type (Community / Course / Placement Test)
sub startpage {
my ($r,$psymb,$crstype) = @_;
@@ -1228,9 +1357,34 @@ ENDHEAD
}
+# Prints a row for table mode (except for the tr start).
+# Every time a hash reference is passed, a single entry is used, so print_row
+# could just use these values, but why make it simple when it can be complicated ?
+#
+# @param {Apache2::RequestRec} $r - the Apache request
+# @param {string} $which - parameter key ('parameter_'.part.'_'.name)
+# @param {hash reference} $part - parameter key -> parameter part (can be problem part.'_'.response id for response parameters)
+# @param {hash reference} $name - parameter key -> parameter name
+# @param {hash reference} $symbp - map pc or resource/map id -> map src.'___(all)' or resource symb
+# @param {string} $rid - resource id
+# @param {hash reference} $default - parameter key -> resource parameter default value
+# @param {hash reference} $defaulttype - parameter key -> resource parameter default type
+# @param {hash reference} $display - parameter key -> full title for the parameter
+# @param {string} $defbgone - user level and other levels background color
+# @param {string} $defbgtwo - section level background color, also used for part number
+# @param {string} $defbgthree - group level background color
+# @param {string} $parmlev - parameter level (Resource:'full', Map:'map', Course:'general')
+# @param {string} $uname - user name
+# @param {string} $udom - user domain
+# @param {string} $csec - section name
+# @param {string} $cgroup - group name
+# @param {array reference} $usersgroups - list of groups the user belongs to, if any
+# @param {boolean} $noeditgrp - true if no edit is allowed for group level parameters
+# @param {boolean} $readonly - true if no editing allowed.
sub print_row {
my ($r,$which,$part,$name,$symbp,$rid,$default,$defaulttype,$display,$defbgone,
- $defbgtwo,$defbgthree,$parmlev,$uname,$udom,$csec,$cgroup,$usersgroups,$noeditgrp)=@_;
+ $defbgtwo,$defbgthree,$parmlev,$uname,$udom,$csec,$cgroup,$usersgroups,$noeditgrp,
+ $readonly)=@_;
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom);
@@ -1275,27 +1429,27 @@ sub print_row {
if ($parmlev eq 'general') {
if ($uname) {
- &print_td($r,4,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
+ &print_td($r,4,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly);
} elsif ($cgroup) {
- &print_td($r,8,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
+ &print_td($r,8,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp,$readonly);
} elsif ($csec) {
- &print_td($r,12,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
+ &print_td($r,12,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly);
} else {
- &print_td($r,18,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
+ &print_td($r,18,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly);
}
} elsif ($parmlev eq 'map') {
if ($uname) {
- &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
- &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
+ &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly);
+ &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly);
} elsif ($cgroup) {
- &print_td($r,7,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
- &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
+ &print_td($r,7,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp,$readonly);
+ &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp,$readonly);
} elsif ($csec) {
- &print_td($r,11,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
- &print_td($r,10,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
+ &print_td($r,11,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly);
+ &print_td($r,10,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly);
} else {
- &print_td($r,17,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
- &print_td($r,16,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
+ &print_td($r,17,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly);
+ &print_td($r,16,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly);
}
} else {
if ($uname) {
@@ -1315,35 +1469,35 @@ sub print_row {
}
}
- &print_td($r,18,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
- &print_td($r,17,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
- &print_td($r,16,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
- &print_td($r,15,'#FFDDDD',$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
- &print_td($r,14,'#FFDDDD',$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
- &print_td($r,13,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
+ &print_td($r,18,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly);
+ &print_td($r,17,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly);
+ &print_td($r,16,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly);
+ &print_td($r,15,'#FFDDDD',$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly);
+ &print_td($r,14,'#FFDDDD',$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly);
+ &print_td($r,13,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly);
if ($csec) {
- &print_td($r,12,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
- &print_td($r,11,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
- &print_td($r,10,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
- &print_td($r,9,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
+ &print_td($r,12,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly);
+ &print_td($r,11,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly);
+ &print_td($r,10,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly);
+ &print_td($r,9,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly);
}
if ($cgroup) {
- &print_td($r,8,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
- &print_td($r,7,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
- &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
- &print_td($r,5,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
+ &print_td($r,8,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp,$readonly);
+ &print_td($r,7,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp,$readonly);
+ &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp,$readonly);
+ &print_td($r,5,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp.$readonly);
}
if ($uname) {
if ($othergrp) {
$r->print($othergrp);
}
- &print_td($r,4,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
- &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
- &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
- &print_td($r,1,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
+ &print_td($r,4,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly);
+ &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly);
+ &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly);
+ &print_td($r,1,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly);
}
} # end of $parmlev if/else
@@ -1364,30 +1518,52 @@ sub print_row {
$r->print("\n");
}
+# Prints a cell for table mode.
+#
+# FIXME: some of these parameter names are uninspired ($which and $value)
+# Also, it would make more sense to pass the display for this cell rather
+# than the full display hash and the key to use.
+#
+# @param {Apache2::RequestRec} $r - the Apache request
+# @param {integer} $which - level
+# @param {string} $defbg - cell background color
+# @param {integer} $result - the most specific level that is defined for that parameter
+# @param {array reference} $outpar - array level -> parameter value (when defined)
+# @param {string} $mprefix - resource id.'&'.part.'_'.parameter name.'&'
+# @param {string} $value - parameter key ('parameter_'.part.'_'.name)
+# @param {array reference} $typeoutpar - array level -> parameter type (when defined)
+# @param {hash reference} $display - parameter key -> full title for the parameter
+# @param {boolean} $noeditgrp - true if no edit is allowed for group level parameters
+# @param {boolean} $readonly -true if editing not allowed.
sub print_td {
- my ($r,$which,$defbg,$result,$outpar,$mprefix,$value,$typeoutpar,$display,$noeditgrp)=@_;
+ my ($r,$which,$defbg,$result,$outpar,$mprefix,$value,$typeoutpar,$display,$noeditgrp,$readonly)=@_;
$r->print('
');
my $nolink = 0;
- if ($which == 14 || $which == 15) {
- $nolink = 1;
- } elsif (($env{'request.course.sec'} ne '') && ($which > 12)) {
+ if ($readonly) {
$nolink = 1;
- } elsif ($which == 5 || $which == 6 || $which == 7 || $which == 8) {
- if ($noeditgrp) {
- $nolink = 1;
- }
- } elsif ($mprefix =~ /availablestudent\&$/) {
- if ($which > 4) {
+ } else {
+ if ($which == 14 || $which == 15) {
$nolink = 1;
- }
- } elsif ($mprefix =~ /examcode\&$/) {
- unless ($which == 2) {
+ } elsif (($env{'request.course.sec'} ne '') && ($which > 12)) {
$nolink = 1;
+ } elsif ($which == 5 || $which == 6 || $which == 7 || $which == 8) {
+ if ($noeditgrp) {
+ $nolink = 1;
+ }
+ } elsif ($mprefix =~ /availablestudent\&$/) {
+ if ($which > 4) {
+ $nolink = 1;
+ }
+ } elsif ($mprefix =~ /examcode\&$/) {
+ unless ($which == 2) {
+ $nolink = 1;
+ }
}
}
if ($nolink) {
$r->print(&valout($$outpar[$which],$$typeoutpar[$which],$mprefix));
+# FIXME: probably a good thing that mprefix is not used in valout, because it does not look like a parameter name !
} else {
$r->print(&plink($$typeoutpar[$which],
$$display{$value},$$outpar[$which],
@@ -1396,6 +1572,19 @@ sub print_td {
$r->print('
'."\n");
}
+# FIXME: Despite the name, this does not print anything, the $r parameter is unused.
+# Returns HTML and other info for the cell added when a user is selected
+# and that user is in several groups. This is the cell with the title "Control by other group".
+#
+# @param {Apache2::RequestRec} $r - the Apache request (unused)
+# @param {string} $what - parameter part.'.'.parameter name
+# @param {string} $rid - resource id
+# @param {string} $cgroup - group name
+# @param {string} $defbg - cell background color
+# @param {array reference} $usersgroups - list of groups the user belongs to, if any
+# @param {integer} $result - level
+# @param {hash reference} $courseopt - course parameters hash (result of lonnet::get_courseresdata, dump of course's resourcedata.db)
+# @returns {Array} - array (parameter value for the other group, HTML for the cell, HTML with the value, name of the other group)
sub print_usergroups {
my ($r,$what,$rid,$cgroup,$defbg,$usersgroups,$result,$courseopt) = @_;
my $courseid = $env{'request.course.id'};
@@ -1429,6 +1618,17 @@ sub print_usergroups {
return ($coursereply,$output,$grp_parm,$resultgroup);
}
+# Looks for a group with a defined parameter for given user and parameter.
+# Used by print_usergroups.
+#
+# @param {string} $courseid - the course id
+# @param {array reference} $usersgroups - list of groups the user belongs to, if any
+# @param {string} $symbparm - end of the course parameter hash key for the group resource level
+# @param {string} $mapparm - end of the course parameter hash key for the group map/folder level
+# @param {string} $recurseparm - end of the course parameter hash key for the group recursive level
+# @param {string} $what - parameter part.'.'.parameter name
+# @param {hash reference} $courseopt - course parameters hash
+# @returns {Array} - (parameter value for the group, course parameter hash key for the parameter, name of the group, level name, parameter type)
sub parm_control_group {
my ($courseid,$usersgroups,$symbparm,$mapparm,$recurseparm,$what,$courseopt) = @_;
my ($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype);
@@ -1455,6 +1655,21 @@ sub parm_control_group {
+# Extracts lots of information about all of the the course's resources into a variety of hashes, using lonnavmaps and lonnet::metadata.
+# All the parameters are references and are filled by the sub.
+#
+# @param {array reference} $ids - resource and map ids
+# @param {hash reference} $typep - hash resource/map id -> resource type (file extension)
+# @param {hash reference} $keyp - hash resource/map id -> comma-separated list of parameter keys from lonnet::metadata
+# @param {hash reference} $allparms - hash parameter name -> parameter title
+# @param {hash reference} $allparts - hash parameter part -> part title (a parameter part can be problem part.'_'.response id for response parameters)
+# @param {hash reference} $allmaps - hash map pc -> map src
+# @param {hash reference} $mapp - hash map pc or resource/map id -> enclosing map src
+# @param {hash reference} $symbp - hash map pc or resource/map id -> map src.'___(all)' for a map or resource symb for a resource
+# @param {hash reference} $maptitles - hash map pc or src -> map title (this should really be two separate hashes)
+# @param {hash reference} $uris - hash resource/map id -> resource src
+# @param {hash reference} $keyorder - hash parameter key -> appearance rank for this parameter when looking through every resource and every parameter, starting at 100 (integer)
+# @param {hash reference} $defkeytype - hash parameter name -> parameter type
sub extractResourceInformation {
my $ids = shift;
my $typep = shift;
@@ -1555,17 +1770,22 @@ sub extractResourceInformation {
}
-
+# Tells if a parameter type is a date.
+#
+# @param {string} type - parameter type
+# @returns{boolean} - true if it is a date
sub isdateparm {
my $type=shift;
return (($type=~/^date/) && (!($type eq 'date_interval')));
}
+# Prints the HTML and Javascript to select parameters, with various shortcuts.
+# FIXME: remove unused parameters
#
-# parmmenu displays a list of the selected parameters.
-# It also offers a link to show/hide the complete parameter list
-# from which you can select all desired parameters.
-#
+# @param {Apache2::RequestRec} $r - the Apache request (unused)
+# @param {hash reference} $allparms - hash parameter name -> parameter title
+# @param {array reference} $pscat - list of selected parameter names (unused)
+# @param {hash reference} $keyorder - hash parameter key -> appearance rank (unused)
sub parmmenu {
my ($r,$allparms,$pscat,$keyorder)=@_;
my $tempkey;
@@ -1581,7 +1801,7 @@ sub parmmenu {
displayOverview = "none"
}
- for (i=0; i
@@ -1650,7 +1868,10 @@ ENDSCRIPT
&shortCuts($r,$allparms,$pscat,$keyorder);
$r->print('');
}
-# return a hash
+
+# Returns parameter categories.
+#
+# @returns {hash} - category name -> title in English
sub categories {
return ('time_settings' => 'Time Settings',
'grading' => 'Grading',
@@ -1664,7 +1885,9 @@ sub categories {
'misc' => 'Miscellaneous' );
}
-# return a hash. Like a look-up table
+# Returns the category for each parameter.
+#
+# @returns {hash} - parameter name -> category name
sub lookUpTableParameter {
return (
@@ -1715,6 +1938,10 @@ sub lookUpTableParameter {
);
}
+# Adds the given parameter name to an array of arrays listing all parameters for each category.
+#
+# @param {string} $name - parameter name
+# @param {array reference} $catList - array reference category name -> array reference of parameter names
sub whatIsMyCategory {
my $name = shift;
my $catList = shift;
@@ -1738,6 +1965,11 @@ sub whatIsMyCategory {
}
}
+# Sorts parameter names based on appearance order.
+#
+# @param {array reference} name - array reference of parameter names
+# @param {hash reference} $keyorder - hash parameter key -> appearance rank
+# @returns {Array} - array of parameter names
sub keysindisplayorderCategory {
my ($name,$keyorder)=@_;
return sort {
@@ -1745,6 +1977,9 @@ sub keysindisplayorderCategory {
} ( @{$name});
}
+# Returns a hash category name -> order, starting at 1 (integer)
+#
+# @returns {hash}
sub category_order {
return (
'time_settings' => 1,
@@ -1761,6 +1996,12 @@ sub category_order {
}
+# Prints HTML to let the user select parameters, from a list of all parameters organized by category.
+#
+# @param {Apache2::RequestRec} $r - the Apache request
+# @param {hash reference} $allparms - hash parameter name -> parameter title
+# @param {array reference} $pscat - list of selected parameter names
+# @param {hash reference} $keyorder - hash parameter key -> appearance rank
sub parmboxes {
my ($r,$allparms,$pscat,$keyorder)=@_;
my %categories = &categories();
@@ -1802,9 +2043,14 @@ sub parmboxes {
}
$r->print("\n");
}
+
+# Prints HTML with shortcuts to select groups of parameters in one click, or deselect all.
+# FIXME: remove unused parameters
#
-# This function offers some links on the parameter section to get with one click a group a parameters
-#
+# @param {Apache2::RequestRec} $r - the Apache request
+# @param {hash reference} $allparms - hash parameter name -> parameter title (unused)
+# @param {array reference} $pscat - list of selected parameter names (unused)
+# @param {hash reference} $keyorder - hash parameter key -> appearance rank (unused)
sub shortCuts {
my ($r,$allparms,$pscat,$keyorder)=@_;
@@ -1837,6 +2083,12 @@ sub shortCuts {
);
}
+# Prints HTML to select parts to view (except for the title).
+# Used by table and overview modes.
+#
+# @param {Apache2::RequestRec} $r - the Apache request
+# @param {hash reference} $allparts - hash parameter part -> part title
+# @param {array reference} $psprt - list of selected parameter parts
sub partmenu {
my ($r,$allparts,$psprt)=@_;
my $selsize = 1+scalar(keys(%{$allparts}));
@@ -1846,7 +2098,7 @@ sub partmenu {
$r->print('');
}
+# Prints HTML to select a user and/or a group.
+# Used by table mode.
+#
+# @param {Apache2::RequestRec} $r - the Apache request
+# @param {string} $uname - selected user name
+# @param {string} $id - selected Student/Employee ID
+# @param {string} $udom - selected user domain
+# @param {string} $csec - selected section name
+# @param {string} $cgroup - selected group name
+# @param {string} $parmlev - parameter level (Resource:'full', Map:'map', Course:'general')
+# @param {array reference} $usersgroups - list of groups the user belongs to, if any
+# @param {string} $pssymb - resource symb (when a single resource is selected)
sub usermenu {
my ($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,$usersgroups,$pssymb)=@_;
my $chooseopt=&Apache::loncommon::select_dom_form($udom,'udom').' '.
@@ -1974,16 +2238,23 @@ function group_or_section(caller) {
,$chooseopt));
}
+# Prints HTML to select parameters from a list of all parameters.
+# Uses parmmenu and parmboxes.
+# Used by table and overview modes.
#
-# This function shows on table Mode the available Parameters for the selected Resources
-#
+# @param {Apache2::RequestRec} $r - the Apache request
+# @param {hash reference} $allparms - hash parameter name -> parameter title
+# @param {array reference} $pscat - list of selected parameter names
+# @param {array reference} $psprt - list of selected parameter parts (unused)
+# @param {hash reference} $keyorder - hash parameter key -> appearance rank
+# @param {string} [$divid] - name used to give an id to the HTML element for the scroll box
sub displaymenu {
my ($r,$allparms,$pscat,$psprt,$keyorder,$divid)=@_;
$r->print(&Apache::lonhtmlcommon::start_pick_box());
$r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parameters to View')));
- &parmmenu($r,$allparms,$pscat,$keyorder);
+ &parmmenu($r,$allparms,$pscat,$keyorder); # only $allparms is used by parmmenu
$r->print(&Apache::loncommon::start_scrollbox('480px','440px','200px',$divid));
&parmboxes($r,$allparms,$pscat,$keyorder);
$r->print(&Apache::loncommon::end_scrollbox());
@@ -1993,6 +2264,14 @@ sub displaymenu {
}
+# Prints HTML to select a map.
+# Used by table mode and overview mode.
+#
+# @param {Apache2::RequestRec} $r - the Apache request
+# @param {hash reference} $allmaps - hash map pc -> map src
+# @param {string} $pschp - selected map pc, or 'all'
+# @param {hash reference} $maptitles - hash map id or src -> map title
+# @param {hash reference} $symbp - hash map pc or resource/map id -> map src.'___(all)' or resource symb
sub mapmenu {
my ($r,$allmaps,$pschp,$maptitles,$symbp)=@_;
my %allmaps_inverted = reverse %$allmaps;
@@ -2144,8 +2423,12 @@ sub mapmenu {
}
}
-# Build up the select Box to choose if your parameter specification should work for the resource, map/folder or the course level
-# The value of default selection in the select box is set by the value that is given by the argument in $parmlev.
+# Prints HTML to select the parameter level (resource, map/folder or course).
+# Used by table and overview modes.
+#
+# @param {Apache2::RequestRec} $r - the Apache request
+# @param {hash reference} $alllevs - all parameter levels, hash English title -> value
+# @param {string} $parmlev - selected level value (full|map|general), or ''
sub levelmenu {
my ($r,$alllevs,$parmlev)=@_;
@@ -2163,6 +2446,11 @@ sub levelmenu {
}
+# Returns HTML to select a section (with a select HTML element).
+# Used by overview mode.
+#
+# @param {array reference} $selectedsections - list of selected section ids
+# @returns {string}
sub sectionmenu {
my ($selectedsections)=@_;
my %sectionhash = &Apache::loncommon::get_sections();
@@ -2188,6 +2476,11 @@ sub sectionmenu {
return $output;
}
+# Returns HTML to select a group (with a select HTML element).
+# Used by overview mode.
+#
+# @param {array reference} $selectedgroups - list of selected group names
+# @returns {string}
sub groupmenu {
my ($selectedgroups)=@_;
my %grouphash;
@@ -2210,11 +2503,23 @@ sub groupmenu {
return $output;
}
+# Returns an array with the given parameter split by comma.
+# Used by assessparms (table mode).
+#
+# @param {string} $keyp - the string to split
+# @returns {Array}
sub keysplit {
my $keyp=shift;
return (split(/\,/,$keyp));
}
+# Returns the keys in $name, sorted using $keyorder.
+# Parameters are sorted by key, which means they are sorted by part first, then by name.
+# Used by assessparms (table mode) for resource level.
+#
+# @param {hash reference} $name - parameter key -> parameter name
+# @param {hash reference} $keyorder - hash parameter key -> appearance rank
+# @returns {Array}
sub keysinorder {
my ($name,$keyorder)=@_;
return sort {
@@ -2222,10 +2527,16 @@ sub keysinorder {
} (keys(%{$name}));
}
+# Returns the keys in $name, sorted using $keyorder to sort parameters by name first, then by part.
+# Used by assessparms (table mode) for map and general levels.
+#
+# @param {hash reference} $name - parameter key -> parameter name
+# @param {hash reference} $keyorder - hash parameter key -> appearance rank
+# @returns {Array}
sub keysinorder_bytype {
my ($name,$keyorder)=@_;
return sort {
- my $ta=(split('_',$a))[-1];
+ my $ta=(split('_',$a))[-1]; # parameter name
my $tb=(split('_',$b))[-1];
if ($$keyorder{'parameter_0_'.$ta} == $$keyorder{'parameter_0_'.$tb}) {
return ($a cmp $b);
@@ -2234,6 +2545,12 @@ sub keysinorder_bytype {
} (keys(%{$name}));
}
+# Returns the keys in $name, sorted using $keyorder to sort parameters by name.
+# Used by defaultsetter (parameter settings default actions).
+#
+# @param {hash reference} $name - hash parameter name -> parameter title
+# @param {hash reference} $keyorder - hash parameter key -> appearance rank
+# @returns {Array}
sub keysindisplayorder {
my ($name,$keyorder)=@_;
return sort {
@@ -2241,6 +2558,11 @@ sub keysindisplayorder {
} (keys(%{$name}));
}
+# Prints HTML with a choice to sort results by realm or student first.
+# Used by overview mode.
+#
+# @param {Apache2::RequestRec} $r - the Apache request
+# @param {string} $sortorder - realmstudent|studentrealm
sub sortmenu {
my ($r,$sortorder)=@_;
$r->print('
'
@@ -3157,8 +3525,12 @@ ENDMAPONE
##################################################
# OVERVIEW MODE
##################################################
-my $tableopen;
+my $tableopen; # boolean, true if HTML table is already opened
+
+# Returns HTML with the HTML table start tag and header, unless the table is already opened.
+# @param {boolean} $readonly - true if values cannot be edited (otherwise more columns are added)
+# @returns {string}
sub tablestart {
my ($readonly) = @_;
if ($tableopen) {
@@ -3176,6 +3548,8 @@ sub tablestart {
}
}
+# Returns HTML with the HTML table end tag, unless the table is not opened.
+# @returns {string}
sub tableend {
if ($tableopen) {
$tableopen=0;
@@ -3185,6 +3559,13 @@ sub tableend {
}
}
+# Reads course and user information.
+# If the context is looking for a scalar, returns the course parameters hash (result of lonnet::get_courseresdata, dump of course's resourcedata.db) with added student data from lonnet::get_userresdata (which reads the user's resourcedata.db).
+# The key for student data is modified with '[useropt:'.username.':'.userdomain.'].'.
+# If the context is looking for a list, returns a list with the scalar data and the class list.
+# @param {string} $crs - course number
+# @param {string} $dom - course domain
+# @returns {hash reference|Array}
sub readdata {
my ($crs,$dom)=@_;
# Read coursedata
@@ -3213,8 +3594,24 @@ sub readdata {
}
-# Setting
-
+# Stores parameter data, using form parameters directly.
+#
+# Uses the following form parameters. The variable part in the names is a resourcedata key (except for a modification for user data).
+# set_* (except settext, setipallow, setipdeny) - set a parameter value
+# del_* - remove a parameter
+# datepointer_* - set a date parameter (value is key_* refering to a set of other form parameters)
+# dateinterval_* - set a date interval parameter (value refers to more form parameters)
+# key_* - date values
+# days_* - for date intervals
+# hours_* - for date intervals
+# minutes_* - for date intervals
+# seconds_* - for date intervals
+# done_* - for date intervals
+# typeof_* - parameter type
+#
+# @param {Apache2::RequestRec} $r - the Apache request
+# @param {string} $crs - course number
+# @param {string} $dom - course domain
sub storedata {
my ($r,$crs,$dom)=@_;
# Set userlevel immediately
@@ -3237,151 +3634,152 @@ sub storedata {
$tkey=~s/\.\[useropt\:$tuname\:$tudom\]\./\./;
}
if ($cmd eq 'set' || $cmd eq 'datepointer' || $cmd eq 'dateinterval') {
- my ($data, $typeof, $text, $name, $valchk, $valmatch, $namematch);
- if ($cmd eq 'set') {
- $data=$env{$key};
- $valmatch = '';
- $valchk = $data;
- $typeof=$env{'form.typeof_'.$thiskey};
- $text = &mt('Saved modified parameter for');
- if ($typeof eq 'string_questiontype') {
- $name = 'type';
- } elsif ($typeof eq 'string_lenient') {
- $name = 'lenient';
- my $stringmatch = &standard_string_matches($typeof);
- if (ref($stringmatch) eq 'ARRAY') {
- foreach my $item (@{$stringmatch}) {
- if (ref($item) eq 'ARRAY') {
- my ($regexpname,$pattern) = @{$item};
- if ($pattern ne '') {
- if ($data =~ /$pattern/) {
- $valmatch = $regexpname;
- $valchk = '';
- last;
+ my ($data, $typeof, $text, $name, $valchk, $valmatch, $namematch);
+ if ($cmd eq 'set') {
+ $data=$env{$key};
+ $valmatch = '';
+ $valchk = $data;
+ $typeof=$env{'form.typeof_'.$thiskey};
+ $text = &mt('Saved modified parameter for');
+ if ($typeof eq 'string_questiontype') {
+ $name = 'type';
+ } elsif ($typeof eq 'string_lenient') {
+ $name = 'lenient';
+ my $stringmatch = &standard_string_matches($typeof);
+ if (ref($stringmatch) eq 'ARRAY') {
+ foreach my $item (@{$stringmatch}) {
+ if (ref($item) eq 'ARRAY') {
+ my ($regexpname,$pattern) = @{$item};
+ if ($pattern ne '') {
+ if ($data =~ /$pattern/) {
+ $valmatch = $regexpname;
+ $valchk = '';
+ last;
+ }
}
}
}
}
- }
- } elsif ($typeof eq 'string_discussvote') {
- $name = 'discussvote';
- } elsif ($typeof eq 'string_examcode') {
- $name = 'examcode';
- if (&Apache::lonnet::validCODE($data)) {
- $valchk = 'valid';
- }
- } elsif ($typeof eq 'string_yesno') {
- if ($thiskey =~ /\.retrypartial$/) {
- $name = 'retrypartial';
- }
- }
- } elsif ($cmd eq 'datepointer') {
- $data=&Apache::lonhtmlcommon::get_date_from_form($env{$key});
- $typeof=$env{'form.typeof_'.$thiskey};
- $text = &mt('Saved modified date for');
- if ($typeof eq 'date_start') {
- if ($thiskey =~ /\.printstartdate$/) {
- $name = 'printstartdate';
- if (($data) && ($data > $now)) {
- $valchk = 'future';
+ } elsif ($typeof eq 'string_discussvote') {
+ $name = 'discussvote';
+ } elsif ($typeof eq 'string_examcode') {
+ $name = 'examcode';
+ if (&Apache::lonnet::validCODE($data)) {
+ $valchk = 'valid';
+ }
+ } elsif ($typeof eq 'string_yesno') {
+ if ($thiskey =~ /\.retrypartial$/) {
+ $name = 'retrypartial';
}
}
- } elsif ($typeof eq 'date_end') {
- if ($thiskey =~ /\.printenddate$/) {
- $name = 'printenddate';
- if (($data) && ($data < $now)) {
- $valchk = 'past';
+ } elsif ($cmd eq 'datepointer') {
+ $data=&Apache::lonhtmlcommon::get_date_from_form($env{$key});
+ $typeof=$env{'form.typeof_'.$thiskey};
+ $text = &mt('Saved modified date for');
+ if ($typeof eq 'date_start') {
+ if ($thiskey =~ /\.printstartdate$/) {
+ $name = 'printstartdate';
+ if (($data) && ($data > $now)) {
+ $valchk = 'future';
+ }
+ }
+ } elsif ($typeof eq 'date_end') {
+ if ($thiskey =~ /\.printenddate$/) {
+ $name = 'printenddate';
+ if (($data) && ($data < $now)) {
+ $valchk = 'past';
+ }
}
}
- }
- } elsif ($cmd eq 'dateinterval') {
- $data=&get_date_interval_from_form($thiskey);
- if ($thiskey =~ /\.interval$/) {
- $name = 'interval';
- my $intervaltype = &get_intervaltype($name);
- my $intervalmatch = &standard_interval_matches($intervaltype);
- if (ref($intervalmatch) eq 'ARRAY') {
- foreach my $item (@{$intervalmatch}) {
- if (ref($item) eq 'ARRAY') {
- my ($regexpname,$pattern) = @{$item};
- if ($pattern ne '') {
- if ($data =~ /$pattern/) {
- $valmatch = $regexpname;
- $valchk = '';
- last;
+ } elsif ($cmd eq 'dateinterval') {
+ $data=&get_date_interval_from_form($thiskey);
+ if ($thiskey =~ /\.interval$/) {
+ $name = 'interval';
+ my $intervaltype = &get_intervaltype($name);
+ my $intervalmatch = &standard_interval_matches($intervaltype);
+ if (ref($intervalmatch) eq 'ARRAY') {
+ foreach my $item (@{$intervalmatch}) {
+ if (ref($item) eq 'ARRAY') {
+ my ($regexpname,$pattern) = @{$item};
+ if ($pattern ne '') {
+ if ($data =~ /$pattern/) {
+ $valmatch = $regexpname;
+ $valchk = '';
+ last;
+ }
}
}
}
}
}
+ $typeof=$env{'form.typeof_'.$thiskey};
+ $text = &mt('Saved modified date for');
}
- $typeof=$env{'form.typeof_'.$thiskey};
- $text = &mt('Saved modified date for');
- }
- if ($thiskey =~ m{\.(?:sequence|page)___\(rec\)}) {
- $namematch = 'maplevelrecurse';
- }
- if (($name ne '') || ($namematch ne '')) {
- my ($needsrelease,$needsnewer);
- if ($name ne '') {
- $needsrelease = $Apache::lonnet::needsrelease{"parameter:$name:$valchk:$valmatch:"};
- if ($needsrelease) {
- unless ($got_chostname) {
- ($chostname,$cmajor,$cminor)=¶meter_release_vars();
- $got_chostname = 1;
- }
- $needsnewer = ¶meter_releasecheck($name,$valchk,$valmatch,undef,
- $needsrelease,
- $cmajor,$cminor);
- }
+ if ($thiskey =~ m{\.(?:sequence|page)___\(rec\)}) {
+ $namematch = 'maplevelrecurse';
}
- if ($namematch ne '') {
- if ($needsnewer) {
- undef($namematch);
- } else {
- my $currneeded;
+ if (($name ne '') || ($namematch ne '')) {
+ my ($needsrelease,$needsnewer);
+ if ($name ne '') {
+ $needsrelease = $Apache::lonnet::needsrelease{"parameter:$name:$valchk:$valmatch:"};
if ($needsrelease) {
- $currneeded = $needsrelease;
- }
- $needsrelease =
- $Apache::lonnet::needsrelease{"parameter::::$namematch"};
- if (($needsrelease) && (($currneeded eq '') || ($needsrelease < $currneeded))) {
unless ($got_chostname) {
- ($chostname,$cmajor,$cminor) = ¶meter_release_vars();
+ ($chostname,$cmajor,$cminor)=¶meter_release_vars();
$got_chostname = 1;
}
- $needsnewer = ¶meter_releasecheck(undef,$valchk,$valmatch,$namematch,
- $needsrelease,$cmajor,$cminor);
- } else {
+ $needsnewer = ¶meter_releasecheck($name,$valchk,$valmatch,undef,
+ $needsrelease,
+ $cmajor,$cminor);
+ }
+ }
+ if ($namematch ne '') {
+ if ($needsnewer) {
undef($namematch);
+ } else {
+ my $currneeded;
+ if ($needsrelease) {
+ $currneeded = $needsrelease;
+ }
+ $needsrelease =
+ $Apache::lonnet::needsrelease{"parameter::::$namematch"};
+ if (($needsrelease) &&
+ (($currneeded eq '') || ($needsrelease < $currneeded))) {
+ unless ($got_chostname) {
+ ($chostname,$cmajor,$cminor) = ¶meter_release_vars();
+ $got_chostname = 1;
+ }
+ $needsnewer = ¶meter_releasecheck(undef,$valchk,$valmatch,
+ $namematch, $needsrelease,$cmajor,$cminor);
+ } else {
+ undef($namematch);
+ }
}
}
+ if ($needsnewer) {
+ $r->print(' '.&oldversion_warning($name,$namematch,$data,
+ $chostname,$cmajor,
+ $cminor,$needsrelease));
+ next;
+ }
}
- if ($needsnewer) {
- $r->print(' '.&oldversion_warning($name,$namematch,$data,
- $chostname,$cmajor,
- $cminor,$needsrelease));
- next;
- }
- }
- if (defined($data) and $$olddata{$thiskey} ne $data) {
- if ($tuname) {
- if (&Apache::lonnet::put('resourcedata',{$tkey=>$data,
- $tkey.'.type' => $typeof},
- $tudom,$tuname) eq 'ok') {
- &log_parmset({$tkey=>$data,$tkey.'.type' => $typeof},0,$tuname,$tudom);
- $r->print(' '.$text.' '.
- &Apache::loncommon::plainname($tuname,$tudom));
+ if (defined($data) and $$olddata{$thiskey} ne $data) {
+ if ($tuname) {
+ if (&Apache::lonnet::put('resourcedata',{$tkey=>$data,
+ $tkey.'.type' => $typeof},
+ $tudom,$tuname) eq 'ok') {
+ &log_parmset({$tkey=>$data,$tkey.'.type' => $typeof},0,$tuname,$tudom);
+ $r->print(' '.$text.' '.
+ &Apache::loncommon::plainname($tuname,$tudom));
+ } else {
+ $r->print('
');
+ $newdata{$thiskey}=$data;
+ $newdata{$thiskey.'.type'}=$typeof;
}
- &Apache::lonnet::devalidateuserresdata($tuname,$tudom);
- } else {
- $newdata{$thiskey}=$data;
- $newdata{$thiskey.'.type'}=$typeof;
}
- }
} elsif ($cmd eq 'del') {
if ($tuname) {
if (&Apache::lonnet::del('resourcedata',[$tkey],$tudom,$tuname) eq 'ok') {
@@ -3425,11 +3823,20 @@ sub storedata {
}
}
+# Returns the username and domain from a key created in readdata from a resourcedata key.
+#
+# @param {string} $key - the key
+# @returns {Array}
sub extractuser {
my $key=shift;
return ($key=~/^$env{'request.course.id'}.\[useropt\:($match_username)\:($match_domain)\]\./);
}
+# Parses a parameter key and returns the components.
+#
+# @param {string} $key -
+# @param {hash reference} $listdata -
+# @return {Array} - (student, resource, part, parameter)
sub parse_listdata_key {
my ($key,$listdata) = @_;
# split into student/section affected, and
@@ -3450,9 +3857,18 @@ sub parse_listdata_key {
return ($student,$res,$part,$parm);
}
-# Displays forms for the given data in overview mode (newoverview or overview).
+# Prints HTML with forms for the given parameter data in overview mode (newoverview or overview).
+#
+# @param {Apache2::RequestRec} $r - the Apache request
+# @param {hash reference} $resourcedata - parameter data returned by readdata
+# @param {hash reference} $listdata - data created in secgroup_lister, course id.[section id].part.name -> 1 or course id.[section id].part.name.type -> parameter type
+# @param {string} $sortorder - realmstudent|studentrealm
+# @param {string} $caller - name of the calling sub (overview|newoverview)
+# @param {hash reference} $classlist - from loncoursedata::get_classlist
+# @param {boolean} $readonly - true if editing not allowed
+# @returns{integer} - number of $listdata parameters processed
sub listdata {
- my ($r,$resourcedata,$listdata,$sortorder,$caller,$classlist)=@_;
+ my ($r,$resourcedata,$listdata,$sortorder,$caller,$classlist,$readonly)=@_;
# Start list output
@@ -3516,7 +3932,6 @@ sub listdata {
} keys(%{$listdata})) { # foreach my $thiskey
- my $readonly;
if ($$listdata{$thiskey.'.type'}) {
my $thistype=$$listdata{$thiskey.'.type'};
if ($$resourcedata{$thiskey.'.type'}) {
@@ -3653,6 +4068,12 @@ sub listdata {
return $foundkeys;
}
+# Returns a string representing the interval, directly using form data matching the given key.
+# The returned string may also include information related to proctored exams.
+# Format: seconds['_done'[':'done button title':']['_proctor'['_'proctor key]]]
+#
+# @param {string} $key - suffix for form fields related to the interval
+# @returns {string}
sub get_date_interval_from_form {
my ($key) = @_;
my $seconds = 0;
@@ -3685,6 +4106,12 @@ sub get_date_interval_from_form {
}
+# Returns HTML to enter a text value for a parameter.
+#
+# @param {string} $thiskey - parameter key
+# @param {string} $showval - the current value
+# @param {boolean} $readonly - true if the field should not be made editable
+# @returns {string}
sub default_selector {
my ($thiskey, $showval, $readonly) = @_;
my $disabled;
@@ -3694,6 +4121,12 @@ sub default_selector {
return '';
}
+# Returns HTML to enter allow/deny rules related to IP addresses.
+#
+# @param {string} $thiskey - parameter key
+# @param {string} $showval - the current value
+# @param {boolean} $readonly - true if the fields should not be made editable
+# @returns {string}
sub string_ip_selector {
my ($thiskey, $showval, $readonly) = @_;
my %access = (
@@ -3722,7 +4155,7 @@ sub string_ip_selector {
@{$access{'deny'}} = ('');
}
my ($disabled,$addmore);
- if ($disabled) {
+ if ($readonly) {
$disabled=' disabled="disabled"';
} else {
$addmore = "\n".'';
@@ -3807,6 +4240,11 @@ my %stringtypes = (
acc => 'string_ip',
);
+# Returns the possible values and titles for a given string type, or undef if there are none.
+# Used by courseprefs.
+#
+# @param {string} $string_type - a parameter type for strings
+# @returns {array reference} - 2D array, containing values and English titles
sub standard_string_options {
my ($string_type) = @_;
if (ref($strings{$string_type}) eq 'ARRAY') {
@@ -3815,6 +4253,10 @@ sub standard_string_options {
return;
}
+# Returns regular expressions to match kinds of string types, or undef if there are none.
+#
+# @param {string} $string_type - a parameter type for strings
+# @returns {array reference} - 2D array, containing regular expression names and regular expressions
sub standard_string_matches {
my ($string_type) = @_;
if (ref($stringmatches{$string_type}) eq 'ARRAY') {
@@ -3823,6 +4265,10 @@ sub standard_string_matches {
return;
}
+# Returns a parameter type for a given parameter with a string type, or undef if not known.
+#
+# @param {string} $name - parameter name
+# @returns {string}
sub get_stringtype {
my ($name) = @_;
if (exists($stringtypes{$name})) {
@@ -3831,6 +4277,14 @@ sub get_stringtype {
return;
}
+# Returns HTML to edit a string parameter.
+#
+# @param {string} $thistype - parameter type
+# @param {string} $thiskey - parameter key
+# @param {string} $showval - parameter current value
+# @param {string} $name - parameter name
+# @param {boolean} $readonly - true if the values should not be made editable
+# @returns {string}
sub string_selector {
my ($thistype, $thiskey, $showval, $name, $readonly) = @_;
@@ -3996,6 +4450,10 @@ my %intervaltypes = (
interval => 'date_interval',
);
+# Returns regular expressions to match kinds of interval type, or undef if there are none.
+#
+# @param {string} $interval_type - a parameter type for intervals
+# @returns {array reference} - 2D array, containing regular expression names and regular expressions
sub standard_interval_matches {
my ($interval_type) = @_;
if (ref($intervalmatches{$interval_type}) eq 'ARRAY') {
@@ -4004,6 +4462,10 @@ sub standard_interval_matches {
return;
}
+# Returns a parameter type for a given parameter with an interval type, or undef if not known.
+#
+# @param {string} $name - parameter name
+# @returns {string}
sub get_intervaltype {
my ($name) = @_;
if (exists($intervaltypes{$name})) {
@@ -4012,6 +4474,11 @@ sub get_intervaltype {
return;
}
+# Returns the possible values and titles for a given interval type, or undef if there are none.
+# Used by courseprefs.
+#
+# @param {string} $interval_type - a parameter type for intervals
+# @returns {array reference} - 2D array, containing values and English titles
sub standard_interval_options {
my ($interval_type) = @_;
if (ref($intervals{$interval_type}) eq 'ARRAY') {
@@ -4020,6 +4487,13 @@ sub standard_interval_options {
return;
}
+# Returns HTML to edit a date interval parameter.
+#
+# @param {string} $thiskey - parameter key
+# @param {string} $name - parameter name
+# @param {string} $showval - parameter current value
+# @param {boolean} $readonly - true if the values should not be made editable
+# @returns {string}
sub date_interval_selector {
my ($thiskey, $name, $showval, $readonly) = @_;
my ($result,%skipval);
@@ -4102,17 +4576,21 @@ sub date_interval_selector {
$currprocdisplay = 'text';
}
my $onclick = ' onclick="toggleSecret(this.form,'."'done_','$thiskey'".');"';
+ my $disabled;
+ if ($readonly) {
+ $disabled = ' disabled="disabled"';
+ }
$result .= ' '.&mt('Include "done" button').
- ' '.
+ 'name="done_'.$thiskey.'_proctorkey" value="'.&HTML::Entities::encode($currproctorkey,'"<>&').'"'.$disabled.' /> '.
''.&mt('Button text').': '.
- '&').'" />';
+ '&').'"'.$disabled.' />';
}
}
unless ($readonly) {
@@ -4121,6 +4599,16 @@ sub date_interval_selector {
return $result;
}
+# Returns HTML with a warning if a parameter requires a more recent version of LON-CAPA.
+#
+# @param {string} $name - parameter name
+# @param {string} $namematch - parameter level name (recognized: resourcelevel|maplevel|maplevelrecurse|courselevel)
+# @param {string} $value - parameter value
+# @param {string} $chostname - course server name
+# @param {integer} $cmajor - major version number
+# @param {integer} $cminor - minor version number
+# @param {string} $needsrelease - release version needed (major.minor)
+# @returns {string}
sub oldversion_warning {
my ($name,$namematch,$value,$chostname,$cmajor,$cminor,$needsrelease) = @_;
my $standard_name = &standard_parameter_names($name);
@@ -4196,10 +4684,11 @@ sub oldversion_warning {
} # end of block using some constants related to parameter types
-#
-# Shift all start and end dates by $shift
-#
+# Shifts all start and end dates in the current course by $shift.
+#
+# @param {integer} $shift - time to shift, in seconds
+# @returns {string} - error name or 'ok'
sub dateshift {
my ($shift)=@_;
my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
@@ -4231,12 +4720,19 @@ sub dateshift {
return $reply;
}
+# Overview mode UI to edit course parameters.
+#
+# @param {Apache2::RequestRec} $r - the Apache request
sub newoverview {
- my ($r) = @_;
+ 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 $readonly = 1;
+ if ($parm_permission->{'edit'}) {
+ undef($readonly);
+ }
&Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview',
text=>"Overview Mode"});
@@ -4339,7 +4835,7 @@ ENDOVER
$r->print('
');
$r->print('
');
- &displaymenu($r,\%allparms,\@pscat,\%keyorder);
+ &displaymenu($r,\%allparms,\@pscat,\%keyorder); # FIXME: wrong parameters, could make keysindisplayorderCategory crash because $keyorder is undefined
$r->print(&Apache::lonhtmlcommon::start_pick_box());
$r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parts to View')));
my $sectionselector = §ionmenu(\@selected_sections);
@@ -4395,15 +4891,31 @@ ENDOVER
# List data
- &listdata($r,$resourcedata,$listdata,$sortorder,'newoverview');
+ &listdata($r,$resourcedata,$listdata,$sortorder,'newoverview',undef,$readonly);
+ }
+ $r->print(&tableend());
+ unless ($readonly) {
+ $r->print( ((($env{'form.store'}) || ($env{'form.dis'}))?'':'') );
}
- $r->print(&tableend().
- ((($env{'form.store'}) || ($env{'form.dis'}))?'':'').
- '');
+ $r->print('');
&endSettingsScreen($r);
$r->print(&Apache::loncommon::end_page());
}
+# Fills $listdata with parameter information.
+# Keys use the format course id.[section id].part.name and course id.[section id].part.name.type.
+# The non-type value is always 1.
+#
+# @param {string} $cat - parameter name
+# @param {string} $pschp - selected map pc, or 'all'
+# @param {string} $parmlev - selected level value (full|map|general), or ''
+# @param {hash reference} $listdata - the parameter data that will be modified
+# @param {array reference} $psprt - selected parts
+# @param {array reference} $selections - selected sections
+# @param {hash reference} $defkeytype - hash parameter name -> parameter type
+# @param {hash reference} $allmaps - hash map pc -> map src
+# @param {array reference} $ids - resource and map ids
+# @param {hash reference} $symbp - hash map pc or resource/map id -> map src.'___(all)' or resource symb
sub secgroup_lister {
my ($cat,$pschp,$parmlev,$listdata,$psprt,$selections,$defkeytype,$allmaps,$ids,$symbp) = @_;
foreach my $item (@{$selections}) {
@@ -4442,12 +4954,19 @@ sub secgroup_lister {
}
}
-# Display all existing parameter settings.
+# UI to edit parameter settings starting with a list of all existing parameters.
+# (called by setoverview action)
+#
+# @param {Apache2::RequestRec} $r - the Apache request
sub overview {
- my ($r) = @_;
+ 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 $readonly = 1;
+ if ($parm_permission->{'edit'}) {
+ undef($readonly);
+ }
my $js = '