Diff for /loncom/interface/lonparmset.pm between versions 1.545 and 1.561

version 1.545, 2014/06/12 22:29:42 version 1.561, 2016/07/15 18:03:52
Line 36  lonparmset - Handler to set parameters f Line 36  lonparmset - Handler to set parameters f
   
 =head1 SYNOPSIS  =head1 SYNOPSIS
   
 lonparmset provides an interface to setting course parameters.   lonparmset provides an interface to setting course parameters.
   
   It contains all the code for the "Content and Problem Settings" UI, except
   for the helpers parameter.helper and resettimes.helper, and lonhelper.pm,
   and lonblockingmenu.pm.
   
 =head1 DESCRIPTION  =head1 DESCRIPTION
   
Line 54  Inputs:  $what - a parameter spec (inclu Line 58  Inputs:  $what - a parameter spec (inclu
          $id   - a bighash Id number           $id   - a bighash Id number
          $def  - the resource's default value   'stupid emacs           $def  - the resource's default value   'stupid emacs
   
 Returns:  A list, the first item is the index into the remaining list of items of parm valuse that is the active one, the list consists of parm values at the 14 possible levels  Returns:  A list, the first item is the index into the remaining list of items of parm values that is the active one, the list consists of parm values at the 18 possible levels
   
 14- General Course  18 - General Course
 13- Map or Folder level in course  17 - Map or Folder level in course (recursive) 
 12- resource default  16 - Map or Folder level in course (non-recursive)
 11- map default  15 - resource default
 10- resource level in course  14 - map default
 9 - General for section  13 - resource level in course
 8 - Map or Folder level for section  12 - General for section
 7 - resource level in section  11 - Map or Folder level for section (recursive)
 6 - General for group  10 - Map or Folder level for section (non-recursive)
 5 - Map or Folder level for group  9 - resource level in section
 4 - resource level in group  8 - General for group
 3 - General for specific student  7 - Map or Folder level for group (recursive)
 2 - Map or Folder level for specific student  6 - Map or Folder level for group (non-recursive)
   5 - resource level in group
   4 - General for specific student
   3 - Map or Folder level for specific student (recursive)
   2 - Map or Folder level for specific student (non-recursive)
 1 - resource level for specific student  1 - resource level for specific student
   
 =item parmval_by_symb()  =item parmval_by_symb()
Line 323  use HTML::Entities; Line 331  use HTML::Entities;
 use LONCAPA qw(:DEFAULT :match);  use LONCAPA qw(:DEFAULT :match);
   
   
   ##################################################
   # CONTENT AND PROBLEM SETTINGS HTML PAGE HEADER/FOOTER
   ##################################################
   
   # 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 {  sub startSettingsScreen {
     my ($r,$mode,$crstype)=@_;      my ($r,$mode,$crstype)=@_;
   
Line 341  sub startSettingsScreen { Line 358  sub startSettingsScreen {
     $r->print('<div class="LC_Box" style="clear:both;margin:0;" id="parameditor"><div id="maincoursedoc" style="margin:0 0;padding:0 0;"><div class="LC_ContentBox" id="mainCourseDocuments" style="display: block;">');      $r->print('<div class="LC_Box" style="clear:both;margin:0;" id="parameditor"><div id="maincoursedoc" style="margin:0 0;padding:0 0;"><div class="LC_ContentBox" id="mainCourseDocuments" style="display: block;">');
 }  }
   
   # Page footer
 sub endSettingsScreen {  sub endSettingsScreen {
    my ($r)=@_;     my ($r)=@_;
    $r->print('</div></div></div>');     $r->print('</div></div></div>');
Line 348  sub endSettingsScreen { Line 366  sub endSettingsScreen {
   
   
   
   ##################################################
   # TABLE MODE
   # (parmval is also used for the log of parameter changes)
   ##################################################
   
   # Calls parmval_by_symb, getting the symb from $id (the big hash resource id) with &symbcache.
   #
   # @param {string} $what - part info and parameter name separated by a dot, e.g. '0.weight'
   # @param {string} $id - big hash resource id
   # @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 {  sub parmval {
     my ($what,$id,$def,$uname,$udom,$csec,$cgroup,$courseopt)=@_;      my ($what,$id,$def,$uname,$udom,$csec,$cgroup,$courseopt)=@_;
     return &parmval_by_symb($what,&symbcache($id),$def,$uname,$udom,$csec,      return &parmval_by_symb($what,&symbcache($id),$def,$uname,$udom,$csec,
                                                            $cgroup,$courseopt);                                                             $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
   # @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 {  sub parmval_by_symb {
     my ($what,$symb,$def,$uname,$udom,$csec,$cgroup,$courseopt)=@_;      my ($what,$symb,$def,$uname,$udom,$csec,$cgroup,$courseopt)=@_;
   
     my $useropt;      my $useropt;
     if ($uname ne '' && $udom ne '') {      if ($uname ne '' && $udom ne '') {
     $useropt = &Apache::lonnet::get_userresdata($uname,$udom);          $useropt = &Apache::lonnet::get_userresdata($uname,$udom);
     }      }
   
     my $result='';      my $result='';
Line 367  sub parmval_by_symb { Line 415  sub parmval_by_symb {
 # ----------------------------------------------------- Cascading lookup scheme  # ----------------------------------------------------- Cascading lookup scheme
     my $map=(&Apache::lonnet::decode_symb($symb))[0];      my $map=(&Apache::lonnet::decode_symb($symb))[0];
     $map = &Apache::lonnet::deversion($map);      $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 $symbparm=$symb.'.'.$what;
       my $recurseparm=$map.'___(rec).'.$what; 
     my $mapparm=$map.'___(all).'.$what;      my $mapparm=$map.'___(all).'.$what;
   
     my $grplevel=$env{'request.course.id'}.'.['.$cgroup.'].'.$what;      my $grplevel=$env{'request.course.id'}.'.['.$cgroup.'].'.$what;
     my $grplevelr=$env{'request.course.id'}.'.['.$cgroup.'].'.$symbparm;      my $grplevelr=$env{'request.course.id'}.'.['.$cgroup.'].'.$symbparm;
       my $grpleveli=$env{'request.course.id'}.'.['.$cgroup.'].'.$recurseparm;
     my $grplevelm=$env{'request.course.id'}.'.['.$cgroup.'].'.$mapparm;      my $grplevelm=$env{'request.course.id'}.'.['.$cgroup.'].'.$mapparm;
   
     my $seclevel=$env{'request.course.id'}.'.['.$csec.'].'.$what;      my $seclevel=$env{'request.course.id'}.'.['.$csec.'].'.$what;
     my $seclevelr=$env{'request.course.id'}.'.['.$csec.'].'.$symbparm;      my $seclevelr=$env{'request.course.id'}.'.['.$csec.'].'.$symbparm;
       my $secleveli=$env{'request.course.id'}.'.['.$csec.'].'.$recurseparm;
     my $seclevelm=$env{'request.course.id'}.'.['.$csec.'].'.$mapparm;      my $seclevelm=$env{'request.course.id'}.'.['.$csec.'].'.$mapparm;
   
     my $courselevel=$env{'request.course.id'}.'.'.$what;      my $courselevel=$env{'request.course.id'}.'.'.$what;
     my $courselevelr=$env{'request.course.id'}.'.'.$symbparm;      my $courselevelr=$env{'request.course.id'}.'.'.$symbparm;
       my $courseleveli=$env{'request.course.id'}.'.'.$recurseparm;
     my $courselevelm=$env{'request.course.id'}.'.'.$mapparm;      my $courselevelm=$env{'request.course.id'}.'.'.$mapparm;
   
   
 # --------------------------------------------------------- first, check course  # --------------------------------------------------------- first, check course
   
   # 18 - General Course
     if (defined($$courseopt{$courselevel})) {      if (defined($$courseopt{$courselevel})) {
     $outpar[14]=$$courseopt{$courselevel};          $outpar[18]=$$courseopt{$courselevel};
     $result=14;          $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})) {      if (defined($$courseopt{$courselevelm})) {
     $outpar[13]=$$courseopt{$courselevelm};          $outpar[16]=$$courseopt{$courselevelm};
     $result=13;          $result=16;
     }      }
   
 # ------------------------------------------------------- second, check default  # ------------------------------------------------------- second, check default
   
     if (defined($def)) { $outpar[12]=$def; $result=12; }  # 15 - resource default
       if (defined($def)) { $outpar[15]=$def; $result=15; }
   
 # ------------------------------------------------------ third, check map parms  # ------------------------------------------------------ third, check map parms
   
       
   # 14 - map default
     my $thisparm=&parmhash($symbparm);      my $thisparm=&parmhash($symbparm);
     if (defined($thisparm)) { $outpar[11]=$thisparm; $result=11; }      if (defined($thisparm)) { $outpar[14]=$thisparm; $result=14; }
   
   # 13 - resource level in course
     if (defined($$courseopt{$courselevelr})) {      if (defined($$courseopt{$courselevelr})) {
     $outpar[10]=$$courseopt{$courselevelr};          $outpar[13]=$$courseopt{$courselevelr};
     $result=10;          $result=13;
     }      }
   
 # ------------------------------------------------------ fourth, back to course  # ------------------------------------------------------ fourth, back to course
     if ($csec ne '') {      if ($csec ne '') {
   # 12 - General for section
         if (defined($$courseopt{$seclevel})) {          if (defined($$courseopt{$seclevel})) {
         $outpar[9]=$$courseopt{$seclevel};              $outpar[12]=$$courseopt{$seclevel};
         $result=9;              $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})) {          if (defined($$courseopt{$seclevelm})) {
         $outpar[8]=$$courseopt{$seclevelm};              $outpar[10]=$$courseopt{$seclevelm};
         $result=8;              $result=10;
     }          }
   # 9 - resource level in section
         if (defined($$courseopt{$seclevelr})) {          if (defined($$courseopt{$seclevelr})) {
         $outpar[7]=$$courseopt{$seclevelr};              $outpar[9]=$$courseopt{$seclevelr};
         $result=7;              $result=9;
     }          }
     }      }
 # ------------------------------------------------------ fifth, check course group  # ------------------------------------------------------ fifth, check course group
     if ($cgroup ne '') {      if ($cgroup ne '') {
   # 8 - General for group
         if (defined($$courseopt{$grplevel})) {          if (defined($$courseopt{$grplevel})) {
             $outpar[6]=$$courseopt{$grplevel};              $outpar[8]=$$courseopt{$grplevel};
             $result=6;              $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})) {          if (defined($$courseopt{$grplevelm})) {
             $outpar[5]=$$courseopt{$grplevelm};              $outpar[6]=$$courseopt{$grplevelm};
             $result=5;              $result=6;
         }          }
   # 5 - resource level in group
         if (defined($$courseopt{$grplevelr})) {          if (defined($$courseopt{$grplevelr})) {
             $outpar[4]=$$courseopt{$grplevelr};              $outpar[5]=$$courseopt{$grplevelr};
             $result=4;              $result=5;
         }          }
     }      }
   
 # ---------------------------------------------------------- fifth, check user  # ---------------------------------------------------------- sixth, check user
   
     if ($uname ne '') {      if ($uname ne '') {
     if (defined($$useropt{$courselevel})) {  # 4 - General for specific student
         $outpar[3]=$$useropt{$courselevel};          if (defined($$useropt{$courselevel})) {
         $result=3;              $outpar[4]=$$useropt{$courselevel};
     }              $result=4;
           }
     if (defined($$useropt{$courselevelm})) {  
         $outpar[2]=$$useropt{$courselevelm};  
         $result=2;  
     }  
   
     if (defined($$useropt{$courselevelr})) {  # 3 - Map or Folder level for specific student (recursive)
         $outpar[1]=$$useropt{$courselevelr};          if (defined($$useropt{$courseleveli})) {
         $result=1;              $outpar[3]=$$useropt{$courseleveli};
     }              $result=3;
           }
   
   # 2 - Map or Folder level for specific student (non-recursive)
           if (defined($$useropt{$courselevelm})) {
               $outpar[2]=$$useropt{$courselevelm};
               $result=2;
           }
   
   # 1 - resource level for specific student
           if (defined($$useropt{$courselevelr})) {
               $outpar[1]=$$useropt{$courselevelr};
               $result=1;
           }
     }      }
     return ($result,@outpar);      return ($result,@outpar);
 }  }
Line 468  sub parmval_by_symb { Line 559  sub parmval_by_symb {
 # --- Caches local to lonparmset  # --- Caches local to lonparmset
   
   
   # Reset lonparmset caches (called at the beginning and end of the handler).
 sub reset_caches {  sub reset_caches {
     &resetparmhash();      &resetparmhash();
     &resetsymbcache();      &resetsymbcache();
     &resetrulescache();      &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 $parmhashid; # course identifier, to initialize the cache only once for a course
     my %parmhash;      my %parmhash; # the parameter cache
       # reset map parameter hash
     sub resetparmhash {      sub resetparmhash {
     undef($parmhashid);          undef($parmhashid);
     undef(%parmhash);          undef(%parmhash);
     }      }
   
       # dump the _parms.db database into %parmhash
     sub cacheparmhash {      sub cacheparmhash {
     if ($parmhashid eq  $env{'request.course.fn'}) { return; }          if ($parmhashid eq  $env{'request.course.fn'}) { return; }
     my %parmhashfile;          my %parmhashfile;
     if (tie(%parmhashfile,'GDBM_File',          if (tie(%parmhashfile,'GDBM_File',
         $env{'request.course.fn'}.'_parms.db',&GDBM_READER(),0640)) {              $env{'request.course.fn'}.'_parms.db',&GDBM_READER(),0640)) {
         %parmhash=%parmhashfile;              %parmhash=%parmhashfile;
         untie(%parmhashfile);              untie(%parmhashfile);
         $parmhashid=$env{'request.course.fn'};              $parmhashid=$env{'request.course.fn'};
     }          }
     }      }
   
       # returns a parameter value for an identifier symb.parts.parameter, using the map parameter cache
     sub parmhash {      sub parmhash {
     my ($id) = @_;          my ($id) = @_;
     &cacheparmhash();          &cacheparmhash();
     return $parmhash{$id};          return $parmhash{$id};
     }      }
  }  }
   
   # cache big hash id -> symb, using lonnavmaps to find association
 {  {
     my $symbsid;      my $symbsid; # course identifier, to initialize the cache only once for a course
     my %symbs;      my %symbs; # hash id->symb
       # reset the id->symb cache
     sub resetsymbcache {      sub resetsymbcache {
     undef($symbsid);          undef($symbsid);
     undef(%symbs);          undef(%symbs);
     }      }
   
       # returns the symb corresponding to a big hash id (using lonnavmaps and a cache)
     sub symbcache {      sub symbcache {
     my $id=shift;          my $id=shift;
     if ($symbsid ne $env{'request.course.id'}) {          if ($symbsid ne $env{'request.course.id'}) {
         undef(%symbs);              undef(%symbs);
     }          }
     if (!$symbs{$id}) {          if (!$symbs{$id}) {
         my $navmap = Apache::lonnavmaps::navmap->new();              my $navmap = Apache::lonnavmaps::navmap->new();
         if ($id=~/\./) {              if ($id=~/\./) {
         my $resource=$navmap->getById($id);                  my $resource=$navmap->getById($id);
         $symbs{$id}=$resource->symb();                  $symbs{$id}=$resource->symb();
         } else {              } else {
         my $resource=$navmap->getByMapPc($id);                  my $resource=$navmap->getByMapPc($id);
         $symbs{$id}=&Apache::lonnet::declutter($resource->src());                  $symbs{$id}=&Apache::lonnet::declutter($resource->src());
               }
               $symbsid=$env{'request.course.id'};
         }          }
         $symbsid=$env{'request.course.id'};          return $symbs{$id};
     }  
     return $symbs{$id};  
     }      }
  }  }
   
   # cache for parameter default actions (stored in parmdefactions.db)
 {  {
     my $rulesid;      my $rulesid; # course identifier, to initialize the cache only once for a course
     my %rules;      my %rules; # parameter default actions hash
     sub resetrulescache {      sub resetrulescache {
     undef($rulesid);          undef($rulesid);
     undef(%rules);          undef(%rules);
     }      }
   
       # returns the value for a given key in the parameter default action hash
     sub rulescache {      sub rulescache {
     my $id=shift;          my $id=shift;
     if ($rulesid ne $env{'request.course.id'}          if ($rulesid ne $env{'request.course.id'}
         && !defined($rules{$id})) {              && !defined($rules{$id})) {
         my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};              my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
         my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};              my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
         %rules=&Apache::lonnet::dump('parmdefactions',$dom,$crs);              %rules=&Apache::lonnet::dump('parmdefactions',$dom,$crs);
         $rulesid=$env{'request.course.id'};              $rulesid=$env{'request.course.id'};
     }          }
     return $rules{$id};          return $rules{$id};
     }      }
 }  }
   
   
   # 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<string>} - (hours, min, sec, value)
 sub preset_defaults {  sub preset_defaults {
     my $type=shift;      my $type=shift;
     if (&rulescache($type.'_action') eq 'default') {      if (&rulescache($type.'_action') eq 'default') {
 # yes, there is something          # yes, there is something
     return (&rulescache($type.'_hours'),          return (&rulescache($type.'_hours'),
         &rulescache($type.'_min'),              &rulescache($type.'_min'),
         &rulescache($type.'_sec'),              &rulescache($type.'_sec'),
         &rulescache($type.'_value'));              &rulescache($type.'_value'));
     } else {      } else {
 # nothing there or something else          # nothing there or something else
     return ('','','','','');          return ('','','','','');
     }      }
 }  }
   
   
   # 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 {  sub date_sanity_info {
    my $checkdate=shift;     my $checkdate=shift;
    unless ($checkdate) { return ''; }     unless ($checkdate) { return ''; }
Line 602  sub date_sanity_info { Line 714  sub date_sanity_info {
 #      }  #      }
    return $result;     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 big hash id
   # @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
 sub storeparm {  sub storeparm {
     my ($sresid,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$cgroup)=@_;      my ($sresid,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$cgroup)=@_;
     &storeparm_by_symb(&symbcache($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
   # @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 {boolean} $recflag - should be true for recursive calls to storeparm_by_symb, false otherwise
   # @param {string} $cgroup - group name
 sub storeparm_by_symb {  sub storeparm_by_symb {
     my ($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$recflag,$cgroup)=@_;      my ($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$recflag,$cgroup)=@_;
     unless ($recflag) {      unless ($recflag) {
 # first time call          # first time call
     %recstack=();          %recstack=();
     $recflag=1;          $recflag=1;
     }      }
 # store parameter      # store parameter
     &storeparm_by_symb_inner      &storeparm_by_symb_inner
     ($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$cgroup);      ($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$cgroup);
 # don't do anything if parameter was reset      # don't do anything if parameter was reset
     unless ($nval) { return; }      unless ($nval) { return; }
     my ($prefix,$parm)=($spnam=~/^(.*[\_\.])([^\_\.]+)$/);      my ($prefix,$parm)=($spnam=~/^(.*[\_\.])([^\_\.]+)$/);
 # remember that this was set      # remember that this was set
     $recstack{$parm}=1;      $recstack{$parm}=1;
 # what does this trigger?      # what does this trigger?
     foreach my $triggered (split(/\:/,&rulescache($parm.'_triggers'))) {      foreach my $triggered (split(/\:/,&rulescache($parm.'_triggers'))) {
 # don't backfire          # don't backfire
        unless ((!$triggered) || ($recstack{$triggered})) {          unless ((!$triggered) || ($recstack{$triggered})) {
        my $action=&rulescache($triggered.'_action');              my $action=&rulescache($triggered.'_action');
        my ($whichaction,$whichparm)=($action=~/^(.*\_)([^\_]+)$/);              my ($whichaction,$whichparm)=($action=~/^(.*\_)([^\_]+)$/);
 # set triggered parameter on same level              # set triggered parameter on same level
        my $newspnam=$prefix.$triggered;              my $newspnam=$prefix.$triggered;
        my $newvalue='';              my $newvalue='';
        my $active=1;              my $active=1;
        if ($action=~/^when\_setting/) {              if ($action=~/^when\_setting/) {
 # are there restrictions?              # are there restrictions?
            if (&rulescache($triggered.'_triggervalue')=~/\w/) {                  if (&rulescache($triggered.'_triggervalue')=~/\w/) {
            $active=0;                      $active=0;
            foreach my $possiblevalue (split(/\s*\,\s*/,&rulescache($triggered.'_triggervalue'))) {                      foreach my $possiblevalue (split(/\s*\,
                if (lc($possiblevalue) eq lc($nval)) { $active=1; }                              \s*/,&rulescache($triggered.'_triggervalue'))) {
            }                          if (lc($possiblevalue) eq lc($nval)) { $active=1; }
            }                      }
            $newvalue=&rulescache($triggered.'_value');                  }
        } else {                  $newvalue=&rulescache($triggered.'_value');
            my $totalsecs=((&rulescache($triggered.'_days')*24+&rulescache($triggered.'_hours'))*60+&rulescache($triggered.'_min'))*60+&rulescache($triggered.'_sec');              } else {
            if ($action=~/^later\_than/) {                  my $totalsecs=((&rulescache($triggered.'_days')*24+&rulescache($triggered.'_hours'))*60+&rulescache($triggered.'_min'))*60+&rulescache($triggered.'_sec');
            $newvalue=$nval+$totalsecs;                  if ($action=~/^later\_than/) {
            } else {                      $newvalue=$nval+$totalsecs;
            $newvalue=$nval-$totalsecs;                  } else {
            }                      $newvalue=$nval-$totalsecs;
        }                  }
        if ($active) {              }
            &storeparm_by_symb($symb,$newspnam,$snum,$newvalue,&rulescache($triggered.'_type'),              if ($active) {
                    $uname,$udom,$csec,$recflag,$cgroup);                  &storeparm_by_symb($symb,$newspnam,$snum,$newvalue,&rulescache($triggered.'_type'),
        }                          $uname,$udom,$csec,$recflag,$cgroup);
        }              }
           }
     }      }
     return '';      return '';
 }  }
   
   # Adds all given arguments to the course parameter log.
   # @returns {string} - the answer to the lonnet query.
 sub log_parmset {  sub log_parmset {
     return &Apache::lonnet::write_log('course','parameterlog',@_);      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
   # @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 {  sub storeparm_by_symb_inner {
 # ---------------------------------------------------------- Get symb, map, etc  # ---------------------------------------------------------- Get symb, map, etc
     my ($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$cgroup)=@_;      my ($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$cgroup)=@_;
Line 686  sub storeparm_by_symb_inner { Line 827  sub storeparm_by_symb_inner {
     $map = &Apache::lonnet::deversion($map);      $map = &Apache::lonnet::deversion($map);
   
     my $symbparm=$symb.'.'.$spnam;      my $symbparm=$symb.'.'.$spnam;
       my $recurseparm=$map.'___(rec).'.$spnam;
     my $mapparm=$map.'___(all).'.$spnam;      my $mapparm=$map.'___(all).'.$spnam;
   
     my $grplevel=$env{'request.course.id'}.'.['.$cgroup.'].'.$spnam;      my $grplevel=$env{'request.course.id'}.'.['.$cgroup.'].'.$spnam;
     my $grplevelr=$env{'request.course.id'}.'.['.$cgroup.'].'.$symbparm;      my $grplevelr=$env{'request.course.id'}.'.['.$cgroup.'].'.$symbparm;
       my $grpleveli=$env{'request.course.id'}.'.['.$cgroup.'].'.$recurseparm;
     my $grplevelm=$env{'request.course.id'}.'.['.$cgroup.'].'.$mapparm;      my $grplevelm=$env{'request.course.id'}.'.['.$cgroup.'].'.$mapparm;
   
     my $seclevel=$env{'request.course.id'}.'.['.$csec.'].'.$spnam;      my $seclevel=$env{'request.course.id'}.'.['.$csec.'].'.$spnam;
     my $seclevelr=$env{'request.course.id'}.'.['.$csec.'].'.$symbparm;      my $seclevelr=$env{'request.course.id'}.'.['.$csec.'].'.$symbparm;
       my $secleveli=$env{'request.course.id'}.'.['.$csec.'].'.$recurseparm;
     my $seclevelm=$env{'request.course.id'}.'.['.$csec.'].'.$mapparm;      my $seclevelm=$env{'request.course.id'}.'.['.$csec.'].'.$mapparm;
   
     my $courselevel=$env{'request.course.id'}.'.'.$spnam;      my $courselevel=$env{'request.course.id'}.'.'.$spnam;
     my $courselevelr=$env{'request.course.id'}.'.'.$symbparm;      my $courselevelr=$env{'request.course.id'}.'.'.$symbparm;
       my $courseleveli=$env{'request.course.id'}.'.'.$recurseparm;
     my $courselevelm=$env{'request.course.id'}.'.'.$mapparm;      my $courselevelm=$env{'request.course.id'}.'.'.$mapparm;
   
     my $storeunder='';      my $storeunder='';
     if (($snum==14) || ($snum==3)) { $storeunder=$courselevel; }      if (($snum==18) || ($snum==4)) { $storeunder=$courselevel; }
     if (($snum==13) || ($snum==2)) { $storeunder=$courselevelm; }      if (($snum==17) || ($snum==3)) { $storeunder=$courseleveli; } 
     if (($snum==10) || ($snum==1)) { $storeunder=$courselevelr; }      if (($snum==16) || ($snum==2)) { $storeunder=$courselevelm; }
     if ($snum==9) { $storeunder=$seclevel; }      if (($snum==13) || ($snum==1)) { $storeunder=$courselevelr; }
     if ($snum==8) { $storeunder=$seclevelm; }      if ($snum==12) { $storeunder=$seclevel; }
     if ($snum==7) { $storeunder=$seclevelr; }      if ($snum==11) { $storeunder=$secleveli; }
     if ($snum==6) { $storeunder=$grplevel; }      if ($snum==10) { $storeunder=$seclevelm; }
     if ($snum==5) { $storeunder=$grplevelm; }      if ($snum==9) { $storeunder=$seclevelr; }
     if ($snum==4) { $storeunder=$grplevelr; }      if ($snum==8) { $storeunder=$grplevel; }
       if ($snum==7) { $storeunder=$grpleveli; }
       if ($snum==6) { $storeunder=$grplevelm; }
       if ($snum==5) { $storeunder=$grplevelr; }
   
   
     my $delete;      my $delete;
Line 717  sub storeparm_by_symb_inner { Line 865  sub storeparm_by_symb_inner {
     my %storecontent = ($storeunder         => $nval,      my %storecontent = ($storeunder         => $nval,
             $storeunder.'.type' => $ntype);              $storeunder.'.type' => $ntype);
     my $reply='';      my $reply='';
     if ($snum>3) {      
       if ($snum>4) {
 # ---------------------------------------------------------------- Store Course  # ---------------------------------------------------------------- Store Course
 #  #
     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};          my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};          my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
 # Expire sheets          # Expire sheets
     &Apache::lonnet::expirespread('','','studentcalc');          &Apache::lonnet::expirespread('','','studentcalc');
     if (($snum==10) || ($snum==7) || ($snum==4)) {          if (($snum==13) || ($snum==9) || ($snum==5)) {
         &Apache::lonnet::expirespread('','','assesscalc',$symb);              &Apache::lonnet::expirespread('','','assesscalc',$symb);
     } elsif (($snum==11) || ($snum==8) || ($snum==5)) {          } elsif (($snum==14) || ($snum==10) || ($snum==6)) {
         &Apache::lonnet::expirespread('','','assesscalc',$map);              &Apache::lonnet::expirespread('','','assesscalc',$map);
     } else {          } else {
         &Apache::lonnet::expirespread('','','assesscalc');              &Apache::lonnet::expirespread('','','assesscalc');
     }          }
 # Store parameter          # Store parameter
     if ($delete) {          if ($delete) {
         $reply=&Apache::lonnet::del              $reply=&Apache::lonnet::del
         ('resourcedata',[keys(%storecontent)],$cdom,$cnum);              ('resourcedata',[keys(%storecontent)],$cdom,$cnum);
             &log_parmset(\%storecontent,1);                  &log_parmset(\%storecontent,1);
     } else {          } else {
         $reply=&Apache::lonnet::cput              $reply=&Apache::lonnet::cput
         ('resourcedata',\%storecontent,$cdom,$cnum);              ('resourcedata',\%storecontent,$cdom,$cnum);
         &log_parmset(\%storecontent);              &log_parmset(\%storecontent);
     }          }
     &Apache::lonnet::devalidatecourseresdata($cnum,$cdom);          &Apache::lonnet::devalidatecourseresdata($cnum,$cdom);
     } else {      } else {
 # ------------------------------------------------------------------ Store User  # ------------------------------------------------------------------ Store User
 #  #
 # Expire sheets          # Expire sheets
     &Apache::lonnet::expirespread($uname,$udom,'studentcalc');          &Apache::lonnet::expirespread($uname,$udom,'studentcalc');
     if ($snum==1) {          if ($snum==1) {
         &Apache::lonnet::expirespread              &Apache::lonnet::expirespread
         ($uname,$udom,'assesscalc',$symb);              ($uname,$udom,'assesscalc',$symb);
     } elsif ($snum==2) {          } elsif ($snum==2) {
         &Apache::lonnet::expirespread              &Apache::lonnet::expirespread
         ($uname,$udom,'assesscalc',$map);              ($uname,$udom,'assesscalc',$map);
     } else {          } else {
         &Apache::lonnet::expirespread($uname,$udom,'assesscalc');              &Apache::lonnet::expirespread($uname,$udom,'assesscalc');
     }          }
 # Store parameter          # Store parameter
     if ($delete) {          if ($delete) {
         $reply=&Apache::lonnet::del              $reply=&Apache::lonnet::del
         ('resourcedata',[keys(%storecontent)],$udom,$uname);              ('resourcedata',[keys(%storecontent)],$udom,$uname);
         &log_parmset(\%storecontent,1,$uname,$udom);              &log_parmset(\%storecontent,1,$uname,$udom);
     } else {          } else {
         $reply=&Apache::lonnet::cput              $reply=&Apache::lonnet::cput
         ('resourcedata',\%storecontent,$udom,$uname);              ('resourcedata',\%storecontent,$udom,$uname);
         &log_parmset(\%storecontent,0,$uname,$udom);              &log_parmset(\%storecontent,0,$uname,$udom);
     }          }
     &Apache::lonnet::devalidateuserresdata($uname,$udom);          &Apache::lonnet::devalidateuserresdata($uname,$udom);
     }      }
   
     if ($reply=~/^error\:(.*)/) {      if ($reply=~/^error\:(.*)/) {
     return "<span class=\"LC_error\">Write Error: $1</span>";          return "<span class=\"LC_error\">Write Error: $1</span>";
     }      }
     return '';      return '';
 }  }
   
   
   # 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 {  sub valout {
     my ($value,$type,$editable)=@_;      my ($value,$type,$name,$editable)=@_;
     my $result = '';      my $result = '';
     # Values of zero are valid.      # Values of zero are valid.
     if (! $value && $value ne '0') {      if (! $value && $value ne '0') {
Line 791  sub valout { Line 950  sub valout {
         }          }
     } else {      } else {
         if ($type eq 'date_interval') {          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;              my @timer;
             $year=$year-70;              $year=$year-70;
             $mday--;              $mday--;
Line 824  sub valout { Line 993  sub valout {
                 push(@timer,&mt('[quant,_1,sec]',0));                  push(@timer,&mt('[quant,_1,sec]',0));
             }              }
             $result.=join(", ",@timer);              $result.=join(", ",@timer);
               if ($usesdone eq 'done') {
                   if ($secretkey) {
                       $result .= ' '.&mt('+ "[_1]" with proctor key: [_2]',$donebuttontext,$secretkey);  
                   } else {
                       $result .= ' + "'.$donebuttontext.'"';
                   }
               }
         } elsif (&isdateparm($type)) {          } elsif (&isdateparm($type)) {
             $result = &Apache::lonlocal::locallocaltime($value).              $result = &Apache::lonlocal::locallocaltime($value).
         &date_sanity_info($value);                  &date_sanity_info($value);
         } else {          } else {
             $result = $value;              $result = $value;
             $result=~s/\,/\, /gs;              $result=~s/\,/\, /gs;
         $result = &HTML::Entities::encode($result,'"<>&');              $result = &HTML::Entities::encode($result,'"<>&');
         }          }
     }      }
     return $result;      return $result;
 }  }
   
   
   # 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 {  sub plink {
     my ($type,$dis,$value,$marker,$return,$call)=@_;      my ($type,$dis,$value,$marker,$return,$call)=@_;
     my $winvalue=$value;      my $winvalue=$value;
     unless ($winvalue) {      unless ($winvalue) {
     if (&isdateparm($type)) {          if (&isdateparm($type)) {
             $winvalue=$env{'form.recent_'.$type};              $winvalue=$env{'form.recent_'.$type};
         } else {          } else {
             $winvalue=$env{'form.recent_'.(split(/\_/,$type))[0]};              $winvalue=$env{'form.recent_'.(split(/\_/,$type))[0]};
Line 850  sub plink { Line 1035  sub plink {
     my ($parmname)=((split(/\&/,$marker))[1]=~/\_([^\_]+)$/);      my ($parmname)=((split(/\&/,$marker))[1]=~/\_([^\_]+)$/);
     my ($hour,$min,$sec,$val)=&preset_defaults($parmname);      my ($hour,$min,$sec,$val)=&preset_defaults($parmname);
     unless (defined($winvalue)) { $winvalue=$val; }      unless (defined($winvalue)) { $winvalue=$val; }
     my $valout = &valout($value,$type,1);      my $valout = &valout($value,$type,$parmname,1);
     my $unencmarker = $marker;      my $unencmarker = $marker;
     foreach my $item (\$type, \$dis, \$winvalue, \$marker, \$return, \$call,      foreach my $item (\$type, \$dis, \$winvalue, \$marker, \$return, \$call,
               \$hour, \$min, \$sec) {                \$hour, \$min, \$sec) {
     $$item = &HTML::Entities::encode($$item,'"<>&');          $$item = &HTML::Entities::encode($$item,'"<>&');
     $$item =~ s/\'/\\\'/g;          $$item =~ s/\'/\\\'/g;
     }      }
     return '<table width="100%"><tr valign="top" align="right"><td><a name="'.$unencmarker.'" /></td></tr><tr><td align="center">'.      return '<table width="100%"><tr valign="top" align="right"><td><a name="'.$unencmarker.'" /></td></tr><tr><td align="center">'.
     '<a href="javascript:pjump('."'".$type."','".$dis."','".$winvalue."','"      '<a href="javascript:pjump('."'".$type."','".$dis."','".$winvalue."','"
Line 863  sub plink { Line 1048  sub plink {
         $valout.'</a></td></tr></table>';          $valout.'</a></td></tr></table>';
 }  }
   
   # Javascript for table mode.
 sub page_js {  sub page_js {
   
     my $selscript=&Apache::loncommon::studentbrowser_javascript();      my $selscript=&Apache::loncommon::studentbrowser_javascript();
Line 912  ENDJS Line 1098  ENDJS
   
 }  }
   
   # Javascript to show or hide the map selection (function showHide_courseContent),
   # for table and overview modes.
 sub showhide_js {  sub showhide_js {
     return <<"COURSECONTENTSCRIPT";      return <<"COURSECONTENTSCRIPT";
   
Line 932  function showHide_courseContent() { Line 1120  function showHide_courseContent() {
 COURSECONTENTSCRIPT  COURSECONTENTSCRIPT
 }  }
   
   # Javascript functions showHideLenient and toggleParmTextbox, for overview mode
   sub toggleparmtextbox_js {
       return <<"ENDSCRIPT";
   
   if (!document.getElementsByClassName) {
       function getElementsByClassName(node, classname) {
           var a = [];
           var re = new RegExp('(^| )'+classname+'( |$)');
           var els = node.getElementsByTagName("*");
           for(var i=0,j=els.length; i<j; i++)
               if(re.test(els[i].className))a.push(els[i]);
           return a;
       }
   }
   
   function showHideLenient() {
       var lenients;
       var setRegExp = /^set_/;
       if (document.getElementsByClassName) {
           lenients = document.getElementsByClassName('LC_lenient_radio');
       } else {
           lenients = getElementsByClassName(document.body,'LC_lenient_radio');
       }
       if (lenients != 'undefined') {
           for (var i=0; i<lenients.length; i++) {
               if (lenients[i].checked) {
                   if (lenients[i].value == 'weighted') {
                       if (setRegExp.test(lenients[i].name)) {
                           var identifier = lenients[i].name.replace(setRegExp,'');
                           toggleParmTextbox(document.parmform,identifier);
                       }
                   }
               }
           }
       }
       return;
   }
   
   function toggleParmTextbox(form,key) {
       var divfortext = document.getElementById('LC_parmtext_'+key);
       if (divfortext) {
           var caller = form.elements['set_'+key];
           if (caller.length) {
               for (i=0; i<caller.length; i++) {
                   if (caller[i].checked) {
                       if (caller[i].value == 'weighted') {
                           divfortext.style.display = 'inline';
                       } else {
                           divfortext.style.display = 'none';
                       }
                   }
               }
           }
       }
       return;
   }
   
   ENDSCRIPT
   }
   
   # Javascript function validateParms, for overview mode
   sub validateparms_js {
       return <<'ENDSCRIPT';
   
   function validateParms() {
       var textRegExp = /^settext_/;
       var tailLenient = /\.lenient$/;
       var patternRelWeight = /^\-?[\d.]+$/;
       var patternLenientStd = /^(yes|no|default)$/;
       var ipallowRegExp = /^setipallow_/;
       var ipdenyRegExp = /^setipdeny_/; 
       var patternIP = /[\[\]\*\.a-zA-Z\d\-]+/;
       if ((document.parmform.elements.length != 'undefined')  && (document.parmform.elements.length) != 'null') {
           if (document.parmform.elements.length) {
               for (i=0; i<document.parmform.elements.length; i++) {
                   var name=document.parmform.elements[i].name;
                   if (textRegExp.test(name)) { 
                       var identifier = name.replace(textRegExp,'');
                       if (tailLenient.test(identifier)) {
                           if (document.parmform.elements['set_'+identifier].length) {
                               for (var j=0; j<document.parmform.elements['set_'+identifier].length; j++) {
                                   if (document.parmform.elements['set_'+identifier][j].checked) {
                                       if (!(patternLenientStd.test(document.parmform.elements['set_'+identifier][j].value))) {
                                           var relweight = document.parmform.elements[i].value;
                                           relweight = relweight.replace(/^\s+|\s+$/g,'');
                                           if (!patternRelWeight.test(relweight)) {
                                               relweight = '0.0';
                                           }
                                           if (document.parmform.elements['set_'+identifier][j].value == 'weighted') {
                                               document.parmform.elements['set_'+identifier][j].value = relweight;
                                           } else {
                                               document.parmform.elements['set_'+identifier][j].value += ','+relweight;
                                           }
                                       }
                                       break;
                                   }
                               }
                           }
                       }
                   } else {
                       if (ipallowRegExp.test(name)) {
                           var identifier = name.replace(ipallowRegExp,'');
                           var possallow = document.parmform.elements[i].value;
                           possallow = possallow.replace(/^\s+|\s+$/g,'');
                           if (patternIP.test(possallow)) {
                               if (document.parmform.elements['set_'+identifier].value) {
                                   possallow = ','+possallow;
                               }
                               document.parmform.elements['set_'+identifier].value += possallow; 
                           }
                       } else {
                           if (ipdenyRegExp.test(name)) {
                               var identifier = name.replace(ipdenyRegExp,'');
                               var possdeny = document.parmform.elements[i].value;
                               possdeny = possdeny.replace(/^\s+|\s+$/g,'');
                               if (patternIP.test(possdeny)) {
                                   possdeny = '!'+possdeny;
                                   if (document.parmform.elements['set_'+identifier].value) {
                                       possdeny = ','+possdeny;
                                   }
                                   document.parmform.elements['set_'+identifier].value += possdeny;
                               }
                           }
                       }
                   }
               }
           }
       }
       return true;
   }
   
   ENDSCRIPT
   }
   
   # Javascript initialization, for overview mode
   sub ipacc_boxes_js  {
       my $remove = &mt('Remove');
       return <<"END";
   \$(document).ready(function() {
       var wrapper         = \$(".LC_string_ipacc_wrap");
       var add_button      = \$(".LC_add_ipacc_button");
       var ipaccRegExp     = /^LC_string_ipacc_/;
   
       \$(add_button).click(function(e){
           e.preventDefault();
           var identifier = \$(this).closest("div").attr("id");
           identifier = identifier.replace(ipaccRegExp,'');
           \$(this).closest('div').find('.LC_string_ipacc_inner').append('<div><input type="text" name="setip'+identifier+'" /><a href="#" class="LC_remove_ipacc">$remove</a></div>');
       });
   
       \$(wrapper).delegate(".LC_remove_ipacc","click", function(e){
           e.preventDefault(); \$(this).closest("div").remove();
       })
   });
   
   
   END
   }
   
   # Javascript function toggleSecret, for overview mode.
   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
   
   }
   
   # 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 {  sub startpage {
     my ($r,$psymb,$crstype) = @_;      my ($r,$psymb,$crstype) = @_;
   
Line 942  sub startpage { Line 1319  sub startpage {
         $loaditems{'onload'} = "showHide_courseContent(); group_or_section('cgroup'); resize_scrollbox('mapmenuscroll','1','1');";          $loaditems{'onload'} = "showHide_courseContent(); group_or_section('cgroup'); resize_scrollbox('mapmenuscroll','1','1');";
     }      }
   
     if ((($env{'form.command'} eq 'set') && ($env{'form.url'})      if ((($env{'form.command'} eq 'set') && ($env{'form.url'}) &&
          && (!$env{'form.dis'})) || ($env{'form.symb'})) {              (!$env{'form.dis'})) || ($env{'form.symb'})) {
     &Apache::lonhtmlcommon::add_breadcrumb({help=>'Problem_Parameters',          &Apache::lonhtmlcommon::add_breadcrumb({help=>'Problem_Parameters',
         text=>"Problem Parameters"});              text=>"Problem Parameters"});
     } else {      } else {
     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=settable',          &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=settable',
        text=>"Table Mode",              text=>"Table Mode",
        help => 'Course_Setting_Parameters'});              help => 'Course_Setting_Parameters'});
     }      }
     my $js = &page_js().'      my $js = &page_js().'
 <script type="text/javascript">  <script type="text/javascript">
Line 980  ENDHEAD Line 1357  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 - resource id -> 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
 sub print_row {  sub print_row {
     my ($r,$which,$part,$name,$symbp,$rid,$default,$defaulttype,$display,$defbgone,      my ($r,$which,$part,$name,$symbp,$rid,$default,$defaulttype,$display,$defbgone,
     $defbgtwo,$defbgthree,$parmlev,$uname,$udom,$csec,$cgroup,$usersgroups)=@_;      $defbgtwo,$defbgthree,$parmlev,$uname,$udom,$csec,$cgroup,$usersgroups,$noeditgrp)=@_;
     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};      my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};      my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
     my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom);      my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom);
 # get the values for the parameter in cascading order  
 # empty levels will remain empty      # get the values for the parameter in cascading order
       # empty levels will remain empty
     my ($result,@outpar)=&parmval($$part{$which}.'.'.$$name{$which},      my ($result,@outpar)=&parmval($$part{$which}.'.'.$$name{$which},
       $rid,$$default{$which},$uname,$udom,$csec,$cgroup,$courseopt);        $rid,$$default{$which},$uname,$udom,$csec,$cgroup,$courseopt);
 # get the type for the parameters      # get the type for the parameters
 # problem: these may not be set for all levels      # problem: these may not be set for all levels
     my ($typeresult,@typeoutpar)=&parmval($$part{$which}.'.'.      my ($typeresult,@typeoutpar)=&parmval($$part{$which}.'.'.
                                           $$name{$which}.'.type',$rid,                                            $$name{$which}.'.type',$rid,
          $$defaulttype{$which},$uname,$udom,$csec,$cgroup,$courseopt);           $$defaulttype{$which},$uname,$udom,$csec,$cgroup,$courseopt);
 # cascade down manually      # cascade down manually
     my $cascadetype=$$defaulttype{$which};      my $cascadetype=$$defaulttype{$which};
     for (my $i=14;$i>0;$i--) {      for (my $i=18;$i>0;$i--) {
      if ($typeoutpar[$i]) {          if ($typeoutpar[$i]) {
             $cascadetype=$typeoutpar[$i];              $cascadetype=$typeoutpar[$i];
     } else {          } else {
             $typeoutpar[$i]=$cascadetype;              $typeoutpar[$i]=$cascadetype;
         }          }
     }      }
Line 1014  sub print_row { Line 1415  sub print_row {
     }      }
     my $automatic=&rulescache(($which=~/\_([^\_]+)$/)[0].'_triggers');      my $automatic=&rulescache(($which=~/\_([^\_]+)$/)[0].'_triggers');
     if ($automatic) {      if ($automatic) {
     $parm.='<span class="LC_warning"><br />'.&mt('Automatically sets').' '.join(', ',split(/\:/,$automatic)).'</span>';          $parm.='<span class="LC_warning"><br />'.&mt('Automatically sets').' '.join(', ',split(/\:/,$automatic)).'</span>';
     }      }
     $r->print('<td>'.$parm.'</td>');      $r->print('<td>'.$parm.'</td>');
   
     my $thismarker=$which;      my $thismarker=$which;
     $thismarker=~s/^parameter\_//;      $thismarker=~s/^parameter\_//;
     my $mprefix=$rid.'&'.$thismarker.'&';      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);      my ($othergrp,$grp_parm,$controlgrp);
   
     if ($parmlev eq 'general') {      if ($parmlev eq 'general') {
   
         if ($uname) {          if ($uname) {
             &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);              &print_td($r,4,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
         } elsif ($cgroup) {          } elsif ($cgroup) {
             &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);              &print_td($r,8,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
         } elsif ($csec) {          } elsif ($csec) {
             &print_td($r,9,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);              &print_td($r,12,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
         } else {          } else {
             &print_td($r,14,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);              &print_td($r,18,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
         }          }
     } elsif ($parmlev eq 'map') {      } elsif ($parmlev eq 'map') {
   
         if ($uname) {          if ($uname) {
             &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);              &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
               &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display); 
         } elsif ($cgroup) {          } elsif ($cgroup) {
             &print_td($r,5,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);              &print_td($r,7,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
               &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
         } elsif ($csec) {          } elsif ($csec) {
             &print_td($r,8,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);              &print_td($r,11,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
               &print_td($r,10,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
         } else {          } else {
             &print_td($r,13,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);              &print_td($r,17,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
               &print_td($r,16,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
         }          }
     } else {      } else {
         if ($uname) {          if ($uname) {
Line 1053  sub print_row { Line 1456  sub print_row {
                 ($coursereply,$othergrp,$grp_parm,$controlgrp) =                  ($coursereply,$othergrp,$grp_parm,$controlgrp) =
                     &print_usergroups($r,$$part{$which}.'.'.$$name{$which},                      &print_usergroups($r,$$part{$which}.'.'.$$name{$which},
                        $rid,$cgroup,$defbgone,$usersgroups,$result,$courseopt);                         $rid,$cgroup,$defbgone,$usersgroups,$result,$courseopt);
                 if ($coursereply && $result > 3) {                  if ($coursereply && $result > 4) {
                     if (defined($controlgrp)) {                      if (defined($controlgrp)) {
                         if ($cgroup ne $controlgrp) {                          if ($cgroup ne $controlgrp) {
                             $effective_parm = $grp_parm;                              $effective_parm = $grp_parm;
Line 1064  sub print_row { Line 1467  sub print_row {
             }              }
         }          }
   
         &print_td($r,14,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);          &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,13,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);          &print_td($r,16,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
     &print_td($r,12,'#FFDDDD',$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);          &print_td($r,15,'#FFDDDD',$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
     &print_td($r,11,'#FFDDDD',$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);          &print_td($r,14,'#FFDDDD',$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
     &print_td($r,10,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);          &print_td($r,13,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
   
     if ($csec) {          if ($csec) {
         &print_td($r,9,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);              &print_td($r,12,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
         &print_td($r,8,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);              &print_td($r,11,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
         &print_td($r,7,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);              &print_td($r,10,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
     }              &print_td($r,9,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
           }
   
         if ($cgroup) {          if ($cgroup) {
             &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);              &print_td($r,8,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
             &print_td($r,5,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);              &print_td($r,7,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
             &print_td($r,4,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);              &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
               &print_td($r,5,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
         }          }
   
     if ($uname) {          if ($uname) {
             if ($othergrp) {              if ($othergrp) {
                 $r->print($othergrp);                  $r->print($othergrp);
             }              }
         &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);              &print_td($r,4,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
         &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);              &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
         &print_td($r,1,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);              &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
     }              &print_td($r,1,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
           }
   
     } # end of $parmlev if/else      } # end of $parmlev if/else
     $r->print('<td style="background-color:#CCCCFF;" align="center">'.$effective_parm.'</td>');      $r->print('<td style="background-color:#CCCCFF;" align="center">'.$effective_parm.'</td>');
Line 1099  sub print_row { Line 1505  sub print_row {
         my $sessionval=&Apache::lonnet::EXT('resource.'.$$part{$which}.          my $sessionval=&Apache::lonnet::EXT('resource.'.$$part{$which}.
                                         '.'.$$name{$which},$$symbp{$rid});                                          '.'.$$name{$which},$$symbp{$rid});
         my $sessionvaltype=$typeoutpar[$result];          my $sessionvaltype=$typeoutpar[$result];
         if (!defined($sessionvaltype)) { $sessionvaltype=$$defaulttype{$which}; }          if (!defined($sessionvaltype)) {
               $sessionvaltype=$$defaulttype{$which};
           }
         $r->print('<td style="background-color:#999999;" align="center"><font color="#FFFFFF">'.          $r->print('<td style="background-color:#999999;" align="center"><font color="#FFFFFF">'.
                   &valout($sessionval,$sessionvaltype).'&nbsp;'.                    &valout($sessionval,$sessionvaltype,$$name{$which}).'&nbsp;'.
                   '</font></td>');                    '</font></td>');
     }      }
     $r->print('</tr>');      $r->print('</tr>');
     $r->print("\n");      $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
 sub print_td {  sub print_td {
     my ($r,$which,$defbg,$result,$outpar,$mprefix,$value,$typeoutpar,$display)=@_;      my ($r,$which,$defbg,$result,$outpar,$mprefix,$value,$typeoutpar,$display,$noeditgrp)=@_;
     $r->print('<td style="background-color:'.(($result==$which)?'#AAFFAA':$defbg).      $r->print('<td style="background-color:'.(($result==$which)?'#AAFFAA':$defbg).
               ';" align="center">');                ';" align="center">');
     my $nolink = 0;      my $nolink = 0;
     if ($which == 11 || $which == 12) {      if ($which == 14 || $which == 15) {
           $nolink = 1;
       } elsif (($env{'request.course.sec'} ne '') && ($which > 12)) {
         $nolink = 1;          $nolink = 1;
       } elsif ($which == 5 || $which ==  6 || $which == 7 || $which == 8) {
           if ($noeditgrp) {
               $nolink = 1;
           }
     } elsif ($mprefix =~ /availablestudent\&$/) {      } elsif ($mprefix =~ /availablestudent\&$/) {
         if ($which > 3) {          if ($which > 4) {
             $nolink = 1;              $nolink = 1;
         }          }
     } elsif ($mprefix =~ /examcode\&$/) {      } elsif ($mprefix =~ /examcode\&$/) {
Line 1125  sub print_td { Line 1555  sub print_td {
         }          }
     }      }
     if ($nolink) {      if ($nolink) {
         $r->print(&valout($$outpar[$which],$$typeoutpar[$which]));          $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 {      } else {
         $r->print(&plink($$typeoutpar[$which],          $r->print(&plink($$typeoutpar[$which],
                          $$display{$value},$$outpar[$which],                           $$display{$value},$$outpar[$which],
Line 1134  sub print_td { Line 1565  sub print_td {
     $r->print('</td>'."\n");      $r->print('</td>'."\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 {  sub print_usergroups {
     my ($r,$what,$rid,$cgroup,$defbg,$usersgroups,$result,$courseopt) = @_;      my ($r,$what,$rid,$cgroup,$defbg,$usersgroups,$result,$courseopt) = @_;
     my $courseid = $env{'request.course.id'};      my $courseid = $env{'request.course.id'};
Line 1141  sub print_usergroups { Line 1585  sub print_usergroups {
     my $symb = &symbcache($rid);      my $symb = &symbcache($rid);
     my $symbparm=$symb.'.'.$what;      my $symbparm=$symb.'.'.$what;
     my $map=(&Apache::lonnet::decode_symb($symb))[0];      my $map=(&Apache::lonnet::decode_symb($symb))[0];
       my $recurseparm=$map.'___(rec).'.$what; 
     my $mapparm=$map.'___(all).'.$what;      my $mapparm=$map.'___(all).'.$what;
     my ($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype) =      my ($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype) =
           &parm_control_group($courseid,$usersgroups,$symbparm,$mapparm,$what,            &parm_control_group($courseid,$usersgroups,$symbparm,$mapparm,
                                                                    $courseopt);                                $recurseparm,$what,$courseopt);
     my $bgcolor = $defbg;      my $bgcolor = $defbg;
     my $grp_parm;      my $grp_parm;
     if (($coursereply) && ($cgroup ne $resultgroup)) {      if (($coursereply) && ($cgroup ne $resultgroup)) {
         if ($result > 3) {          if ($result > 3) {
             $bgcolor = '#AAFFAA';              $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">';          $output = '<td style="background-color:'.$bgcolor.';" align="center">';
         if ($resultgroup && $resultlevel) {          if ($resultgroup && $resultlevel) {
             $output .= '<small><b>'.$resultgroup.'</b> ('.$resultlevel.'): </small>'.$grp_parm;              $output .= '<small><b>'.$resultgroup.'</b> ('.$resultlevel.'): </small>'.$grp_parm;
Line 1166  sub print_usergroups { Line 1611  sub print_usergroups {
     return ($coursereply,$output,$grp_parm,$resultgroup);      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 {  sub parm_control_group {
     my ($courseid,$usersgroups,$symbparm,$mapparm,$what,$courseopt) = @_;      my ($courseid,$usersgroups,$symbparm,$mapparm,$recurseparm,$what,$courseopt) = @_;
     my ($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype);      my ($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype);
     my $grpfound = 0;      my $grpfound = 0;
     my @levels = ($symbparm,$mapparm,$what);      my @levels = ($symbparm,$mapparm,$recurseparm,$what);
     my @levelnames = ('resource','map/folder','general');      my @levelnames = ('resource','map/folder','recursive','general');
     foreach my $group (@{$usersgroups}) {      foreach my $group (@{$usersgroups}) {
         if ($grpfound) { last; }          if ($grpfound) { last; }
         for (my $i=0; $i<@levels; $i++) {          for (my $i=0; $i<@levels; $i++) {
Line 1192  sub parm_control_group { Line 1648  sub parm_control_group {
   
   
   
   # extracts lots of information about all of the the course's resources into a variety of hashes.
 sub extractResourceInformation {  sub extractResourceInformation {
     my $ids = shift;      my $ids = shift;
     my $typep = shift;      my $typep = shift;
Line 1281  sub extractResourceInformation { Line 1738  sub extractResourceInformation {
                 $$maptitles{$mapid}=&Apache::lonnet::gettitle($$mapp{$id});                  $$maptitles{$mapid}=&Apache::lonnet::gettitle($$mapp{$id});
             }              }
             $$maptitles{$$mapp{$id}}=$$maptitles{$mapid};              $$maptitles{$$mapp{$id}}=$$maptitles{$mapid};
             $$symbp{$mapid}=$$mapp{$id}.'___(all)';              $$symbp{$mapid}=$$mapp{$id}.'___(all)';  # Added in rev. 1.57, but seems not to be used.
                                                        # Lines 1038 and 1114 which use $symbp{$mapid}
                                                        # are commented out in rev. 1.57
         } else {          } else {
             $$mapp{$id} = $$mapp{$mapid};              $$mapp{$id} = $$mapp{$mapid};
         }          }
Line 1410  sub lookUpTableParameter { Line 1869  sub lookUpTableParameter {
         'contentopen' => 'time_settings',          'contentopen' => 'time_settings',
         'contentclose' => 'time_settings',          'contentclose' => 'time_settings',
         'discussend' => 'time_settings',          'discussend' => 'time_settings',
  'printstartdate' => 'time_settings',          'printstartdate' => 'time_settings',
  'printenddate' => 'time_settings',          'printenddate' => 'time_settings',
         'weight' => 'grading',          'weight' => 'grading',
         'handgrade' => 'grading',          'handgrade' => 'grading',
         'maxtries' => 'tries',          'maxtries' => 'tries',
Line 1498  sub category_order { Line 1957  sub category_order {
   
 sub parmboxes {  sub parmboxes {
     my ($r,$allparms,$pscat,$keyorder)=@_;      my ($r,$allparms,$pscat,$keyorder)=@_;
     my $tempkey;      my %categories = &categories();
     my $tempparameter;  
     my %categories = &categories;  
     my %category_order = &category_order();      my %category_order = &category_order();
     my %categoryList = (      my %categoryList = (
         'time_settings' => [],          'time_settings' => [],
Line 1515  sub parmboxes { Line 1972  sub parmboxes {
         'misc' => [],          'misc' => [],
     );      );
   
     foreach $tempparameter (keys %$allparms) {      foreach my $tempparameter (keys(%$allparms)) {
         &whatIsMyCategory($tempparameter, \%categoryList);          &whatIsMyCategory($tempparameter, \%categoryList);
     }      }
     #part to print the parm-list      #part to print the parm-list
Line 1588  sub partmenu { Line 2045  sub partmenu {
     my %temphash=();      my %temphash=();
     foreach (@{$psprt}) { $temphash{$_}=1; }      foreach (@{$psprt}) { $temphash{$_}=1; }
     foreach my $tempkey (sort {      foreach my $tempkey (sort {
     if ($a==$b) { return ($a cmp $b) } else { return ($a <=> $b); }                  if ($a==$b) { return ($a cmp $b) } else { return ($a <=> $b); }
     } keys(%{$allparts})) {              } keys(%{$allparts})) {
     unless ($tempkey =~ /\./) {          unless ($tempkey =~ /\./) {
         $r->print('<option value="'.$tempkey.'"');              $r->print('<option value="'.$tempkey.'"');
         if ($$psprt[0] eq "all" ||  $temphash{$tempkey}) {              if ($$psprt[0] eq "all" ||  $temphash{$tempkey}) {
         $r->print(' selected="selected"');                  $r->print(' selected="selected"');
               }
               $r->print('>'.$$allparts{$tempkey}.'</option>');
         }          }
         $r->print('>'.$$allparts{$tempkey}.'</option>');  
     }  
     }      }
     $r->print('</select>');      $r->print('</select>');
 }  }
   
 sub usermenu {  sub usermenu {
     my ($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,$usersgroups)=@_;      my ($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,$usersgroups,$pssymb)=@_;
     my $chooseopt=&Apache::loncommon::select_dom_form($udom,'udom').' '.      my $chooseopt=&Apache::loncommon::select_dom_form($udom,'udom').' '.
         &Apache::loncommon::selectstudent_link('parmform','uname','udom');          &Apache::loncommon::selectstudent_link('parmform','uname','udom');
     my $selscript=&Apache::loncommon::studentbrowser_javascript();      my $selscript=&Apache::loncommon::studentbrowser_javascript();
Line 1611  sub usermenu { Line 2068  sub usermenu {
     my %sectionhash = &Apache::loncommon::get_sections();      my %sectionhash = &Apache::loncommon::get_sections();
   
     my $groups;      my $groups;
     my %grouphash = &Apache::longroup::coursegroups();      my %grouphash;
       if (($pssymb) || &Apache::lonnet::allowed('mdg',$env{'request.course.id'})) {
           %grouphash = &Apache::longroup::coursegroups();
       } elsif ($env{'request.course.groups'} ne '') {
           map { $grouphash{$_} = 1; } split(/,/,$env{'request.course.groups'});
       }
   
     my $g_s_header='';      my $g_s_header='';
     my $g_s_footer='';      my $g_s_footer='';
   
     if (%sectionhash) {      my $currsec = $env{'request.course.sec'};
       if ($currsec) {
           $sections=&mt('Section:').' '.$currsec;
           if (%grouphash) {
               $sections .= ';'.('&nbsp;' x2);
           }
       } elsif (%sectionhash && $currsec eq '') {
         $sections=&mt('Section:').' <select name="csec"';          $sections=&mt('Section:').' <select name="csec"';
         if (%grouphash && $parmlev ne 'full') {          if (%grouphash && $parmlev ne 'full') {
             $sections .= qq| onchange="group_or_section('csec')" |;              $sections .= qq| onchange="group_or_section('csec')" |;
         }          }
         $sections .= '>';          $sections .= '>';
     foreach my $section ('',sort keys %sectionhash) {      foreach my $section ('',sort(keys(%sectionhash))) {
         $sections.='<option value="'.$section.'" '.          $sections.='<option value="'.$section.'" '.
         ($section eq $csec?'selected="selected"':'').'>'.$section.          ($section eq $csec?'selected="selected"':'').'>'.$section.
                                                               '</option>';                                                                '</option>';
Line 1630  sub usermenu { Line 2098  sub usermenu {
         $sections.='</select>';          $sections.='</select>';
     }      }
   
     if (%sectionhash && %grouphash && $parmlev ne 'full') {      if (%sectionhash && %grouphash && $parmlev ne 'full' && $currsec eq '') {
         $sections .= '&nbsp;'.&mt('or').'&nbsp;';          $sections .= '&nbsp;'.&mt('or').'&nbsp;';
         $sections .= qq|          $sections .= qq|
 <script type="text/javascript">  <script type="text/javascript">
Line 1663  function group_or_section(caller) { Line 2131  function group_or_section(caller) {
   
     if (%grouphash) {      if (%grouphash) {
         $groups=&mt('Group:').' <select name="cgroup"';          $groups=&mt('Group:').' <select name="cgroup"';
         if (%sectionhash && $env{'form.action'} eq 'settable') {          if (%sectionhash && $env{'form.action'} eq 'settable' && $currsec eq '') {
             $groups .= qq| onchange="group_or_section('cgroup')" |;              $groups .= qq| onchange="group_or_section('cgroup')" |;
         }          }
         $groups .= '>';          $groups .= '>';
         foreach my $grp ('',sort keys %grouphash) {          foreach my $grp ('',sort(keys(%grouphash))) {
             $groups.='<option value="'.$grp.'" ';              $groups.='<option value="'.$grp.'" ';
             if ($grp eq $cgroup) {              if ($grp eq $cgroup) {
                 unless ((defined($uname)) && ($grp eq '')) {                  unless ((defined($uname)) && ($grp eq '')) {
Line 1689  function group_or_section(caller) { Line 2157  function group_or_section(caller) {
         $r->print(&Apache::lonhtmlcommon::row_title(&mt('Group/Section')));          $r->print(&Apache::lonhtmlcommon::row_title(&mt('Group/Section')));
         $r->print($sections.$groups);          $r->print($sections.$groups);
         $r->print(&Apache::lonhtmlcommon::row_closure());          $r->print(&Apache::lonhtmlcommon::row_closure());
       } else {
           $r->print($sections); 
     }      }
   
     $r->print(&Apache::lonhtmlcommon::row_title(&mt('User')));      $r->print(&Apache::lonhtmlcommon::row_title(&mt('User')));
Line 1873  sub mapmenu { Line 2343  sub mapmenu {
 sub levelmenu {  sub levelmenu {
     my ($r,$alllevs,$parmlev)=@_;      my ($r,$alllevs,$parmlev)=@_;
   
     $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parameter Level').&Apache::loncommon::help_open_topic('Course_Parameter_Levels')));      $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parameter Level').
                                                   &Apache::loncommon::help_open_topic('Course_Parameter_Levels')));
     $r->print('<select id="parmlev" name="parmlev" onchange="showHide_courseContent()">');      $r->print('<select id="parmlev" name="parmlev" onchange="showHide_courseContent()">');
     foreach (reverse sort keys %{$alllevs}) {      foreach my $lev (reverse(sort(keys(%{$alllevs})))) {
     $r->print('<option value="'.$$alllevs{$_}.'"');          $r->print('<option value="'.$$alllevs{$lev}.'"');
     if ($parmlev eq $$alllevs{$_}) {          if ($parmlev eq $$alllevs{$lev}) {
         $r->print(' selected="selected"');              $r->print(' selected="selected"');
     }          }
     $r->print('>'.&mt($_).'</option>');          $r->print('>'.&mt($lev).'</option>');
     }      }
     $r->print("</select>");      $r->print("</select>");
 }  }
   
   
 sub sectionmenu {  sub sectionmenu {
     my ($r,$selectedsections)=@_;      my ($selectedsections)=@_;
     my %sectionhash = &Apache::loncommon::get_sections();      my %sectionhash = &Apache::loncommon::get_sections();
     return if (!%sectionhash);      return '' if (!%sectionhash);
   
     $r->print('<select name="Section" multiple="multiple" size="8">');      my (@possibles,$disabled);
     foreach my $s ('all',sort keys %sectionhash) {      if ($env{'request.course.sec'} ne '') {
     $r->print('    <option value="'.$s.'"');          @possibles = ($env{'request.course.sec'});
     foreach (@{$selectedsections}) {          $selectedsections = [$env{'request.course.sec'}];
         if ($s eq $_) {          $disabled = ' disabled="disabled"';
         $r->print(' selected="selected"');      } else {
         last;          @possibles = ('all',sort(keys(%sectionhash)));
         }  
     }      }
     $r->print('>'.$s."</option>\n");      my $output = '<select name="Section" multiple="multiple" size="8"'.$disabled.'>';
       foreach my $s (@possibles) {
           $output .= '    <option value="'.$s.'"';
           if ((@{$selectedsections}) && (grep(/^\Q$s\E$/,@{$selectedsections}))) {  
               $output .= ' selected="selected"';
           }
           $output .= '>'."$s</option>\n";
     }      }
     $r->print("</select>\n");      $output .= "</select>\n";
       return $output;
 }  }
   
 sub groupmenu {  sub groupmenu {
     my ($r,$selectedgroups)=@_;      my ($selectedgroups)=@_;
     my %grouphash = &Apache::longroup::coursegroups();      my %grouphash;
     return if (!%grouphash);      if (&Apache::lonnet::allowed('mdg',$env{'request.course.id'})) {
           %grouphash = &Apache::longroup::coursegroups();
       } elsif ($env{'request.course.groups'} ne '') {
            map { $grouphash{$_} = 1; } split(/,/,$env{'request.course.groups'});
       }
       return '' if (!%grouphash);
   
     $r->print('<select name="Group" multiple="multiple" size="8">');      my $output = '<select name="Group" multiple="multiple" size="8">';
     foreach my $group (sort(keys(%grouphash))) {      foreach my $group (sort(keys(%grouphash))) {
     $r->print('    <option value="'.$group.'"');          $output .= '    <option value="'.$group.'"';
     foreach (@{$selectedgroups}) {          if ((@{$selectedgroups}) && (grep(/^\Q$group\E$/,\@{$selectedgroups}))) {
         if ($group eq $_) {              $output .=  ' selected="selected"';
         $r->print(' selected="selected"');  
         last;  
         }          }
           $output .= '>'."$group</option>\n";
     }      }
     $r->print('>'.$group."</option>\n");      $output .= "</select>\n";
     }      return $output;
     $r->print("</select>\n");  
 }  }
   
   
 sub keysplit {  sub keysplit {
     my $keyp=shift;      my $keyp=shift;
     return (split(/\,/,$keyp));      return (split(/\,/,$keyp));
Line 1933  sub keysplit { Line 2412  sub keysplit {
 sub keysinorder {  sub keysinorder {
     my ($name,$keyorder)=@_;      my ($name,$keyorder)=@_;
     return sort {      return sort {
     $$keyorder{$a} <=> $$keyorder{$b};          $$keyorder{$a} <=> $$keyorder{$b};
     } (keys %{$name});      } (keys(%{$name}));
 }  }
   
 sub keysinorder_bytype {  sub keysinorder_bytype {
     my ($name,$keyorder)=@_;      my ($name,$keyorder)=@_;
     return sort {      return sort {
     my $ta=(split('_',$a))[-1];          my $ta=(split('_',$a))[-1];
     my $tb=(split('_',$b))[-1];          my $tb=(split('_',$b))[-1];
     if ($$keyorder{'parameter_0_'.$ta} == $$keyorder{'parameter_0_'.$tb}) {          if ($$keyorder{'parameter_0_'.$ta} == $$keyorder{'parameter_0_'.$tb}) {
         return ($a cmp $b);              return ($a cmp $b);
     }          }
     $$keyorder{'parameter_0_'.$ta} <=> $$keyorder{'parameter_0_'.$tb};          $$keyorder{'parameter_0_'.$ta} <=> $$keyorder{'parameter_0_'.$tb};
     } (keys %{$name});      } (keys(%{$name}));
 }  }
   
 sub keysindisplayorder {  sub keysindisplayorder {
     my ($name,$keyorder)=@_;      my ($name,$keyorder)=@_;
     return sort {      return sort {
     $$keyorder{'parameter_0_'.$a} <=> $$keyorder{'parameter_0_'.$b};          $$keyorder{'parameter_0_'.$a} <=> $$keyorder{'parameter_0_'.$b};
     } (keys %{$name});      } (keys(%{$name}));
 }  }
   
 sub sortmenu {  sub sortmenu {
Line 1993  sub standardkeyorder { Line 2472  sub standardkeyorder {
         'parameter_0_discussend' => 19,          'parameter_0_discussend' => 19,
         'parameter_0_discusshide' => 20,          'parameter_0_discusshide' => 20,
         'parameter_0_discussvote' => 21,          'parameter_0_discussvote' => 21,
  'parameter_0_printstartdate'  =>  22,          'parameter_0_printstartdate'  =>  22,
  'parameter_0_printenddate' =>  23);          'parameter_0_printenddate' =>  23);
 }  }
   
   
   # Table mode UI.
 sub assessparms {  sub assessparms {
   
     my $r=shift;      my $r=shift;
   
   
   
 # -------------------------------------------------------- Variable declaration  # -------------------------------------------------------- Variable declaration
     my @ids=();      my @ids=();
     my %symbp=();      my %symbp=();
Line 2044  sub assessparms { Line 2523  sub assessparms {
     my $message='';      my $message='';
   
     $csec=$env{'form.csec'};      $csec=$env{'form.csec'};
       if ($env{'request.course.sec'} ne '') {
           $csec = $env{'request.course.sec'};    
       }
   
   # Check group privs.
     $cgroup=$env{'form.cgroup'};      $cgroup=$env{'form.cgroup'};
       my $noeditgrp; 
       if ($cgroup ne '') {
           unless (&Apache::lonnet::allowed('mdg',$env{'request.course.id'})) {
               if (($env{'request.course.groups'} eq '') || 
                   (!grep(/^\Q$cgroup\E$/,split(/,/,$env{'request.course.groups'})))) {
                   $noeditgrp = 1;
               }
           }
       }
   
     if      ($udom=$env{'form.udom'}) {      if      ($udom=$env{'form.udom'}) {
     } elsif ($udom=$env{'request.role.domain'}) {      } elsif ($udom=$env{'request.role.domain'}) {
Line 2073  sub assessparms { Line 2566  sub assessparms {
   
 # ----------------------------------------------- Was this started from grades?  # ----------------------------------------------- Was this started from grades?
   
     if (($env{'form.command'} eq 'set') && ($env{'form.url'})      if (($env{'form.command'} eq 'set') && ($env{'form.url'}) &&
     && (!$env{'form.dis'})) {              (!$env{'form.dis'})) {
         my $url=$env{'form.url'};          my $url=$env{'form.url'};
         $url=~s-^http://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--;          $url=~s-^http://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--;
         $pssymb=&Apache::lonnet::symbread($url);          $pssymb=&Apache::lonnet::symbread($url);
Line 2092  sub assessparms { Line 2585  sub assessparms {
   
     my $id=$env{'form.id'};      my $id=$env{'form.id'};
     if (($id) && ($udom)) {      if (($id) && ($udom)) {
         $uname=(&Apache::lonnet::idget($udom,$id))[1];          $uname=(&Apache::lonnet::idget($udom,[$id],'ids'))[1];
         if ($uname) {          if ($uname) {
             $id='';              $id='';
         } else {          } else {
Line 2167  sub assessparms { Line 2660  sub assessparms {
         my $chome = $env{'course.'.$env{'request.course.id'}.'.home'};          my $chome = $env{'course.'.$env{'request.course.id'}.'.home'};
         my ($got_chostname,$chostname,$cmajor,$cminor);          my ($got_chostname,$chostname,$cmajor,$cminor);
         my $totalstored = 0;          my $totalstored = 0;
           my $now = time;
   
         for (my $i=0;$i<=$#markers;$i++) {          for (my $i=0;$i<=$#markers;$i++) {
             my ($needsrelease,$needsnewer,$name);              my ($needsrelease,$needsnewer,$name,$namematch);
             if ($markers[$i] =~ /^[\d.]+\&0_availablestudent\&(1|2|3)$/) {              if (($env{'request.course.sec'} ne '') && ($markers[$i] =~ /\&(9|10|11|12)$/)) {
                   next if ($csec ne $env{'request.course.sec'});
               }
               if ($markers[$i] =~ /\&(8|7|6|5)$/) {
                   next if ($noeditgrp);
               }
               if ($markers[$i] =~ /\&(17|11|7|3)$/) {
                   $namematch = 'maplevelrecurse';
               }
               if ($markers[$i] =~ /^[\d.]+\&0_availablestudent\&(1|2|3|4)$/) {
                 my (@ok_slots,@fail_slots,@del_slots);                  my (@ok_slots,@fail_slots,@del_slots);
                 my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom);                  my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom);
                 my ($level,@all) =                  my ($level,@all) =
Line 2201  sub assessparms { Line 2702  sub assessparms {
                         }                          }
                     }                      }
                 }                  }
             } elsif ($markers[$i] =~ /_(type|lenient|retrypartial|discussvote|examcode)\&\d+$/) {              } elsif ($markers[$i] =~ /_(type|lenient|retrypartial|discussvote|examcode|printstartdate|printenddate|acc|interval)\&\d+$/) {
                 $name = $1;                  $name = $1;
                 my $val = $values[$i];                  my $val = $values[$i];
                   my $valmatch = '';
                 if ($name eq 'examcode') {                  if ($name eq 'examcode') {
                     if (&Apache::lonnet::validCODE($values[$i])) {                      if (&Apache::lonnet::validCODE($values[$i])) {
                         $val = 'valid';                          $val = 'valid';
                     }                      }
                   } elsif ($name eq 'printstartdate') {
                       if ($val =~ /^\d+$/) {
                           if ($val > $now) {
                               $val = 'future';
                           }
                       } 
                   } elsif ($name eq 'printenddate') {
                       if ($val =~ /^\d+$/) {
                           if ($val < $now) {
                               $val = 'past';
                           }
                       }
                   } elsif (($name eq 'lenient') || ($name eq 'acc')) {
                       my $stringtype = &get_stringtype($name);
                       my $stringmatch = &standard_string_matches($stringtype);
                       if (ref($stringmatch) eq 'ARRAY') {
                           foreach my $item (@{$stringmatch}) {
                               if (ref($item) eq 'ARRAY') {
                                   my ($regexpname,$pattern) = @{$item};
                                   if ($pattern ne '') {
                                       if ($val =~ /$pattern/) {
                                           $valmatch = $regexpname;
                                           $val = '';
                                           last;
                                       }
                                   }
                               }
                           }
                       }
                   } elsif ($name eq '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 ($val =~ /$pattern/) {
                                           $valmatch = $regexpname;
                                           $val = '';
                                           last;
                                       }
                                   }
                               }
                           }
                       }
                 }                  }
                 $needsrelease =                  $needsrelease =
                     $Apache::lonnet::needsrelease{"parameter:$name:$val"};                      $Apache::lonnet::needsrelease{"parameter:$name:$val:$valmatch:"};
                 if ($needsrelease) {                  if ($needsrelease) {
                     unless ($got_chostname) {                      unless ($got_chostname) {
                         ($chostname,$cmajor,$cminor) = &parameter_release_vars();                          ($chostname,$cmajor,$cminor) = &parameter_release_vars();
                         $got_chostname = 1;                          $got_chostname = 1;
                     }                      } 
                     $needsnewer = &parameter_releasecheck($name,$val,                      $needsnewer = &parameter_releasecheck($name,$val,$valmatch,undef,
                                                           $needsrelease,                                                            $needsrelease,
                                                           $cmajor,$cminor);                                                            $cmajor,$cminor);
                 }                  }
             }              }
             if ($needsnewer) {              if ($needsnewer) {
                 $message .= &oldversion_warning($name,$values[$i],$chostname,$cmajor,                  undef($namematch);
               } else {
                   my $currneeded;
                   if ($needsrelease) {
                       $currneeded = $needsrelease;
                   }
                   if ($namematch) {
                       $needsrelease =
                           $Apache::lonnet::needsrelease{"parameter::::$namematch"};
                       if (($needsrelease) && (($currneeded eq '') || ($needsrelease < $currneeded))) {
                           unless ($got_chostname) {
                               ($chostname,$cmajor,$cminor) = &parameter_release_vars();
                               $got_chostname = 1;
                           }
                           $needsnewer = &parameter_releasecheck(undef,undef,undef,$namematch,
                                                                 $needsrelease,
                                                                 $cmajor,$cminor);
                       } else {
                           undef($namematch);
                       }
                   }
               }
               if ($needsnewer) {
                   $message .= &oldversion_warning($name,$namematch,$values[$i],$chostname,$cmajor,
                                                 $cminor,$needsrelease);                                                  $cminor,$needsrelease);
             } else {              } else {
                 $message.=&storeparm(split(/\&/,$markers[$i]),                  $message.=&storeparm(split(/\&/,$markers[$i]),
Line 2241  sub assessparms { Line 2812  sub assessparms {
         }          }
     }      }
 #----------------------------------------------- if all selected, fill in array  #----------------------------------------------- if all selected, fill in array
     if ($pscat[0] eq "all") {@pscat = (keys %allparms);}      if ($pscat[0] eq "all") {@pscat = (keys(%allparms));}
     if (!@pscat) { @pscat=('duedate','opendate','answerdate','weight','maxtries','type','problemstatus') };      if (!@pscat) { @pscat=('duedate','opendate','answerdate','weight','maxtries','type','problemstatus') };
     if ($psprt[0] eq "all" || !@psprt) {@psprt = (keys %allparts);}      if ($psprt[0] eq "all" || !@psprt) {@psprt = (keys(%allparts));}
 # ------------------------------------------------------------------ Start page  # ------------------------------------------------------------------ Start page
   
     my $crstype = &Apache::loncommon::course_type();      my $crstype = &Apache::loncommon::course_type();
     &startpage($r,$pssymb,$crstype);      &startpage($r,$pssymb,$crstype);
   
     foreach ('tolerance','date_default','date_start','date_end',      foreach my $item ('tolerance','date_default','date_start','date_end',
         'date_interval','int','float','string') {          'date_interval','int','float','string') {
         $r->print('<input type="hidden" value="'.          $r->print('<input type="hidden" value="'.
           &HTML::Entities::encode($env{'form.recent_'.$_},'"&<>').            &HTML::Entities::encode($env{'form.recent_'.$item},'"&<>').
           '" name="recent_'.$_.'" />');            '" name="recent_'.$item.'" />');
     }      }
   
     # ----- Start Parameter Selection      # ----- Start Parameter Selection
Line 2304  ENDPARMSELSCRIPT Line 2875  ENDPARMSELSCRIPT
         # Step 3          # Step 3
         $r->print(&Apache::lonhtmlcommon::topic_bar(3,&mt('User Specification (optional)'),'parmstep3'));          $r->print(&Apache::lonhtmlcommon::topic_bar(3,&mt('User Specification (optional)'),'parmstep3'));
         $r->print(&Apache::lonhtmlcommon::start_pick_box());          $r->print(&Apache::lonhtmlcommon::start_pick_box());
         &usermenu($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,\@usersgroups);          &usermenu($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,\@usersgroups,$pssymb);
         $r->print(&Apache::lonhtmlcommon::row_closure(1));          $r->print(&Apache::lonhtmlcommon::row_closure(1));
         $r->print(&Apache::lonhtmlcommon::end_pick_box());          $r->print(&Apache::lonhtmlcommon::end_pick_box());
   
Line 2336  ENDPARMSELSCRIPT Line 2907  ENDPARMSELSCRIPT
                   '<br />');                    '<br />');
         $r->print(&Apache::lonhtmlcommon::topic_bar('',&mt('Additional Display Specification (optional)')));          $r->print(&Apache::lonhtmlcommon::topic_bar('',&mt('Additional Display Specification (optional)')));
         $r->print(&Apache::lonhtmlcommon::start_pick_box());          $r->print(&Apache::lonhtmlcommon::start_pick_box());
         &usermenu($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,\@usersgroups);          &usermenu($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,\@usersgroups,$pssymb);
         $r->print(&Apache::lonhtmlcommon::row_closure(1));          $r->print(&Apache::lonhtmlcommon::row_closure(1));
         $r->print(&Apache::lonhtmlcommon::end_pick_box());          $r->print(&Apache::lonhtmlcommon::end_pick_box());
         $r->print('<p>'          $r->print('<p>'
Line 2360  ENDPARMSELSCRIPT Line 2931  ENDPARMSELSCRIPT
   
     @pscat = @temp_pscat;      @pscat = @temp_pscat;
   
   
     if (($env{'form.prevvisit'}) || ($pschp) || ($pssymb)) {      if (($env{'form.prevvisit'}) || ($pschp) || ($pssymb)) {
 # ----------------------------------------------------------------- Start Table  # ----------------------------------------------------------------- Start Table
         my @catmarker=map { tr|.|_|; 'parameter_'.$_; } @pscat;          my @catmarker=map { tr|.|_|; 'parameter_'.$_; } @pscat;
Line 2370  ENDPARMSELSCRIPT Line 2942  ENDPARMSELSCRIPT
 #  #
 # This produces the cascading table output of parameters  # This produces the cascading table output of parameters
 #  #
                my $coursespan=$csec?8:5;              my $coursespan=$csec?10:6;
                my $userspan=3;              my $userspan=4;
                if ($cgroup ne '') {              if ($cgroup ne '') {
                   $coursespan += 3;                  $coursespan += 4;
                }              }
   
                $r->print(&Apache::loncommon::start_data_table());              $r->print(&Apache::loncommon::start_data_table());
 #              #
 # This produces the headers              # This produces the headers
 #              #
                $r->print('<tr><td colspan="5"></td>');              $r->print('<tr><td colspan="5"></td>');
                $r->print('<th colspan="'.($coursespan).'">'.&mt('Any User').'</th>');              $r->print('<th colspan="'.($coursespan).'">'.&mt('Any User').'</th>');
                if ($uname) {              if ($uname) {
                 if (@usersgroups > 1) {                  if (@usersgroups > 1) {
                        $userspan ++;                      $userspan ++;
                    }                  }
                    $r->print('<th colspan="'.$userspan.'" rowspan="2">');                  $r->print('<th colspan="'.$userspan.'" rowspan="2">');
                    $r->print(&mt('User [_1] at Domain [_2]',"'".$uname."'","'".$udom."'").'</th>');                  $r->print(&mt('User [_1] at Domain [_2]',"'".$uname."'","'".$udom."'").'</th>');
                }              }
                my %lt=&Apache::lonlocal::texthash(              my %lt=&Apache::lonlocal::texthash(
                 'pie'    => "Parameter in Effect",                  'pie'    => "Parameter in Effect",
                 'csv'    => "Current Session Value",                  'csv'    => "Current Session Value",
                 'rl'     => "Resource Level",                  'rl'     => "Resource Level",
Line 2403  ENDPARMSELSCRIPT Line 2975  ENDPARMSELSCRIPT
                 'femof'  => 'from Enclosing Map or Folder',                  'femof'  => 'from Enclosing Map or Folder',
                 'gen'    => 'general',                  'gen'    => 'general',
                 'foremf' => 'for Enclosing Map or Folder',                  'foremf' => 'for Enclosing Map or Folder',
                   'formfr' => 'for Map or Folder (recursive)',
                 'fr'     => 'for Resource'                  'fr'     => 'for Resource'
             );              );
                $r->print(<<ENDTABLETWO);              $r->print(<<ENDTABLETWO);
 <th rowspan="3">$lt{'pie'}</th>  <th rowspan="3">$lt{'pie'}</th>
 <th rowspan="3">$lt{'csv'}<br />($csuname:$csudom)</th>  <th rowspan="3">$lt{'csv'}<br />($csuname:$csudom)</th>
 </tr><tr><td colspan="5"></td><th colspan="2">$lt{'ic'}</th><th colspan="2">$lt{'rl'}</th>  </tr><tr><td colspan="5"></td><th colspan="3">$lt{'ic'}</th><th colspan="2">$lt{'rl'}</th>
 <th colspan="1">$lt{'ic'}</th>  <th colspan="1">$lt{'ic'}</th>
   
 ENDTABLETWO  ENDTABLETWO
                if ($csec) {              if ($csec) {
                    $r->print('<th colspan="3">'.                  $r->print('<th colspan="4">'.
                   &mt("in Section")." $csec</th>");                  &mt("in Section")." $csec</th>");
                }              }
                if ($cgroup) {              if ($cgroup) {
                 $r->print('<th colspan="3">'.                  $r->print('<th colspan="4">'.
                 &mt("in Group")." $cgroup</th>");                  &mt("in Group")." $cgroup</th>");
                }              }
                $r->print(<<ENDTABLEHEADFOUR);              $r->print(<<ENDTABLEHEADFOUR);
 </tr><tr><th>$lt{'aut'}</th><th>$lt{'type'}</th>  </tr><tr><th>$lt{'aut'}</th><th>$lt{'type'}</th>
 <th>$lt{'emof'}</th><th>$lt{'part'}</th><th>$lt{'pn'}</th>  <th>$lt{'emof'}</th><th>$lt{'part'}</th><th>$lt{'pn'}</th>
 <th>$lt{'gen'}</th><th>$lt{'foremf'}</th>  <th>$lt{'gen'}</th><th>$lt{'formfr'}</th><th>$lt{'foremf'}</th>
 <th>$lt{'def'}</th><th>$lt{'femof'}</th><th>$lt{'fr'}</th>  <th>$lt{'def'}</th><th>$lt{'femof'}</th><th>$lt{'fr'}</th>
 ENDTABLEHEADFOUR  ENDTABLEHEADFOUR
   
                if ($csec) {              if ($csec) {
                    $r->print('<th>'.&mt('general').'</th><th>'.&mt('for Enclosing Map or Folder').'</th><th>'.&mt('for Resource').'</th>');                  $r->print('<th>'.$lt{'gen'}.'</th><th>'.$lt{'formfr'}.'</th><th>'.$lt{'foremf'}.'</th><th>'.$lt{'fr'}.'</th>');
                }              }
   
                if ($cgroup) {              if ($cgroup) {
                 $r->print('<th>'.&mt('general').'</th><th>'.&mt('for Enclosing Map or Folder').'</th><th>'.&mt('for Resource').'</th>');                  $r->print('<th>'.$lt{'gen'}.'</th><th>'.$lt{'formfr'}.'</th><th>'.&mt('foremf').'</th><th>'.$lt{'fr'}.'</th>');
                }              }
   
                if ($uname) {              if ($uname) {
                 if (@usersgroups > 1) {                  if (@usersgroups > 1) {
                     $r->print('<th>'.&mt('Control by other group?').'</th>');                      $r->print('<th>'.&mt('Control by other group?').'</th>');
                    }                  }
                    $r->print('<th>'.&mt('general').'</th><th>'.&mt('for Enclosing Map or Folder').'</th><th>'.&mt('for Resource').'</th>');                  $r->print('<th>'.$lt{'gen'}.'</th><th>'.$lt{'formfr'}.'</th><th>'.$lt{'foremf'}.'</th><th>'.$lt{'fr'}.'</th>');
                }              }
   
                $r->print('</tr>');              $r->print('</tr>');
 #  #
 # Done with the headers  # Done with the headers
 #   # 
                my $defbgone='';              my $defbgone='';
                my $defbgtwo='';              my $defbgtwo='';
                my $defbgthree = '';              my $defbgthree = '';
   
                foreach my $rid (@ids) {              foreach my $rid (@ids) {
   
                 my ($inmapid)=($rid=~/\.(\d+)$/);                  my ($inmapid)=($rid=~/\.(\d+)$/);
   
                 if ((!$pssymb &&                  if ((!$pssymb &&
                  (($pschp eq 'all') || ($allmaps{$pschp} eq $mapp{$rid})))                          (($pschp eq 'all') || ($allmaps{$pschp} eq $mapp{$rid})))
                 ||                          ||
                 ($pssymb && $pssymb eq $symbp{$rid})) {                          ($pssymb && $pssymb eq $symbp{$rid})) {
 # ------------------------------------------------------ Entry for one resource  # ------------------------------------------------------ Entry for one resource
                     if ($defbgone eq '#E0E099') {                      if ($defbgone eq '#E0E099') {
                         $defbgone='#E0E0DD';                          $defbgone='#E0E0DD';
Line 2485  ENDTABLEHEADFOUR Line 3058  ENDTABLEHEADFOUR
                     my $uri=&Apache::lonnet::declutter($uris{$rid});                      my $uri=&Apache::lonnet::declutter($uris{$rid});
   
                     my $filter=$env{'form.filter'};                      my $filter=$env{'form.filter'};
                     foreach (&keysplit($keyp{$rid})) {                      foreach my $tempkeyp (&keysplit($keyp{$rid})) {
                         my $tempkeyp = $_;  
                         if (grep $_ eq $tempkeyp, @catmarker) {                          if (grep $_ eq $tempkeyp, @catmarker) {
                           my $parmname=&Apache::lonnet::metadata($uri,$_.'.name');                              my $parmname=&Apache::lonnet::metadata($uri,$tempkeyp.'.name');
 # We may only want certain parameters listed      # We may only want certain parameters listed
                           if ($filter) {                              if ($filter) {
                              unless ($filter=~/\Q$parmname\E/) { next; }                                  unless ($filter=~/\Q$parmname\E/) { next; }
                           }                              }
                           $name{$_}=$parmname;                              $name{$tempkeyp}=$parmname;
                           $part{$_}=&Apache::lonnet::metadata($uri,$_.'.part');                              $part{$tempkeyp}=&Apache::lonnet::metadata($uri,$tempkeyp.'.part');
   
                           my $parmdis=&Apache::lonnet::metadata($uri,$_.'.display');                              my $parmdis=&Apache::lonnet::metadata($uri,$tempkeyp.'.display');
                           if ($allparms{$name{$_}} ne '') {                              if ($allparms{$name{$tempkeyp}} ne '') {
                               my $identifier;                                  my $identifier;
                               if ($parmdis =~ /(\s*\[Part.*)$/) {                                  if ($parmdis =~ /(\s*\[Part.*)$/) {
                                   $identifier = $1;                                      $identifier = $1;
                               }                                  }
                               $display{$_} = $allparms{$name{$_}}.$identifier;                                  $display{$tempkeyp} = $allparms{$name{$tempkeyp}}.$identifier;
                           } else {                              } else {
                               $display{$_} = $parmdis;                                  $display{$tempkeyp} = $parmdis;
                           }                              }
                           unless ($display{$_}) { $display{$_}=''; }                              unless ($display{$tempkeyp}) { $display{$tempkeyp}=''; }
                           $display{$_}.=' ('.$name{$_}.')';                              $display{$tempkeyp}.=' ('.$name{$tempkeyp}.')';
                           $default{$_}=&Apache::lonnet::metadata($uri,$_);                              $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$tempkeyp);
                           $type{$_}=&Apache::lonnet::metadata($uri,$_.'.type');                              $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$tempkeyp.'.type');
                           $thistitle=&Apache::lonnet::metadata($uri,$_.'.title');                              $thistitle=&Apache::lonnet::metadata($uri,$tempkeyp.'.title');
                         }                          }
                     }                      }
                     my $totalparms=scalar keys %name;                      my $totalparms=scalar(keys(%name));
                     if ($totalparms>0) {                      if ($totalparms>0) {
                            my $firstrow=1;                          my $firstrow=1;
                         my $title=&Apache::lonnet::gettitle($symbp{$rid});                          my $title=&Apache::lonnet::gettitle($symbp{$rid});
                         $r->print('<tr><td style="background-color:'.$defbgone.';"'.                          $r->print('<tr><td style="background-color:'.$defbgone.';"'.
                              ' rowspan='.$totalparms.                               ' rowspan='.$totalparms.
Line 2539  ENDTABLEHEADFOUR Line 3111  ENDTABLEHEADFOUR
                         $r->print('<td style="background-color:'.$defbgone.';"'.                          $r->print('<td style="background-color:'.$defbgone.';"'.
                                       ' rowspan='.$totalparms.                                        ' rowspan='.$totalparms.
                                       '>'.$maptitles{$mapp{$rid}}.'</td>');                                        '>'.$maptitles{$mapp{$rid}}.'</td>');
                         foreach (&keysinorder_bytype(\%name,\%keyorder)) {                          foreach my $item (&keysinorder_bytype(\%name,\%keyorder)) {
   
                             unless ($firstrow) {                              unless ($firstrow) {
                                 $r->print('<tr>');                                  $r->print('<tr>');
                             } else {                              } else {
                                 undef $firstrow;                                  undef $firstrow;
                             }                              }
                             &print_row($r,$_,\%part,\%name,\%symbp,$rid,\%default,                              &print_row($r,$item,\%part,\%name,\%symbp,$rid,\%default,
                                        \%type,\%display,$defbgone,$defbgtwo,                                         \%type,\%display,$defbgone,$defbgtwo,
                                        $defbgthree,$parmlev,$uname,$udom,$csec,                                         $defbgthree,$parmlev,$uname,$udom,$csec,
                                                             $cgroup,\@usersgroups);                                         $cgroup,\@usersgroups,$noeditgrp);
                         }                          }
                     }                      }
                 }                  }
Line 2573  ENDTABLEHEADFOUR Line 3144  ENDTABLEHEADFOUR
   
 #-------------------------------------------- for each map, gather information  #-------------------------------------------- for each map, gather information
             my $mapid;              my $mapid;
                foreach $mapid (sort {$maplist{$a} cmp $maplist{$b}} keys %maplist) {              foreach $mapid (sort {$maplist{$a} cmp $maplist{$b}} keys(%maplist)) {
                 my $maptitle = $maplist{$mapid};                  my $maptitle = $maplist{$mapid};
   
 #-----------------------  loop through ids and get all parameter types for map  #-----------------------  loop through ids and get all parameter types for map
Line 2587  ENDTABLEHEADFOUR Line 3158  ENDTABLEHEADFOUR
   
 #        $r->print("Catmarker: @catmarker<br />\n");  #        $r->print("Catmarker: @catmarker<br />\n");
   
                 foreach (@ids) {                  foreach my $id (@ids) {
                     ($map)=(/([\d]*?)\./);                      ($map)=($id =~ /([\d]*?)\./);
                       my $rid = $_;                      my $rid = $id;
   
 #                  $r->print("$mapid:$map:   $rid <br /> \n");  #                  $r->print("$mapid:$map:   $rid <br /> \n");
   
                      if ($map eq $mapid) {                      if ($map eq $mapid) {
                         my $uri=&Apache::lonnet::declutter($uris{$rid});                          my $uri=&Apache::lonnet::declutter($uris{$rid});
 #                    $r->print("Keys: $keyp{$rid} <br />\n");  #                    $r->print("Keys: $keyp{$rid} <br />\n");
   
Line 2604  ENDTABLEHEADFOUR Line 3175  ENDTABLEHEADFOUR
 # When storing information, store as part 0  # When storing information, store as part 0
 # When requesting information, request from full part  # When requesting information, request from full part
 #-------------------------------------------------------------------  #-------------------------------------------------------------------
                         foreach (&keysplit($keyp{$rid})) {                          foreach my $fullkeyp (&keysplit($keyp{$rid})) {
                              my $tempkeyp = $_;                              my $tempkeyp = $fullkeyp;
                               my $fullkeyp = $tempkeyp;                              $tempkeyp =~ s/_\w+_/_0_/;
                               $tempkeyp =~ s/_\w+_/_0_/;  
   
                               if ((grep $_ eq $fullkeyp, @catmarker) &&(!$name{$tempkeyp})) {                              if ((grep $_ eq $fullkeyp, @catmarker) &&(!$name{$tempkeyp})) {
                                 $part{$tempkeyp}="0";                                  $part{$tempkeyp}="0";
                                 $name{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.name');                                  $name{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.name');
                                 my $parmdis=&Apache::lonnet::metadata($uri,$fullkeyp.'.display');                                  my $parmdis=&Apache::lonnet::metadata($uri,$fullkeyp.'.display');
Line 2629  ENDTABLEHEADFOUR Line 3199  ENDTABLEHEADFOUR
                                 $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.type');                                  $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.type');
                               }                                }
                         } # end loop through keys                          } # end loop through keys
                       }                      }
                 } # end loop through ids                  } # end loop through ids
   
 #---------------------------------------------------- print header information  #---------------------------------------------------- print header information
Line 2663  ENDTABLEHEADFOUR Line 3233  ENDTABLEHEADFOUR
                 $r->print('<p>'.&Apache::loncommon::start_data_table()                  $r->print('<p>'.&Apache::loncommon::start_data_table()
                          .&Apache::loncommon::start_data_table_header_row()                           .&Apache::loncommon::start_data_table_header_row()
                          .'<th>'.&mt('Parameter Name').'</th>'                           .'<th>'.&mt('Parameter Name').'</th>'
                          .'<th>'.&mt('Default Value').'</th>'                           .'<th>'.&mt('Recursive Value').'</th>'
                            .'<th>'.&mt('Non-Recursive Value').'</th>'
                          .'<th>'.&mt('Parameter in Effect').'</th>'                           .'<th>'.&mt('Parameter in Effect').'</th>'
                          .&Apache::loncommon::end_data_table_header_row()                           .&Apache::loncommon::end_data_table_header_row()
                 );                  );
   
                 foreach (&keysinorder(\%name,\%keyorder)) {                  foreach my $item (&keysinorder(\%name,\%keyorder)) {
                     $r->print(&Apache::loncommon::start_data_table_row());                      $r->print(&Apache::loncommon::start_data_table_row());
                     &print_row($r,$_,\%part,\%name,\%symbp,$mapid,\%default,                      &print_row($r,$item,\%part,\%name,\%symbp,$mapid,\%default,
                            \%type,\%display,$defbgone,$defbgtwo,$defbgthree,                             \%type,\%display,$defbgone,$defbgtwo,$defbgthree,
                            $parmlev,$uname,$udom,$csec,$cgroup);                             $parmlev,$uname,$udom,$csec,$cgroup,'',$noeditgrp);
                 }                  }
                 $r->print(&Apache::loncommon::end_data_table().'</p>'                  $r->print(&Apache::loncommon::end_data_table().'</p>'
                          .'</div>'                           .'</div>'
Line 2695  ENDTABLEHEADFOUR Line 3266  ENDTABLEHEADFOUR
             my %type = ();              my %type = ();
             my %default = ();              my %default = ();
   
             foreach (@ids) {              foreach $id (@ids) {
                 my $rid = $_;                  my $rid = $id;
   
                 my $uri=&Apache::lonnet::declutter($uris{$rid});                  my $uri=&Apache::lonnet::declutter($uris{$rid});
   
Line 2707  ENDTABLEHEADFOUR Line 3278  ENDTABLEHEADFOUR
 # When storing information, store as part 0  # When storing information, store as part 0
 # When requesting information, request from full part  # When requesting information, request from full part
 #-------------------------------------------------------------------  #-------------------------------------------------------------------
                 foreach (&keysplit($keyp{$rid})) {                  foreach my $fullkeyp (&keysplit($keyp{$rid})) {
                     my $tempkeyp = $_;                      my $tempkeyp = $fullkeyp;
                       my $fullkeyp = $tempkeyp;                      $tempkeyp =~ s/_\w+_/_0_/;
                       $tempkeyp =~ s/_\w+_/_0_/;                      if ((grep $_ eq $fullkeyp, @catmarker) &&(!$name{$tempkeyp})) {
                       if ((grep $_ eq $fullkeyp, @catmarker) &&(!$name{$tempkeyp})) {  
                         $part{$tempkeyp}="0";                          $part{$tempkeyp}="0";
                         $name{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.name');                          $name{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.name');
                         my $parmdis=&Apache::lonnet::metadata($uri,$fullkeyp.'.display');                          my $parmdis=&Apache::lonnet::metadata($uri,$fullkeyp.'.display');
Line 2729  ENDTABLEHEADFOUR Line 3299  ENDTABLEHEADFOUR
                         $display{$tempkeyp} =~ s/_\w+_/_0_/;                          $display{$tempkeyp} =~ s/_\w+_/_0_/;
                         $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp);                          $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp);
                         $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.type');                          $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.type');
                       }                      }
                 } # end loop through keys                  } # end loop through keys
             } # end loop through ids              } # end loop through ids
   
Line 2759  ENDMAPONE Line 3329  ENDMAPONE
                      .&Apache::loncommon::end_data_table_header_row()                       .&Apache::loncommon::end_data_table_header_row()
             );              );
   
             foreach (&keysinorder(\%name,\%keyorder)) {              foreach my $item (&keysinorder(\%name,\%keyorder)) {
                 $r->print(&Apache::loncommon::start_data_table_row());                  $r->print(&Apache::loncommon::start_data_table_row());
                 &print_row($r,$_,\%part,\%name,\%symbp,$mapid,\%default,                  &print_row($r,$item,\%part,\%name,\%symbp,$mapid,\%default,
                        \%type,\%display,$defbgone,$defbgtwo,$defbgthree,                         \%type,\%display,$defbgone,$defbgtwo,$defbgthree,
                                    $parmlev,$uname,$udom,$csec,$cgroup);                                     $parmlev,$uname,$udom,$csec,$cgroup,'',$noeditgrp);
             }              }
             $r->print(&Apache::loncommon::end_data_table()              $r->print(&Apache::loncommon::end_data_table()
                      .'</p>'                       .'</p>'
Line 2776  ENDMAPONE Line 3346  ENDMAPONE
     $r->print(&Apache::loncommon::end_page());      $r->print(&Apache::loncommon::end_page());
 } # end sub assessparms  } # end sub assessparms
   
   
   
 ##################################################  ##################################################
 # Overview mode  # OVERVIEW MODE
 ##################################################  ##################################################
 my $tableopen;  my $tableopen;
   
 sub tablestart {  sub tablestart {
       my ($readonly) = @_;
     if ($tableopen) {      if ($tableopen) {
     return '';          return '';
     } else {      } else {
     $tableopen=1;          $tableopen=1;
     return &Apache::loncommon::start_data_table().'<tr><th>'.&mt('Parameter').'</th><th>'.          my $output = &Apache::loncommon::start_data_table().'<tr><th>'.&mt('Parameter').'</th>';
         &mt('Delete').'</th><th>'.&mt('Set to ...').'</th></tr>';          if ($readonly) {
               $output .= '<th>'.&mt('Current value').'</th>';
           } else {
               $output .= '<th>'.&mt('Delete').'</th><th>'.&mt('Set to ...').'</th>';
           }
           $output .= '</tr>';
           return $output;
     }      }
 }  }
   
 sub tableend {  sub tableend {
     if ($tableopen) {      if ($tableopen) {
     $tableopen=0;          $tableopen=0;
     return &Apache::loncommon::end_data_table();          return &Apache::loncommon::end_data_table();
     } else {      } else {
     return'';          return'';
     }      }
 }  }
   
Line 2807  sub readdata { Line 3386  sub readdata {
 # Read userdata  # Read userdata
   
     my $classlist=&Apache::loncoursedata::get_classlist();      my $classlist=&Apache::loncoursedata::get_classlist();
     foreach (keys %$classlist) {      foreach my $user (keys(%$classlist)) {
         if ($_=~/^($match_username)\:($match_domain)$/) {          if ($user=~/^($match_username)\:($match_domain)$/) {
         my ($tuname,$tudom)=($1,$2);              my ($tuname,$tudom)=($1,$2);
         my $useropt=&Apache::lonnet::get_userresdata($tuname,$tudom);              my $useropt=&Apache::lonnet::get_userresdata($tuname,$tudom);
             foreach my $userkey (keys %{$useropt}) {              foreach my $userkey (keys(%{$useropt})) {
         if ($userkey=~/^$env{'request.course.id'}/) {                  if ($userkey=~/^\Q$env{'request.course.id'}\E/) {
                     my $newkey=$userkey;                      my $newkey=$userkey;
             $newkey=~s/^($env{'request.course.id'}\.)/$1\[useropt\:$tuname\:$tudom\]\./;                      $newkey=~s/^($env{'request.course.id'}\.)/$1\[useropt\:$tuname\:$tudom\]\./;
             $$resourcedata{$newkey}=$$useropt{$userkey};                      $$resourcedata{$newkey}=$$useropt{$userkey};
         }                  }
               }
         }          }
     }      }
       if (wantarray) {
           return ($resourcedata,$classlist);
       } else {
           return $resourcedata;
     }      }
     return $resourcedata;  
 }  }
   
   
Line 2836  sub storedata { Line 3419  sub storedata {
     my @deldata=();      my @deldata=();
     undef @deldata;      undef @deldata;
     my ($got_chostname,$chostname,$cmajor,$cminor);      my ($got_chostname,$chostname,$cmajor,$cminor);
     foreach my $key (keys(%env)) {       my $now = time;
     if ($key =~ /^form\.([a-z]+)\_(.+)$/) {      foreach my $key (keys(%env)) {
         my $cmd=$1;          if ($key =~ /^form\.([a-z]+)\_(.+)$/) {
         my $thiskey=$2;              my $cmd=$1;
         my ($tuname,$tudom)=&extractuser($thiskey);              my $thiskey=$2;
         my $tkey=$thiskey;              next if ($cmd eq 'settext' || $cmd eq 'setipallow' || $cmd eq 'setipdeny');
               my ($tuname,$tudom)=&extractuser($thiskey);
               my $tkey=$thiskey;
             if ($tuname) {              if ($tuname) {
         $tkey=~s/\.\[useropt\:$tuname\:$tudom\]\./\./;                  $tkey=~s/\.\[useropt\:$tuname\:$tudom\]\./\./;
         }              }
         if ($cmd eq 'set' || $cmd eq 'datepointer' || $cmd eq 'dateinterval') {              if ($cmd eq 'set' || $cmd eq 'datepointer' || $cmd eq 'dateinterval') {
         my ($data, $typeof, $text, $name);              my ($data, $typeof, $text, $name, $valchk, $valmatch, $namematch);
         if ($cmd eq 'set') {              if ($cmd eq 'set') {
             $data=$env{$key};                  $data=$env{$key};
             $typeof=$env{'form.typeof_'.$thiskey};                  $valmatch = '';
             $text = &mt('Saved modified parameter for');                  $valchk = $data;
             if ($typeof eq 'string_questiontype') {                  $typeof=$env{'form.typeof_'.$thiskey};
                 $name = 'type';                  $text = &mt('Saved modified parameter for');
             } elsif ($typeof eq 'string_lenient') {                  if ($typeof eq 'string_questiontype') {
                 $name = 'lenient';                      $name = 'type';
             } elsif ($typeof eq 'string_discussvote') {                  } elsif ($typeof eq 'string_lenient') {
                 $name = 'discussvote';                      $name = 'lenient';
             } elsif ($typeof eq 'string_examcode') {                      my $stringmatch = &standard_string_matches($typeof);
                 $name = 'examcode';                       if (ref($stringmatch) eq 'ARRAY') {
             } elsif ($typeof eq 'string_yesno') {                          foreach my $item (@{$stringmatch}) {
                 if ($thiskey =~ /\.retrypartial$/) {                              if (ref($item) eq 'ARRAY') {
                     $name = 'retrypartial';                                  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 '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;
                                       }
                                   }
                               }
                           }
                       }
                   }
                   $typeof=$env{'form.typeof_'.$thiskey};
                   $text = &mt('Saved modified date for');
             }              }
             if ($name ne '') {              if ($thiskey =~ m{\.(?:sequence|page)___\(rec\)}) {
                   $namematch = 'maplevelrecurse';
               }
               if (($name ne '') || ($namematch ne '')) {
                 my ($needsrelease,$needsnewer);                  my ($needsrelease,$needsnewer);
                 $needsrelease = $Apache::lonnet::needsrelease{"parameter:$name:$data"};                  if ($name ne '') {
                 if ($needsrelease) {                      $needsrelease = $Apache::lonnet::needsrelease{"parameter:$name:$valchk:$valmatch:"};
                     unless ($got_chostname) {                      if ($needsrelease) {
                         ($chostname,$cmajor,$cminor)=&parameter_release_vars();                          unless ($got_chostname) {
                         $got_chostname = 1;                              ($chostname,$cmajor,$cminor)=&parameter_release_vars();
                               $got_chostname = 1;
                           }
                           $needsnewer = &parameter_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) = &parameter_release_vars();
                                   $got_chostname = 1;
                               }
                               $needsnewer = &parameter_releasecheck(undef,$valchk,$valmatch,$namematch,
                                                                   $needsrelease,$cmajor,$cminor);
                           } else {
                               undef($namematch);
                           }
                     }                      }
                     $needsnewer = &parameter_releasecheck($name,$data,  
                                                           $needsrelease,  
                                                           $cmajor,$cminor);  
                 }                  }
                 if ($needsnewer) {                  if ($needsnewer) {
                     $r->print('<br />'.&oldversion_warning($name,$data,                      $r->print('<br />'.&oldversion_warning($name,$namematch,$data,
                                                            $chostname,$cmajor,                                                          $chostname,$cmajor,
                                                            $cminor,$needsrelease));                                                          $cminor,$needsrelease));
                     next;                      next;
                 }                  }
             }              }
         } elsif ($cmd eq 'datepointer') {              if (defined($data) and $$olddata{$thiskey} ne $data) {
             $data=&Apache::lonhtmlcommon::get_date_from_form($env{$key});                  if ($tuname) {
             $typeof=$env{'form.typeof_'.$thiskey};                      if (&Apache::lonnet::put('resourcedata',{$tkey=>$data,
             $text = &mt('Saved modified date for');                                          $tkey.'.type' => $typeof},
         } elsif ($cmd eq 'dateinterval') {                                  $tudom,$tuname) eq 'ok') {
             $data=&get_date_interval_from_form($thiskey);                          &log_parmset({$tkey=>$data,$tkey.'.type' => $typeof},0,$tuname,$tudom);
             $typeof=$env{'form.typeof_'.$thiskey};                          $r->print('<br />'.$text.' '.
             $text = &mt('Saved modified date for');                              &Apache::loncommon::plainname($tuname,$tudom));
         }                      } else {
         if (defined($data) and $$olddata{$thiskey} ne $data) {                          $r->print('<div class="LC_error">'.
             if ($tuname) {                              &mt('Error saving parameters').'</div>');
             if (&Apache::lonnet::put('resourcedata',{$tkey=>$data,                      }
                                  $tkey.'.type' => $typeof},                      &Apache::lonnet::devalidateuserresdata($tuname,$tudom);
                          $tudom,$tuname) eq 'ok') {                  } else {
                 &log_parmset({$tkey=>$data,$tkey.'.type' => $typeof},0,$tuname,$tudom);                      $newdata{$thiskey}=$data;
                 $r->print('<br />'.$text.' '.                      $newdata{$thiskey.'.type'}=$typeof;
                       &Apache::loncommon::plainname($tuname,$tudom));                  }
             } else {  
                 $r->print('<div class="LC_error">'.  
                       &mt('Error saving parameters').'</div>');  
             }              }
             &Apache::lonnet::devalidateuserresdata($tuname,$tudom);              } elsif ($cmd eq 'del') {
             } else {                  if ($tuname) {
             $newdata{$thiskey}=$data;                      if (&Apache::lonnet::del('resourcedata',[$tkey],$tudom,$tuname) eq 'ok') {
              $newdata{$thiskey.'.type'}=$typeof;                              &log_parmset({$tkey=>''},1,$tuname,$tudom);
                    }                          $r->print('<br />'.&mt('Deleted parameter for').' '.&Apache::loncommon::plainname($tuname,$tudom));
         }                      } else {
         } elsif ($cmd eq 'del') {                          $r->print('<div class="LC_error">'.
         if ($tuname) {                              &mt('Error deleting parameters').'</div>');
             if (&Apache::lonnet::del('resourcedata',[$tkey],$tudom,$tuname) eq 'ok') {                      }
                 &log_parmset({$tkey=>''},1,$tuname,$tudom);                      &Apache::lonnet::devalidateuserresdata($tuname,$tudom);
             $r->print('<br />'.&mt('Deleted parameter for').' '.&Apache::loncommon::plainname($tuname,$tudom));                  } else {
             } else {                      push (@deldata,$thiskey,$thiskey.'.type');
             $r->print('<div class="LC_error">'.                  }
                   &mt('Error deleting parameters').'</div>');  
             }              }
             &Apache::lonnet::devalidateuserresdata($tuname,$tudom);  
         } else {  
             push (@deldata,$thiskey,$thiskey.'.type');  
         }          }
         }  
     }  
     }      }
 # Store all course level  # Store all course level
     my $delentries=$#deldata+1;      my $delentries=$#deldata+1;
     my @newdatakeys=keys %newdata;      my @newdatakeys=keys(%newdata);
     my $putentries=$#newdatakeys+1;      my $putentries=$#newdatakeys+1;
     if ($delentries) {      if ($delentries) {
     if (&Apache::lonnet::del('resourcedata',\@deldata,$dom,$crs) eq 'ok') {          if (&Apache::lonnet::del('resourcedata',\@deldata,$dom,$crs) eq 'ok') {
         my %loghash=map { $_ => '' } @deldata;              my %loghash=map { $_ => '' } @deldata;
         &log_parmset(\%loghash,1);              &log_parmset(\%loghash,1);
         $r->print('<h2>'.&mt('Deleted [_1] parameter(s)',$delentries).'</h2>');              $r->print('<h2>'.&mt('Deleted [quant,_1,parameter]',$delentries/2).'</h2>');
     } else {          } else {
         $r->print('<div class="LC_error">'.              $r->print('<div class="LC_error">'.
               &mt('Error deleting parameters').'</div>');                  &mt('Error deleting parameters').'</div>');
     }          }
     &Apache::lonnet::devalidatecourseresdata($crs,$dom);          &Apache::lonnet::devalidatecourseresdata($crs,$dom);
     }      }
     if ($putentries) {      if ($putentries) {
     if (&Apache::lonnet::put('resourcedata',\%newdata,$dom,$crs) eq 'ok') {          if (&Apache::lonnet::put('resourcedata',\%newdata,$dom,$crs) eq 'ok') {
                 &log_parmset(\%newdata,0);                      &log_parmset(\%newdata,0);
         $r->print('<h3>'.&mt('Saved [_1] parameter(s)',$putentries/2).'</h3>');              $r->print('<h3>'.&mt('Saved [quant,_1,parameter]',$putentries/2).'</h3>');
     } else {          } else {
         $r->print('<div class="LC_error">'.              $r->print('<div class="LC_error">'.
               &mt('Error saving parameters').'</div>');                  &mt('Error saving parameters').'</div>');
     }          }
     &Apache::lonnet::devalidatecourseresdata($crs,$dom);          &Apache::lonnet::devalidatecourseresdata($crs,$dom);
     }      }
 }  }
   
Line 2966  sub parse_listdata_key { Line 3632  sub parse_listdata_key {
     ($key=~/^\Q$env{'request.course.id'}\E\.\[([^\.]+)\]\.(.+)$/);      ($key=~/^\Q$env{'request.course.id'}\E\.\[([^\.]+)\]\.(.+)$/);
     # if course wide student would be undefined      # if course wide student would be undefined
     if (!defined($student)) {      if (!defined($student)) {
     ($realm)=($key=~/^\Q$env{'request.course.id'}\E\.(.+)$/);          ($realm)=($key=~/^\Q$env{'request.course.id'}\E\.(.+)$/);
     }      }
     # strip off the .type if it's not the Question type parameter      # strip off the .type if it's not the Question type parameter
     if ($realm=~/\.type$/ && !exists($listdata->{$key.'.type'})) {      if ($realm=~/\.type$/ && !exists($listdata->{$key.'.type'})) {
     $realm=~s/\.type//;          $realm=~s/\.type//;
     }      }
     # split into resource+part and parameter name      # split into resource+part and parameter name
     my ($res,    $parm) = ($realm=~/^(.*)\.(.*)$/);      my ($res,    $parm) = ($realm=~/^(.*)\.(.*)$/);
Line 2978  sub parse_listdata_key { Line 3644  sub parse_listdata_key {
     return ($student,$res,$part,$parm);      return ($student,$res,$part,$parm);
 }  }
   
   # Displays forms for the given data in overview mode (newoverview or overview).
 sub listdata {  sub listdata {
     my ($r,$resourcedata,$listdata,$sortorder)=@_;      my ($r,$resourcedata,$listdata,$sortorder,$caller,$classlist)=@_;
       
 # Start list output  # Start list output
   
     my $oldsection='';      my $oldsection='';
Line 2990  sub listdata { Line 3658  sub listdata {
     my $foundkeys=0;      my $foundkeys=0;
     my %keyorder=&standardkeyorder();      my %keyorder=&standardkeyorder();
   
       my ($secidx,%grouphash);
       if (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {
           $secidx = &Apache::loncoursedata::CL_SECTION();
           if (&Apache::lonnet::allowed('mdg',$env{'request.course.id'})) {
               %grouphash = &Apache::longroup::coursegroups();
           } elsif ($env{'request.course.groups'} ne '') {
               map { $grouphash{$_} = 1; } split(/,/,$env{'request.course.groups'});
           }
       }
   
     foreach my $thiskey (sort {      foreach my $thiskey (sort {
     my ($astudent,$ares,$apart,$aparm) = &parse_listdata_key($a,$listdata);          my ($astudent,$ares,$apart,$aparm) = &parse_listdata_key($a,$listdata);
     my ($bstudent,$bres,$bpart,$bparm) = &parse_listdata_key($b,$listdata);          my ($bstudent,$bres,$bpart,$bparm) = &parse_listdata_key($b,$listdata);
   
     # get the numerical order for the param          # get the numerical order for the param
     $aparm=$keyorder{'parameter_0_'.$aparm};          $aparm=$keyorder{'parameter_0_'.$aparm};
     $bparm=$keyorder{'parameter_0_'.$bparm};          $bparm=$keyorder{'parameter_0_'.$bparm};
   
     my $result=0;          my $result=0;
   
     if ($sortorder eq 'realmstudent') {          if ($sortorder eq 'realmstudent') {
             if ($ares     ne $bres    ) {              if ($ares     ne $bres    ) {
         $result = ($ares     cmp $bres);                  $result = ($ares     cmp $bres);
             } elsif ($astudent ne $bstudent) {              } elsif ($astudent ne $bstudent) {
         $result = ($astudent cmp $bstudent);                  $result = ($astudent cmp $bstudent);
         } elsif ($apart    ne $bpart   ) {              } elsif ($apart    ne $bpart   ) {
         $result = ($apart    cmp $bpart);                  $result = ($apart    cmp $bpart);
         }              }
     } else {          } else {
         if      ($astudent ne $bstudent) {              if      ($astudent ne $bstudent) {
         $result = ($astudent cmp $bstudent);                  $result = ($astudent cmp $bstudent);
         } elsif ($ares     ne $bres    ) {              } elsif ($ares     ne $bres    ) {
         $result = ($ares     cmp $bres);                  $result = ($ares     cmp $bres);
         } elsif ($apart    ne $bpart   ) {              } elsif ($apart    ne $bpart   ) {
         $result = ($apart    cmp $bpart);                  $result = ($apart    cmp $bpart);
               }
         }          }
     }  
   
     if (!$result) {          if (!$result) {
             if (defined($aparm) && defined($bparm)) {              if (defined($aparm) && defined($bparm)) {
         $result = ($aparm <=> $bparm);                  $result = ($aparm <=> $bparm);
             } elsif (defined($aparm)) {              } elsif (defined($aparm)) {
         $result = -1;                  $result = -1;
             } elsif (defined($bparm)) {              } elsif (defined($bparm)) {
         $result = 1;                  $result = 1;
               }
         }          }
     }  
   
     $result;          $result;
     } keys %{$listdata}) {          
       } keys(%{$listdata})) { # foreach my $thiskey
   
     if ($$listdata{$thiskey.'.type'}) {          my $readonly;
           if ($$listdata{$thiskey.'.type'}) {
             my $thistype=$$listdata{$thiskey.'.type'};              my $thistype=$$listdata{$thiskey.'.type'};
             if ($$resourcedata{$thiskey.'.type'}) {              if ($$resourcedata{$thiskey.'.type'}) {
         $thistype=$$resourcedata{$thiskey.'.type'};                  $thistype=$$resourcedata{$thiskey.'.type'};
         }              }
         my ($middle,$part,$name)=              my ($middle,$part,$name)=
         ($thiskey=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s]+)\.(\w+)$/);                  ($thiskey=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s]+)\.(\w+)$/);
         my $section=&mt('All Students');              my $section=&mt('All Students');
         if ($middle=~/^\[(.*)\]/) {              if ($middle=~/^\[(.*)\]/) {
         my $issection=$1;                  my $issection=$1;
         if ($issection=~/^useropt\:($match_username)\:($match_domain)/) {                  if ($issection=~/^useropt\:($match_username)\:($match_domain)/) {
             $section=&mt('User').": ".&Apache::loncommon::plainname($1,$2);                      my ($stuname,$studom) = ($1,$2);
         } else {                      if (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {
             $section=&mt('Group/Section').': '.$issection;                          if (ref($classlist) eq 'HASH') {
         }                              if (ref($classlist->{$stuname.':'.$studom}) eq 'ARRAY') {
         $middle=~s/^\[(.*)\]//;                                  next unless ($classlist->{$stuname.':'.$studom}->[$secidx] eq $env{'request.course.sec'}); 
         }                              }
         $middle=~s/\.+$//;                          }
         $middle=~s/^\.+//;                      }
         my $realm='<span class="LC_parm_scope_all">'.&mt('All Resources').'</span>';                      $section=&mt('User').": ".&Apache::loncommon::plainname($stuname,$studom);
         if ($middle=~/^(.+)\_\_\_\(all\)$/) {                  } else {
         $realm='<span class="LC_parm_scope_folder">'.&mt('Folder/Map').': '.&Apache::lonnet::gettitle($1).' <br /><span class="LC_parm_folder">('.$1.')</span></span>';                      if (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {
         } elsif ($middle) {                          if (exists($grouphash{$issection})) {
         my ($map,$id,$url)=&Apache::lonnet::decode_symb($middle);                              $section=&mt('Group').': '.$issection;
         $realm='<span class="LC_parm_scope_resource">'.&mt('Resource').': '.&Apache::lonnet::gettitle($middle).' <br /><span class="LC_parm_symb">('.$url.' in '.$map.' id: '.$id.')</span></span>';                          } elsif ($issection eq $env{'request.course.sec'}) {
         }                              $section = &mt('Section').': '.$issection;
         if ($sortorder eq 'realmstudent') {                          } else {
         if ($realm ne $oldrealm) {                              next; 
             $r->print(&tableend()."\n<hr /><h1>$realm</h1>");                          }
             $oldrealm=$realm;                      } else {
             $oldsection='';                          $section=&mt('Group/Section').': '.$issection;
         }                      }
         if ($section ne $oldsection) {                  }
             $r->print(&tableend()."\n<h2>$section</h2>");                  $middle=~s/^\[(.*)\]//;
             $oldsection=$section;              } elsif (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {
             $oldpart='';                  $readonly = 1;
         }              }
         } else {              $middle=~s/\.+$//;
         if ($section ne $oldsection) {              $middle=~s/^\.+//;
             $r->print(&tableend()."\n<hr /><h1>$section</h1>");              my $realm='<span class="LC_parm_scope_all">'.&mt('All Resources').'</span>';
             $oldsection=$section;              if ($middle=~/^(.+)\_\_\_\((all|rec)\)$/) {
             $oldrealm='';                  my $mapurl = $1;
         }                  my $maplevel = $2;
         if ($realm ne $oldrealm) {                  my $leveltitle = &mt('Folder/Map');
             $r->print(&tableend()."\n<h2>$realm</h2>");                  if ($maplevel eq 'rec') {
             $oldrealm=$realm;                      $leveltitle = &mt('Recursive');
             $oldpart='';                  }
         }                  $realm='<span class="LC_parm_scope_folder">'.$leveltitle.': '.&Apache::lonnet::gettitle($mapurl).' <br /><span class="LC_parm_folder">('.$mapurl.')</span></span>';
         }              } elsif ($middle) {
         if ($part ne $oldpart) {                  my ($map,$id,$url)=&Apache::lonnet::decode_symb($middle);
         $r->print(&tableend().                  $realm='<span class="LC_parm_scope_resource">'.&mt('Resource').
               "\n".'<span class="LC_parm_part">'.&mt('Part').": $part</span>");                      ': '.&Apache::lonnet::gettitle($middle).
         $oldpart=$part;                      ' <br /><span class="LC_parm_symb">('.$url.' in '.$map.' id: '.
         }                      $id.')</span></span>';
 #              }
 # Ready to print              if ($sortorder eq 'realmstudent') {
 #                  if ($realm ne $oldrealm) {
                       $r->print(&tableend()."\n<hr /><h1>$realm</h1>");
                       $oldrealm=$realm;
                       $oldsection='';
                   }
                   if ($section ne $oldsection) {
                       $r->print(&tableend()."\n<h2>$section</h2>");
                       $oldsection=$section;
                       $oldpart='';
                   }
               } else {
                   if ($section ne $oldsection) {
                       $r->print(&tableend()."\n<hr /><h1>$section</h1>");
                       $oldsection=$section;
                       $oldrealm='';
                   }
                   if ($realm ne $oldrealm) {
                       $r->print(&tableend()."\n<h2>$realm</h2>");
                       $oldrealm=$realm;
                       $oldpart='';
                   }
               }
               if ($part ne $oldpart) {
                   $r->print(&tableend().
                       "\n".'<span class="LC_parm_part">'.&mt('Part').": $part</span>");
                   $oldpart=$part;
               }
       #
       # Ready to print
       #
             my $parmitem = &standard_parameter_names($name);              my $parmitem = &standard_parameter_names($name);
         $r->print(&tablestart().              $r->print(&tablestart($readonly).
               &Apache::loncommon::start_data_table_row().                  &Apache::loncommon::start_data_table_row().
               '<td><b>'.&mt($parmitem).                  '<td><b>'.&mt($parmitem).
               '</b></td><td><input type="checkbox" name="del_'.                  '</b></td>');
               $thiskey.'" /></td><td>');              unless ($readonly) {
         $foundkeys++;                  $r->print('<td><input type="checkbox" name="del_'.
         if (&isdateparm($thistype)) {                          $thiskey.'" /></td>');
         my $jskey='key_'.$pointer;              }
         $pointer++;              $r->print('<td>');
         $r->print(              $foundkeys++;
               &Apache::lonhtmlcommon::date_setter('parmform',              if (&isdateparm($thistype)) {
                                   $jskey,                  my $jskey='key_'.$pointer;
                               $$resourcedata{$thiskey},                  my $state;
                                   '',1,'','').                  $pointer++;
 '<input type="hidden" name="datepointer_'.$thiskey.'" value="'.$jskey.'" />'.                  if ($readonly) {
 (($$resourcedata{$thiskey}!=0)?'<span class="LC_nobreak"><a href="/adm/parmset?&action=dateshift1&timebase='.$$resourcedata{$thiskey}.'">'.                      $state = 'disabled';
 &mt('Shift all dates based on this date').'</a></span>':'').                  }
 &date_sanity_info($$resourcedata{$thiskey})                  $r->print(
               );                      &Apache::lonhtmlcommon::date_setter('parmform',
         } elsif ($thistype eq 'date_interval') {                                                          $jskey,
         $r->print(&date_interval_selector($thiskey,                                                          $$resourcedata{$thiskey},
                           $$resourcedata{$thiskey}));                                                          '',1,$state));
         } elsif ($thistype =~ m/^string/) {                  unless  ($readonly) {
         $r->print(&string_selector($thistype,$thiskey,                      $r->print(
                        $$resourcedata{$thiskey},$name));      '<input type="hidden" name="datepointer_'.$thiskey.'" value="'.$jskey.'" />'.
         } else {      (($$resourcedata{$thiskey}!=0)?'<span class="LC_nobreak"><a href="/adm/parmset?&action=dateshift1&timebase='.$$resourcedata{$thiskey}.'">'.
         $r->print(&default_selector($thiskey,$$resourcedata{$thiskey}));      &mt('Shift all dates based on this date').'</a></span>':'').
       &date_sanity_info($$resourcedata{$thiskey})
                       );
                   }
               } elsif ($thistype eq 'date_interval') {
                   $r->print(&date_interval_selector($thiskey,$name,
                           $$resourcedata{$thiskey},$readonly));
               } elsif ($thistype =~ m/^string/) {
                   $r->print(&string_selector($thistype,$thiskey,
                           $$resourcedata{$thiskey},$name,$readonly));
               } else {
                   $r->print(&default_selector($thiskey,$$resourcedata{$thiskey},$readonly));
               }
               unless ($readonly) {
                   $r->print('<input type="hidden" name="typeof_'.$thiskey.'" value="'.
                           $thistype.'" />');
               }
               $r->print('</td>'.&Apache::loncommon::end_data_table_row());
         }          }
         $r->print('<input type="hidden" name="typeof_'.$thiskey.'" value="'.  
               $thistype.'" />');  
         $r->print('</td>'.&Apache::loncommon::end_data_table_row());  
     }  
     }      }
     return $foundkeys;      return $foundkeys;
 }  }
   
   
 sub date_interval_selector {  
     my ($thiskey, $showval) = @_;  
     my $result;  
     foreach my $which (['days', 86400, 31],  
                ['hours', 3600, 23],  
                ['minutes', 60, 59],  
                ['seconds',  1, 59]) {  
     my ($name, $factor, $max) = @{ $which };  
     my $amount = int($showval/$factor);  
     $showval  %= $factor;  
     my %select = ((map {$_ => $_} (0..$max)),  
               'select_form_order' => [0..$max]);  
     $result .= &Apache::loncommon::select_form($amount,$name.'_'.$thiskey,  
                            \%select);  
     $result .= ' '.&mt($name);  
     }  
     $result .= '<input type="hidden" name="dateinterval_'.$thiskey.'" />';  
     return $result;  
   
 }  
   
 sub get_date_interval_from_form {  sub get_date_interval_from_form {
     my ($key) = @_;      my ($key) = @_;
     my $seconds = 0;      my $seconds = 0;
Line 3154  sub get_date_interval_from_form { Line 3854  sub get_date_interval_from_form {
                ['hours', 3600],                 ['hours', 3600],
                ['minutes', 60],                 ['minutes', 60],
                ['seconds',  1]) {                 ['seconds',  1]) {
     my ($name, $factor) = @{ $which };          my ($name, $factor) = @{ $which };
     if (defined($env{'form.'.$name.'_'.$key})) {          if (defined($env{'form.'.$name.'_'.$key})) {
         $seconds += $env{'form.'.$name.'_'.$key} * $factor;              $seconds += $env{'form.'.$name.'_'.$key} * $factor;
           }
     }      }
       if (($key =~ /\.interval$/) &&
               (($env{'form.done_'.$key} eq '_done') || ($env{'form.done_'.$key} eq '_done_proctor'))) {
           if ($env{'form.done_'.$key.'_buttontext'}) {
               $env{'form.done_'.$key.'_buttontext'} =~ s/\://g;
               $seconds .= '_done:'.$env{'form.done_'.$key.'_buttontext'}.':';
               if ($env{'form.done_'.$key} eq '_done_proctor') {
                   $seconds .= '_proctor';
               }
           } else {
               $seconds .= $env{'form.done_'.$key}; 
           }
           if (($env{'form.done_'.$key} eq '_done_proctor') && 
                   ($env{'form.done_'.$key.'_proctorkey'})) {
               $seconds .= '_'.$env{'form.done_'.$key.'_proctorkey'};
           }
     }      }
     return $seconds;      return $seconds;
 }  }
   
   
 sub default_selector {  sub default_selector {
     my ($thiskey, $showval) = @_;      my ($thiskey, $showval, $readonly) = @_;
     return '<input type="text" name="set_'.$thiskey.'" value="'.$showval.'" />';      my $disabled;
       if ($readonly) {
           $disabled = ' disabled="disabled"';
       }
       return '<input type="text" name="set_'.$thiskey.'" value="'.$showval.'"'.$disabled.' />';
   }
   
   sub string_ip_selector {
       my ($thiskey, $showval, $readonly) = @_;
       my %access = (
                      allow => [],
                      deny  => [],
                    );
       if ($showval ne '') {
           my @current;
           if ($showval =~ /,/) {
               @current = split(/,/,$showval);
           } else {
               @current = ($showval);
           }
           foreach my $item (@current) {
               if ($item =~ /^\!([\[\]a-zA-Z\.\d\*\-]+)$/) {
                   push(@{$access{'deny'}},$1);
               } elsif ($item =~ /^([\[\]a-zA-Z\.\d\*\-]+)$/) {
                   push(@{$access{'allow'}},$item);
               }
           }
       }
       if (!@{$access{'allow'}}) {
           @{$access{'allow'}} = ('');
       }
       if (!@{$access{'deny'}}) {
           @{$access{'deny'}} = ('');
       }
       my ($disabled,$addmore);
       if ($disabled) {
           $disabled=' disabled="disabled"';
       } else {
           $addmore = "\n".'<button class="LC_add_ipacc_button">'.&mt('Add more').'</button>';
       }
       my $output = '<input type="hidden" name="set_'.$thiskey.'" />
   <table><tr><th>'.&mt('Allow from').'</th><th>'.&mt('Deny from').'</th></tr><tr>';
       foreach my $acctype ('allow','deny') {
           $output .= '
   <td valign="top">
   <div class="LC_string_ipacc_wrap" id="LC_string_ipacc_'.$acctype.'_'.$thiskey.'">
     <div class="LC_string_ipacc_inner">'."\n";
           my $num = 0;
           foreach my $curr (@{$access{$acctype}}) {
               $output .= '<div><input type="text" name="setip'.$acctype.'_'.$thiskey.'" value="'.$curr.'"'.$disabled.' />';
               if ($num > 0) {
                   $output .= '<a href="#" class="LC_remove_ipacc">'.&mt('Remove').'</a>'; 
               }
               $output .= '</div>'."\n";
               $num ++;
           }
           $output .= '
     </div>'.$addmore.'
   </div>
   </td>';
      }
      $output .= '
   </tr>
   </table>'."\n";
       return $output;
 }  }
   
   
   { # block using some constants related to parameter types (overview mode)
   
 my %strings =  my %strings =
     (      (
      'string_yesno'       'string_yesno'
              => [[ 'yes', 'Yes' ],               => [[ 'yes', 'Yes' ],
          [ 'no', 'No' ]],                   [ 'no', 'No' ]],
      'string_problemstatus'       'string_problemstatus'
              => [[ 'yes', 'Yes' ],               => [[ 'yes', 'Yes' ],
          [ 'answer', 'Yes, and show correct answer if they exceed the maximum number of tries.' ],           [ 'answer', 'Yes, and show correct answer if they exceed the maximum number of tries.' ],
Line 3190  my %strings = Line 3973  my %strings =
      'string_lenient'       'string_lenient'
              => [['yes', 'Yes' ],               => [['yes', 'Yes' ],
                  [ 'no', 'No' ],                   [ 'no', 'No' ],
                  [ 'default', 'Default - only bubblesheet grading is lenient' ]],                   [ 'default', 'Default - only bubblesheet grading is lenient' ],
                    [ 'weighted', 'Yes, weighted (optionresponse in checkbox mode)' ]],
      'string_discussvote'       'string_discussvote'
              => [['yes','Yes'],               => [['yes','Yes'],
                  ['notended','Yes, unless discussion ended'],                   ['notended','Yes, unless discussion ended'],
                  ['no','No']],                   ['no','No']],
        'string_ip'
                => [['_allowfrom_','Hostname(s), or IP(s) from which access is allowed'],
                    ['_denyfrom_',], 'Hostname(s) or IP(s) from which access is disallowed'], 
      );       );
   
   my %stringmatches = (
            'string_lenient'
                 => [['weighted','^\-?[.\d]+,\-?[.\d]+,\-?[.\d]+,\-?[.\d]+$'],],
            'string_ip'
                 => [['_allowfrom_','[^\!]+'],
                     ['_denyfrom_','\!']],
       );
   
   my %stringtypes = (
                       type         => 'string_questiontype',
                       lenient      => 'string_lenient',
                       retrypartial => 'string_yesno',
                       discussvote  => 'string_discussvote',
                       examcode     => 'string_examcode',
                       acc          => 'string_ip',
                     );
   
 sub standard_string_options {  sub standard_string_options {
     my ($string_type) = @_;      my ($string_type) = @_;
     if (ref($strings{$string_type}) eq 'ARRAY') {      if (ref($strings{$string_type}) eq 'ARRAY') {
Line 3205  sub standard_string_options { Line 4009  sub standard_string_options {
     return;      return;
 }  }
   
   sub standard_string_matches {
       my ($string_type) = @_;
       if (ref($stringmatches{$string_type}) eq 'ARRAY') {
           return $stringmatches{$string_type};
       }
       return;
   }
   
   sub get_stringtype {
       my ($name) = @_;
       if (exists($stringtypes{$name})) {
           return $stringtypes{$name};
       }
       return;
   }
   
 sub string_selector {  sub string_selector {
     my ($thistype, $thiskey, $showval, $name) = @_;      my ($thistype, $thiskey, $showval, $name, $readonly) = @_;
   
     if (!exists($strings{$thistype})) {      if (!exists($strings{$thistype})) {
     return &default_selector($thiskey,$showval);          return &default_selector($thiskey,$showval,$readonly);
     }      }
   
     my %skiptype;      my %skiptype;
     if (($thistype eq 'string_questiontype') ||       if (($thistype eq 'string_questiontype') || 
         ($thistype eq 'string_lenient') ||              ($thistype eq 'string_lenient') ||
         ($thistype eq 'string_discussvote') ||              ($thistype eq 'string_discussvote') ||
         ($name eq 'retrypartial')) {              ($thistype eq 'string_ip') ||
               ($name eq 'retrypartial')) {
         my ($got_chostname,$chostname,$cmajor,$cminor);           my ($got_chostname,$chostname,$cmajor,$cminor); 
         foreach my $possibilities (@{ $strings{$thistype} }) {          foreach my $possibilities (@{ $strings{$thistype} }) {
             next unless (ref($possibilities) eq 'ARRAY');              next unless (ref($possibilities) eq 'ARRAY');
             my ($parmval, $description) = @{ $possibilities };              my ($parmval, $description) = @{ $possibilities };
             my $needsrelease=$Apache::lonnet::needsrelease{"parameter:$name:$parmval"};              my $parmmatch;
               if (ref($stringmatches{$thistype}) eq 'ARRAY') {
                   foreach my $item (@{$stringmatches{$thistype}}) {
                       if (ref($item) eq 'ARRAY') {
                           if ($parmval eq $item->[0]) {
                               $parmmatch = $parmval;
                               $parmval = '';
                               last;
                           }
                       }
                   }
               }
               my $needsrelease=$Apache::lonnet::needsrelease{"parameter:$name:$parmval:$parmmatch"}; 
             if ($needsrelease) {              if ($needsrelease) {
                 unless ($got_chostname) {                  unless ($got_chostname) {
                     ($chostname,$cmajor,$cminor)=&parameter_release_vars();                      ($chostname,$cmajor,$cminor)=&parameter_release_vars();
                     $got_chostname = 1;                      $got_chostname = 1;
                 }                  }
                 my $needsnewer=&parameter_releasecheck($name,$parmval,$needsrelease,                  my $needsnewer=&parameter_releasecheck($name,$parmval,$parmmatch,undef,
                                                        $cmajor,$cminor);                                                         $needsrelease,$cmajor,$cminor);
                 if ($needsnewer) {                  if ($needsnewer) {
                     $skiptype{$parmval} = 1;                      if ($parmmatch ne '') {
                           $skiptype{$parmmatch} = 1;
                       } elsif ($parmval ne '') {
                           $skiptype{$parmval} = 1;
                       }
                 }                  }
             }              }
         }          }
     }      }
       
   
     my $result;      if ($thistype eq 'string_ip') {
           return &string_ip_selector($thiskey,$showval,$readonly); 
       }
   
       my ($result,$disabled);
   
       if ($readonly) {
           $disabled = ' disabled="disabled"';
       }
     my $numinrow = 3;      my $numinrow = 3;
     if ($thistype eq 'string_problemstatus') {      if ($thistype eq 'string_problemstatus') {
         $numinrow = 2;          $numinrow = 2;
Line 3252  sub string_selector { Line 4096  sub string_selector {
         foreach my $possibilities (@{ $strings{$thistype} }) {          foreach my $possibilities (@{ $strings{$thistype} }) {
             next unless (ref($possibilities) eq 'ARRAY');              next unless (ref($possibilities) eq 'ARRAY');
             my ($name, $description) = @{ $possibilities };              my ($name, $description) = @{ $possibilities };
             next if ($skiptype{$name});               next if ($skiptype{$name});
             $rem = $i%($numinrow);              $rem = $i%($numinrow);
             if ($rem == 0) {              if ($rem == 0) {
                 if ($i > 0) {                  if ($i > 0) {
Line 3260  sub string_selector { Line 4104  sub string_selector {
                 }                  }
                 $result .= '<tr>';                  $result .= '<tr>';
             }              }
             $result .= '<td class="LC_left_item">'.              my $colspan;
               if ($i == @{ $strings{$thistype} }-1) {
                   $rem = @{ $strings{$thistype} }%($numinrow);
                   if ($rem) {
                       my $colsleft = $numinrow - $rem;
                       if ($colsleft) {
                           $colspan = $colsleft+1;
                           $colspan = ' colspan="'.$colspan.'"';
                       }
                   }
               }
               my ($add,$onchange,$css_class);
               if ($thistype eq 'string_lenient') {
                   if ($name eq 'weighted') {
                       my $display;
                       my %relatives = &Apache::lonlocal::texthash(
                                           corrchkd     => 'Correct (checked)',
                                           corrunchkd   => 'Correct (unchecked)',
                                           incorrchkd   => 'Incorrect (checked)',
                                           incorrunchkd => 'Incorrect (unchecked)',
                       );
                       my %textval = (
                                       corrchkd     => '1.0',
                                       corrunchkd   => '1.0',
                                       incorrchkd   => '0.0',
                                       incorrunchkd => '0.0',
                       );
                       if ($showval =~ /^([\-\d\.]+)\,([\-\d\.]+)\,([\-\d\.]+)\,([\-\d\.]+)$/) {
                           $textval{'corrchkd'} = $1;
                           $textval{'corrunchkd'} = $2;
                           $textval{'incorrchkd'} = $3;
                           $textval{'incorrunchkd'} = $4;
                           $display = 'inline';
                           $showval = $name;
                       } else {
                           $display = 'none';
                       }
                       $add = ' <div id="LC_parmtext_'.$thiskey.'" style="display:'.$display.'"><table>'.
                              '<tr><th colspan="2">'.&mt("Foil's submission status").'</th><th>'.&mt('Points').'</th></tr>';  
                       foreach my $reltype ('corrchkd','corrunchkd','incorrchkd','incorrunchkd') {
                           $add .= '<tr><td>&nbsp;</td><td>'.$relatives{$reltype}.'</td>'."\n".
                                   '<td><input type="text" name="settext_'.$thiskey.'"'.
                                   ' value="'.$textval{$reltype}.'" size="3"'.$disabled.' />'.
                                   '</td></tr>';
                       }
                       $add .= '</table></div>'."\n";
                   }
                   $onchange = ' onclick="javascript:toggleParmTextbox(this.form,'."'$thiskey'".');"';
                   $css_class = ' class="LC_lenient_radio"';
               }
               $result .= '<td class="LC_left_item"'.$colspan.'>'.
                        '<span class="LC_nobreak"><label>'.                         '<span class="LC_nobreak"><label>'.
                        '<input type="radio" name="set_'.$thiskey.                         '<input type="radio" name="set_'.$thiskey.
                        '" value="'.$name.'"';                         '" value="'.$name.'"'.$onchange.$css_class.$disabled;
             if ($showval eq $name) {              if ($showval eq $name) {
                 $result .= ' checked="checked"';                  $result .= ' checked="checked"';
             }              }
             $result .= ' />'.&mt($description).'</label></span></td>';              $result .= ' />'.&mt($description).'</label>'.$add.'</span></td>';
             $i++;              $i++;
         }          }
         $rem = @{ $strings{$thistype} }%($numinrow);  
         my $colsleft = $numinrow - $rem;  
         if ($colsleft > 1 ) {  
             $result .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.  
                        '&nbsp;</td>';  
         } elsif ($colsleft == 1) {  
             $result .= '<td class="LC_left_item">&nbsp;</td>';  
         }  
         $result .= '</tr>';          $result .= '</tr>';
     }      }
     if ($result) {      if ($result) {
Line 3286  sub string_selector { Line 4172  sub string_selector {
     return $result;      return $result;
 }  }
   
   my %intervals =
       (
        'date_interval'
                => [[ 'done', 'Yes' ],
                    [ 'done_proctor', 'Yes, with proctor key'],                  
                    [ '', 'No' ]],
       );
   
   my %intervalmatches = (
            'date_interval'
                 => [['done','\d+_done(|\:[^\:]+\:)$'],
                     ['done_proctor','\d+_done(|\:[^\:]+\:)_proctor_']],
       );
   
   my %intervaltypes = (
                         interval => 'date_interval',
       );
   
   sub standard_interval_matches {
       my ($interval_type) = @_;
       if (ref($intervalmatches{$interval_type}) eq 'ARRAY') {
           return $intervalmatches{$interval_type};
       }
       return;
   }
   
   sub get_intervaltype {
       my ($name) = @_;
       if (exists($intervaltypes{$name})) {
           return $intervaltypes{$name};
       }
       return;
   }
   
   sub standard_interval_options {
       my ($interval_type) = @_;
       if (ref($intervals{$interval_type}) eq 'ARRAY') {
           return $intervals{$interval_type};
       }
       return;
   }
   
   sub date_interval_selector {
       my ($thiskey, $name, $showval, $readonly) = @_;
       my ($result,%skipval);
       if ($name eq 'interval') {
           my $intervaltype = &get_intervaltype($name);
           my ($got_chostname,$chostname,$cmajor,$cminor);
           foreach my $possibilities (@{ $intervals{$intervaltype} }) {
               next unless (ref($possibilities) eq 'ARRAY');
               my ($parmval, $description) = @{ $possibilities };
               my $parmmatch;
               if (ref($intervalmatches{$intervaltype}) eq 'ARRAY') {
                   foreach my $item (@{$intervalmatches{$intervaltype}}) {
                       if (ref($item) eq 'ARRAY') {
                           if ($parmval eq $item->[0]) {
                               $parmmatch = $parmval;
                               $parmval = '';
                               last;
                           }
                       }
                   }
               }
               my $needsrelease=$Apache::lonnet::needsrelease{"parameter:$name:$parmval:$parmmatch"};
               if ($needsrelease) {
                   unless ($got_chostname) {
                       ($chostname,$cmajor,$cminor)=&parameter_release_vars();
                       $got_chostname = 1;
                   }
                   my $needsnewer=&parameter_releasecheck($name,$parmval,$parmmatch,undef,
                                                          $needsrelease,$cmajor,$cminor);
                   if ($needsnewer) {
                       if ($parmmatch ne '') {
                           $skipval{$parmmatch} = 1;
                       } elsif ($parmval ne '') {
                           $skipval{$parmval} = 1;
                       }
                   }
               }
           }
       }
   
       my $currval = $showval;
       foreach my $which (['days', 86400, 31],
                  ['hours', 3600, 23],
                  ['minutes', 60, 59],
                  ['seconds',  1, 59]) {
           my ($name, $factor, $max) = @{ $which };
           my $amount = int($showval/$factor);
           $showval  %= $factor;
           my %select = ((map {$_ => $_} (0..$max)),
                   'select_form_order' => [0..$max]);
           $result .= &Apache::loncommon::select_form($amount,$name.'_'.$thiskey,
                               \%select,'',$readonly);
           $result .= ' '.&mt($name);
       }
       if ($name 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'".');"';
               $result .= '<br /><span class="LC_nobreak">'.&mt('Include "done" button').
                          '<label><input type="radio" value="" name="done_'.$thiskey.'"'.$checkedoff.$onclick.' />'.
                          &mt('No').'</label>'.('&nbsp;'x2).
                          '<label><input type="radio" value="_done" name="done_'.$thiskey.'"'.$checkedon.$onclick.' />'.
                          &mt('Yes').'</label>'.('&nbsp;'x2).
                          '<label><input type="radio" value="_done_proctor" name="done_'.$thiskey.'"'.$checkedproc.$onclick.' />'.
                          &mt('Yes, with proctor key').'</label>'.
                          '<input type="'.$currprocdisplay.'" id="done_'.$thiskey.'_proctorkey" '.
                          'name="done_'.$thiskey.'_proctorkey" value="'.&HTML::Entities::encode($currproctorkey,'"<>&').'" /></span><br />'.
                          '<span class="LC_nobreak">'.&mt('Button text').': '.
                          '<input type="text" name="done_'.$thiskey.'_buttontext" value="'.&HTML::Entities::encode($currdonetext,'"<>&').'" /></span>';
           }
       }
       unless ($readonly) {
           $result .= '<input type="hidden" name="dateinterval_'.$thiskey.'" />';
       }
       return $result;
   }
   
   sub oldversion_warning {
       my ($name,$namematch,$value,$chostname,$cmajor,$cminor,$needsrelease) = @_;
       my $standard_name = &standard_parameter_names($name);
       if ($namematch) {
           my $level = &standard_parameter_levels($namematch);
           my $msg = '';
           if ($level) {
               $msg = &mt('[_1] was [_2]not[_3] set at the level of: [_4].',
                          $standard_name,'<b>','</b>','"'.$level.'"');
           } else {
               $msg = &mt('[_1] was [_2]not[_3] set.',
                         $standard_name,'<b>','</b>');
           }
           return '<p class="LC_warning">'.$msg.'<br />'.
                  &mt('LON-CAPA version ([_1]) installed on home server ([_2]) does not meet version requirements ([_3] or newer).',
                      $cmajor.'.'.$cminor,$chostname,
                      $needsrelease).
                      '</p>';
       }
       my $desc;
       my $stringtype = &get_stringtype($name);
       if ($stringtype ne '') {
           if ($name eq 'examcode') {
               $desc = $value;
           } elsif (ref($strings{$stringtypes{$name}}) eq 'ARRAY') {
               foreach my $possibilities (@{ $strings{$stringtypes{$name}} }) {
                   next unless (ref($possibilities) eq 'ARRAY');
                   my ($parmval, $description) = @{ $possibilities };
                   my $parmmatch;
                   if (ref($stringmatches{$stringtypes{$name}}) eq 'ARRAY') {
                       foreach my $item (@{$stringmatches{$stringtypes{$name}}}) {
                           if (ref($item) eq 'ARRAY') {
                               my ($regexpname,$pattern) = @{$item};
                               if ($parmval eq $regexpname) {
                                   if ($value =~ /$pattern/) {
                                       $desc = $description; 
                                       $parmmatch = 1;
                                       last;
                                   }
                               }
                           }
                       }
                       last if ($parmmatch);
                   } elsif ($parmval eq $value) {
                       $desc = $description;
                       last;
                   }
               }
           }
       } elsif (($name eq 'printstartdate') || ($name eq 'printenddate')) {
           my $now = time;
           if ($value =~ /^\d+$/) {
               if ($name eq 'printstartdate') {
                   if ($value > $now) {
                       $desc = &Apache::lonlocal::locallocaltime($value);
                   }
               } elsif ($name eq 'printenddate') {
                   if ($value < $now) {
                       $desc = &Apache::lonlocal::locallocaltime($value);
                   }
               }
           }
       }
       return '<p class="LC_warning">'.
          &mt('[_1] was [_2]not[_3] set to [_4].',
              $standard_name,'<b>','</b>','"'.$desc.'"').'<br />'.
          &mt('LON-CAPA version ([_1]) installed on home server ([_2]) does not meet version requirements ([_3] or newer).',
          $cmajor.'.'.$cminor,$chostname,
          $needsrelease).
          '</p>';
   }
   
   } # end of block using some constants related to parameter types
   
   
 #  #
 # Shift all start and end dates by $shift  # Shift all start and end dates by $shift
 #  #
Line 3296  sub dateshift { Line 4400  sub dateshift {
     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};      my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
     my %data=&Apache::lonnet::dump('resourcedata',$dom,$crs);      my %data=&Apache::lonnet::dump('resourcedata',$dom,$crs);
 # ugly retro fix for broken version of types  # ugly retro fix for broken version of types
     foreach my $key (keys %data) {      foreach my $key (keys(%data)) {
         if ($key=~/\wtype$/) {          if ($key=~/\wtype$/) {
             my $newkey=$key;              my $newkey=$key;
             $newkey=~s/type$/\.type/;              $newkey=~s/type$/\.type/;
Line 3306  sub dateshift { Line 4410  sub dateshift {
     }      }
     my %storecontent=();      my %storecontent=();
 # go through all parameters and look for dates  # go through all parameters and look for dates
     foreach my $key (keys %data) {      foreach my $key (keys(%data)) {
        if ($data{$key.'.type'}=~/^date_(start|end)$/) {         if ($data{$key.'.type'}=~/^date_(start|end)$/) {
           my $newdate=$data{$key}+$shift;            my $newdate=$data{$key}+$shift;
           $storecontent{$key}=$newdate;            $storecontent{$key}=$newdate;
Line 3331  sub newoverview { Line 4435  sub newoverview {
         text=>"Overview Mode"});          text=>"Overview Mode"});
   
     my %loaditems = (      my %loaditems = (
                       'onload'   => "showHide_courseContent(); resize_scrollbox('mapmenuscroll','1','1');",                        'onload'   => "showHide_courseContent(); resize_scrollbox('mapmenuscroll','1','1'); showHideLenient();",
                     );                      );
     my $js = '      my $js = '
 <script type="text/javascript">  <script type="text/javascript">
Line 3339  sub newoverview { Line 4443  sub newoverview {
 '.  '.
             &Apache::lonhtmlcommon::resize_scrollbox_js('params')."\n".              &Apache::lonhtmlcommon::resize_scrollbox_js('params')."\n".
             &showhide_js()."\n".              &showhide_js()."\n".
               &toggleparmtextbox_js()."\n".
               &validateparms_js()."\n".
               &ipacc_boxes_js()."\n".
               &done_proctor_js()."\n".
 '// ]]>  '// ]]>
 </script>  </script>
 ';  ';
   
     my $start_page = &Apache::loncommon::start_page('Set Parameters',$js,      my $start_page = &Apache::loncommon::start_page('Set Parameters',$js,
                                                     {'add_entries' => \%loaditems,});                                                      {'add_entries' => \%loaditems,});
     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview');      my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview');
     $r->print($start_page.$breadcrumbs);      $r->print($start_page.$breadcrumbs);
     &startSettingsScreen($r,'parmset',$crstype);      &startSettingsScreen($r,'parmset',$crstype);
     $r->print(<<ENDOVER);      $r->print(<<ENDOVER);
 <form method="post" action="/adm/parmset?action=newoverview" name="parmform">  <form method="post" action="/adm/parmset?action=newoverview" name="parmform" onsubmit="return validateParms();">
 ENDOVER  ENDOVER
     my @ids=();      my @ids=();
     my %typep=();      my %typep=();
Line 3385  ENDOVER Line 4494  ENDOVER
             @selected_sections = ('all');              @selected_sections = ('all');
         }          }
     }      }
       if ($env{'request.course.sec'} ne '') {
           @selected_sections = ($env{'request.course.sec'});
       }
     my @selected_groups =      my @selected_groups =
         &Apache::loncommon::get_env_multiple('form.Group');          &Apache::loncommon::get_env_multiple('form.Group');
   
Line 3424  ENDOVER Line 4536  ENDOVER
     &displaymenu($r,\%allparms,\@pscat,\%keyorder);      &displaymenu($r,\%allparms,\@pscat,\%keyorder);
     $r->print(&Apache::lonhtmlcommon::start_pick_box());      $r->print(&Apache::lonhtmlcommon::start_pick_box());
     $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parts to View')));      $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parts to View')));
       my $sectionselector = &sectionmenu(\@selected_sections);
       my $groupselector = &groupmenu(\@selected_groups);
     $r->print('<table>'.      $r->print('<table>'.
               '<tr><th>'.&mt('Parts').'</th><th>'.&mt('Section(s)').                '<tr><th>'.&mt('Parts').'</th>');
               '</th><th>'.&mt('Group(s)').'</th></tr><tr><td>');      if ($sectionselector) {
           $r->print('<th>'.&mt('Section(s)').'</th>');
       }
       if ($groupselector) {
           $r->print('<th>'.&mt('Group(s)').'</th>');
       }
       $r->print('</tr><tr><td>');
     &partmenu($r,\%allparts,\@psprt);      &partmenu($r,\%allparts,\@psprt);
     $r->print('</td><td>');      $r->print('</td>');
     &sectionmenu($r,\@selected_sections);      if ($sectionselector) { 
     $r->print('</td><td>');          $r->print('<td>'.$sectionselector.'</td>');
     &groupmenu($r,\@selected_groups);      }
     $r->print('</td></tr></table>');      if ($groupselector) {
     #$r->print('</td></tr></table>');          $r->print('<td>'.$groupselector.'</td>');
       }
       $r->print('</tr></table>');
     $r->print(&Apache::lonhtmlcommon::row_closure(1));      $r->print(&Apache::lonhtmlcommon::row_closure(1));
     $r->print(&Apache::lonhtmlcommon::end_pick_box());      $r->print(&Apache::lonhtmlcommon::end_pick_box());
     $r->print('</div></div>');      $r->print('</div></div>');
Line 3467  ENDOVER Line 4589  ENDOVER
   
 # List data  # List data
   
         &listdata($r,$resourcedata,$listdata,$sortorder);          &listdata($r,$resourcedata,$listdata,$sortorder,'newoverview');
     }      }
     $r->print(&tableend().      $r->print(&tableend().
          ((($env{'form.store'}) || ($env{'form.dis'}))?'<p><input type="submit" name="store" value="'.&mt('Save').'" /></p>':'').           ((($env{'form.store'}) || ($env{'form.dis'}))?'<p><input type="submit" name="store" value="'.&mt('Save').'" /></p>':'').
Line 3491  sub secgroup_lister { Line 4613  sub secgroup_lister {
                 $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};                  $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
             } elsif ($parmlev eq 'map') {              } elsif ($parmlev eq 'map') {
 # map-level parameter  # map-level parameter
                 foreach my $mapid (keys %{$allmaps}) {                  foreach my $mapid (keys(%{$allmaps})) {
                     if (($pschp ne 'all') && ($pschp ne $mapid)) { next; }                      if (($pschp ne 'all') && ($pschp ne $mapid)) { next; }
                     my $newparmkey=$rootparmkey.'.'.$$allmaps{$mapid}.'___(all).'.$part.'.'.$cat;                      my $newparmkey=$rootparmkey.'.'.$$allmaps{$mapid}.'___(all).'.$part.'.'.$cat;
                     $$listdata{$newparmkey}=1;                      $$listdata{$newparmkey}=1;
                     $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};                      $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
                       $newparmkey=$rootparmkey.'.'.$$allmaps{$mapid}.'___(rec).'.$part.'.'.$cat;
                       $$listdata{$newparmkey}=1;
                       $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
                 }                  }
             } else {              } else {
 # resource-level parameter  # resource-level parameter
Line 3511  sub secgroup_lister { Line 4636  sub secgroup_lister {
     }      }
 }  }
   
   # Display all existing parameter settings.
 sub overview {  sub overview {
     my ($r) = @_;      my ($r) = @_;
     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};      my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};      my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
     my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};      my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
       my $js = '<script type="text/javascript">'."\n".
                '// <![CDATA['."\n".
                &toggleparmtextbox_js()."\n".
                &validateparms_js()."\n".
                &ipacc_boxes_js()."\n".
                &done_proctor_js()."\n".
                '// ]]>'."\n".
                '</script>'."\n";
     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview',      &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview',
     text=>"Overview Mode"});      text=>"Overview Mode"});
     my $start_page=&Apache::loncommon::start_page('Modify Parameters');      my %loaditems = (
                         'onload'   => "showHideLenient();",
                       );
   
       my $start_page=&Apache::loncommon::start_page('Modify Parameters',$js,{'add_entries' => \%loaditems,});
     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview');      my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview');
     $r->print($start_page.$breadcrumbs);      $r->print($start_page.$breadcrumbs);
     &startSettingsScreen($r,'parmset',$crstype);      &startSettingsScreen($r,'parmset',$crstype);
     $r->print('<form method="post" action="/adm/parmset?action=setoverview" name="parmform">');      $r->print('<form method="post" action="/adm/parmset?action=setoverview" name="parmform" onsubmit="return validateParms();">');
   
 # Store modified  # Store modified
   
Line 3531  sub overview { Line 4668  sub overview {
   
 # Read modified data  # Read modified data
   
     my $resourcedata=&readdata($crs,$dom);      my ($resourcedata,$classlist)=&readdata($crs,$dom);
   
   
     my $sortorder=$env{'form.sortorder'};      my $sortorder=$env{'form.sortorder'};
Line 3540  sub overview { Line 4677  sub overview {
   
 # List data  # List data
   
     my $foundkeys=&listdata($r,$resourcedata,$resourcedata,$sortorder);      my $foundkeys=&listdata($r,$resourcedata,$resourcedata,$sortorder,'overview',$classlist);
   
     $r->print(&tableend().'<p>'.      $r->print(&tableend().'<p>'.
     ($foundkeys?'<input type="submit" value="'.&mt('Save').'" />':'<span class="LC_info">'.&mt('There are no parameters.').'</span>').'</p></form>'.      ($foundkeys?'<input type="submit" value="'.&mt('Save').'" />':'<span class="LC_info">'.&mt('There are no parameters.').'</span>').'</p></form>'.
           &Apache::loncommon::end_page());            &Apache::loncommon::end_page());
 }  }
   
   # Unused sub.
 sub clean_parameters {  sub clean_parameters {
     my ($r) = @_;      my ($r) = @_;
     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};      my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
Line 3582  ENDOVER Line 4719  ENDOVER
           '<th>'.&mt('Parameter').'</th>'.            '<th>'.&mt('Parameter').'</th>'.
           '</tr>');            '</tr>');
     foreach my $thiskey (sort(keys(%{$resourcedata}))) {      foreach my $thiskey (sort(keys(%{$resourcedata}))) {
     next if (!exists($resourcedata->{$thiskey.'.type'})          next if (!exists($resourcedata->{$thiskey.'.type'})
          && $thiskey=~/\.type$/);              && $thiskey=~/\.type$/);
     my %data = &parse_key($thiskey);          my %data = &parse_key($thiskey);
     if (1) { #exists($data{'realm_exists'})          if (1) { #exists($data{'realm_exists'})
         #&& !$data{'realm_exists'}) {              #&& !$data{'realm_exists'}) {
         $r->print(&Apache::loncommon::start_data_table_row().              $r->print(&Apache::loncommon::start_data_table_row().
               '<tr>'.                  '<tr>'.
               '<td><input type="checkbox" name="del_'.$thiskey.'" /></td>'              );                  '<td><input type="checkbox" name="del_'.$thiskey.'" /></td>'              );
   
         $r->print('<td>');              $r->print('<td>');
         my $display_value = $resourcedata->{$thiskey};              my $display_value = $resourcedata->{$thiskey};
         if (&isdateparm($resourcedata->{$thiskey.'.type'})) {              if (&isdateparm($resourcedata->{$thiskey.'.type'})) {
         $display_value =              $display_value =
             &Apache::lonlocal::locallocaltime($display_value);                  &Apache::lonlocal::locallocaltime($display_value);
         }              }
             my $parmitem = &standard_parameter_names($data{'parameter_name'});              my $parmitem = &standard_parameter_names($data{'parameter_name'});
             $parmitem = &mt($parmitem);              $parmitem = &mt($parmitem);
         $r->print(&mt('Parameter: "[_1]" with value: "[_2]"',              $r->print(&mt('Parameter: "[_1]" with value: "[_2]"',
               $parmitem,$resourcedata->{$thiskey}));                  $parmitem,$resourcedata->{$thiskey}));
         $r->print('<br />');              $r->print('<br />');
         if ($data{'scope_type'} eq 'all') {              if ($data{'scope_type'} eq 'all') {
         $r->print(&mt('All users'));                  $r->print(&mt('All users'));
         } elsif ($data{'scope_type'} eq 'user') {              } elsif ($data{'scope_type'} eq 'user') {
         $r->print(&mt('User: [_1]',join(':',@{$data{'scope'}})));                  $r->print(&mt('User: [_1]',join(':',@{$data{'scope'}})));
         } elsif ($data{'scope_type'} eq 'section') {              } elsif ($data{'scope_type'} eq 'section') {
         $r->print(&mt('Section: [_1]',$data{'scope'}));                  $r->print(&mt('Section: [_1]',$data{'scope'}));
         } elsif ($data{'scope_type'} eq 'group') {              } elsif ($data{'scope_type'} eq 'group') {
         $r->print(&mt('Group: [_1]',$data{'scope'}));                  $r->print(&mt('Group: [_1]',$data{'scope'}));
         }              }
         $r->print('<br />');              $r->print('<br />');
         if ($data{'realm_type'} eq 'all') {              if ($data{'realm_type'} eq 'all') {
         $r->print(&mt('All Resources'));                  $r->print(&mt('All Resources'));
         } elsif ($data{'realm_type'} eq 'folder') {              } elsif ($data{'realm_type'} eq 'folder') {
         $r->print(&mt('Folder: [_1]'),$data{'realm'});                  $r->print(&mt('Folder: [_1]'),$data{'realm'});
         } elsif ($data{'realm_type'} eq 'symb') {              } elsif ($data{'realm_type'} eq 'symb') {
         my ($map,$resid,$url) =              my ($map,$resid,$url) =
             &Apache::lonnet::decode_symb($data{'realm'});                  &Apache::lonnet::decode_symb($data{'realm'});
         $r->print(&mt('Resource: [_1]with ID: [_2]in folder [_3]',              $r->print(&mt('Resource: [_1]with ID: [_2]in folder [_3]',
                       $url.' <br />&nbsp;&nbsp;&nbsp;',                          $url.' <br />&nbsp;&nbsp;&nbsp;',
                       $resid.' <br />&nbsp;&nbsp;&nbsp;',$map));                          $resid.' <br />&nbsp;&nbsp;&nbsp;',$map));
         }              }
         $r->print(' <br />&nbsp;&nbsp;&nbsp;'.&mt('Part: [_1]',$data{'parameter_part'}));              $r->print(' <br />&nbsp;&nbsp;&nbsp;'.&mt('Part: [_1]',$data{'parameter_part'}));
         $r->print('</td></tr>');              $r->print('</td></tr>');
   
     }          }
     }      }
     $r->print(&Apache::loncommon::end_data_table().'<p>'.      $r->print(&Apache::loncommon::end_data_table().'<p>'.
           '<input type="submit" value="'.&mt('Delete Selected').'" />'.            '<input type="submit" value="'.&mt('Delete Selected').'" />'.
Line 3635  ENDOVER Line 4772  ENDOVER
     $r->print(&Apache::loncommon::end_page());      $r->print(&Apache::loncommon::end_page());
 }  }
   
   # Overview mode, UI to shift all dates.
 sub date_shift_one {  sub date_shift_one {
     my ($r) = @_;      my ($r) = @_;
     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};      my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
Line 3663  sub date_shift_one { Line 4801  sub date_shift_one {
     $r->print(&Apache::loncommon::end_page());      $r->print(&Apache::loncommon::end_page());
 }  }
   
   # Overview mode, UI to shift all dates (second form).
 sub date_shift_two {  sub date_shift_two {
     my ($r) = @_;      my ($r) = @_;
     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};      my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
Line 3697  sub parse_key { Line 4836  sub parse_key {
     ($key=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s]+)\.(\w+)$/);      ($key=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s]+)\.(\w+)$/);
     $data{'scope_type'} = 'all';      $data{'scope_type'} = 'all';
     if ($middle=~/^\[(.*)\]/) {      if ($middle=~/^\[(.*)\]/) {
            $data{'scope'} = $1;          $data{'scope'} = $1;
     if ($data{'scope'}=~/^useropt\:($match_username)\:($match_domain)/) {          if ($data{'scope'}=~/^useropt\:($match_username)\:($match_domain)/) {
         $data{'scope_type'} = 'user';              $data{'scope_type'} = 'user';
         $data{'scope'} = [$1,$2];              $data{'scope'} = [$1,$2];
     } else {          } else {
         #FIXME check for group scope              #FIXME check for group scope
         $data{'scope_type'} = 'section';              $data{'scope_type'} = 'section';
     }          }
     $middle=~s/^\[(.*)\]//;          $middle=~s/^\[(.*)\]//;
     }      }
     $middle=~s/\.+$//;      $middle=~s/\.+$//;
     $middle=~s/^\.+//;      $middle=~s/^\.+//;
     $data{'realm_type'}='all';      $data{'realm_type'}='all';
     if ($middle=~/^(.+)\_\_\_\(all\)$/) {      if ($middle=~/^(.+)\_\_\_\(all\)$/) {
     $data{'realm'} = $1;          $data{'realm'} = $1;
     $data{'realm_type'} = 'folder';          $data{'realm_type'} = 'folder';
     $data{'realm_title'} = &Apache::lonnet::gettitle($data{'realm'});          $data{'realm_title'} = &Apache::lonnet::gettitle($data{'realm'});
     ($data{'realm_exists'}) = &Apache::lonnet::is_on_map($data{'realm'});          ($data{'realm_exists'}) = &Apache::lonnet::is_on_map($data{'realm'});
     } elsif ($middle) {      } elsif ($middle) {
     $data{'realm'} = $middle;          $data{'realm'} = $middle;
     $data{'realm_type'} = 'symb';          $data{'realm_type'} = 'symb';
     $data{'realm_title'} = &Apache::lonnet::gettitle($data{'realm'});          $data{'realm_title'} = &Apache::lonnet::gettitle($data{'realm'});
     my ($map,$resid,$url) = &Apache::lonnet::decode_symb($data{'realm'});          my ($map,$resid,$url) = &Apache::lonnet::decode_symb($data{'realm'});
     $data{'realm_exists'} = &Apache::lonnet::symbverify($data{'realm'},$url);          $data{'realm_exists'} = &Apache::lonnet::symbverify($data{'realm'},$url);
     }      }
   
     $data{'parameter_part'} = $part;      $data{'parameter_part'} = $part;
Line 3736  sub header { Line 4875  sub header {
   
   
   
   ##################################################
   # MAIN MENU
   ##################################################
   
 sub print_main_menu {  sub print_main_menu {
     my ($r,$parm_permission)=@_;      my ($r,$parm_permission)=@_;
     #      #
Line 3835  ENDMAINFORMHEAD Line 4978  ENDMAINFORMHEAD
   
   
   
   ##################################################
   # PORTFOLIO METADATA
   ##################################################
   
 sub output_row {  sub output_row {
     my ($r, $field_name, $field_text, $added_flag) = @_;      my ($r, $field_name, $field_text, $added_flag) = @_;
     my $output;      my $output;
Line 3856  sub output_row { Line 5003  sub output_row {
         $output .= '<td><strong>'.$field_text.':</strong></td>';          $output .= '<td><strong>'.$field_text.':</strong></td>';
         $output .= &Apache::loncommon::end_data_table_row();          $output .= &Apache::loncommon::end_data_table_row();
         foreach my $opt (@options) {          foreach my $opt (@options) {
         my $checked = ($options =~ m/$opt->[0]/) ? ' checked="checked" ' : '' ;              my $checked = ($options =~ m/$opt->[0]/) ? ' checked="checked" ' : '' ;
         $output .= &Apache::loncommon::continue_data_table_row();              $output .= &Apache::loncommon::continue_data_table_row();
         $output .= '<td>'.('&nbsp;' x 5).'<label>              $output .= '<td>'.('&nbsp;' x 5).'<label>
                    <input type="checkbox" name="'.                      <input type="checkbox" name="'.
                    $field_name.'_'.$opt->[0].'" value="yes"'.$checked.' />'.                      $field_name.'_'.$opt->[0].'" value="yes"'.$checked.' />'.
                    &mt($opt->[1]).'</label></td>';                      &mt($opt->[1]).'</label></td>';
         $output .= &Apache::loncommon::end_data_table_row();              $output .= &Apache::loncommon::end_data_table_row();
     }          }
         $output .= &Apache::loncommon::continue_data_table_row();          $output .= &Apache::loncommon::continue_data_table_row();
         $output .= '<td>'.('&nbsp;' x 10).'<input name="'.$field_name.'_values" type="text" value="'.$values.'" size="80" /></td>';          $output .= '<td>'.('&nbsp;' x 10).'<input name="'.$field_name.'_values" type="text" value="'.$values.'" size="80" /></td>';
         $output .= &Apache::loncommon::end_data_table_row();          $output .= &Apache::loncommon::end_data_table_row();
Line 3876  sub output_row { Line 5023  sub output_row {
             $multiple_checked = ' checked="checked"';              $multiple_checked = ' checked="checked"';
             $single_checked = '';              $single_checked = '';
         }          }
     $output .= &Apache::loncommon::continue_data_table_row();          $output .= &Apache::loncommon::continue_data_table_row();
     $output .= '<td>'.('&nbsp;' x 10).'          $output .= '<td>'.('&nbsp;' x 10).'
                 <input type="radio" name="'.$field_name.'_onlyone" value="multiple"'.$multiple_checked .' />                      <input type="radio" name="'.$field_name.'_onlyone" value="multiple"'.$multiple_checked .' />
                 '.&mt('Student may select multiple choices from list').'</td>';                      '.&mt('Student may select multiple choices from list').'</td>';
     $output .= &Apache::loncommon::end_data_table_row();          $output .= &Apache::loncommon::end_data_table_row();
     $output .= &Apache::loncommon::continue_data_table_row();          $output .= &Apache::loncommon::continue_data_table_row();
     $output .= '<td>'.('&nbsp;' x 10).'          $output .= '<td>'.('&nbsp;' x 10).'
                 <input type="radio" name="'.$field_name.'_onlyone"  value="single"'.$single_checked.' />                      <input type="radio" name="'.$field_name.'_onlyone"  value="single"'.$single_checked.' />
                 '.&mt('Student may select only one choice from list').'</td>';                      '.&mt('Student may select only one choice from list').'</td>';
     $output .= &Apache::loncommon::end_data_table_row();          $output .= &Apache::loncommon::end_data_table_row();
     }      }
     return ($output);      return ($output);
 }  }
   
   
   # UI to order portfolio metadata fields.
 sub order_meta_fields {  sub order_meta_fields {
     my ($r)=@_;      my ($r)=@_;
     my $idx = 1;      my $idx = 1;
Line 3899  sub order_meta_fields { Line 5046  sub order_meta_fields {
     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};      my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
     my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};;      my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};;
     $r->print(&Apache::loncommon::start_page('Order Metadata Fields'));      $r->print(&Apache::loncommon::start_page('Order Metadata Fields'));
     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=addmetadata',      &Apache::lonhtmlcommon::add_breadcrumb(
           {href=>'/adm/parmset?action=addmetadata',
         text=>"Add Metadata Field"});          text=>"Add Metadata Field"});
     &Apache::lonhtmlcommon::add_breadcrumb      &Apache::lonhtmlcommon::add_breadcrumb(
             ({href=>"/adm/parmset?action=setrestrictmeta",          {href=>"/adm/parmset?action=setrestrictmeta",
               text=>"Restrict Metadata"},          text=>"Restrict Metadata"},
              {text=>"Order Metadata"});          {text=>"Order Metadata"});
     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Order Metadata'));      $r->print(&Apache::lonhtmlcommon::breadcrumbs('Order Metadata'));
     &startSettingsScreen($r,'parmset',$crstype);      &startSettingsScreen($r,'parmset',$crstype);
     if ($env{'form.storeorder'}) {      if ($env{'form.storeorder'}) {
         my $newpos = $env{'form.newpos'} - 1;          my $newpos = $env{'form.newpos'} - 1;
         my $currentpos = $env{'form.currentpos'} - 1;          my $currentpos = $env{'form.currentpos'} - 1;
         my @neworder = ();          my @neworder = ();
         my @oldorder = split /,/,$env{'course.'.$env{'request.course.id'}.'.metadata.addedorder'};          my @oldorder = split(/,/,$env{'course.'.$env{'request.course.id'}.'.metadata.addedorder'});
         my $i;          my $i;
         if ($newpos > $currentpos) {          if ($newpos > $currentpos) {
         # moving stuff up          # moving stuff up
             for ($i=0;$i<$currentpos;$i++) {              for ($i=0;$i<$currentpos;$i++) {
             $neworder[$i]=$oldorder[$i];                  $neworder[$i]=$oldorder[$i];
             }              }
             for ($i=$currentpos;$i<$newpos;$i++) {              for ($i=$currentpos;$i<$newpos;$i++) {
             $neworder[$i]=$oldorder[$i+1];                  $neworder[$i]=$oldorder[$i+1];
             }              }
             $neworder[$newpos]=$oldorder[$currentpos];              $neworder[$newpos]=$oldorder[$currentpos];
             for ($i=$newpos+1;$i<=$#oldorder;$i++) {              for ($i=$newpos+1;$i<=$#oldorder;$i++) {
             $neworder[$i]=$oldorder[$i];                  $neworder[$i]=$oldorder[$i];
             }              }
         } else {          } else {
         # moving stuff down          # moving stuff down
Line 3938  sub order_meta_fields { Line 5086  sub order_meta_fields {
                 $neworder[$i]=$oldorder[$i];                  $neworder[$i]=$oldorder[$i];
             }              }
         }          }
     my $ordered_fields = join ",", @neworder;          my $ordered_fields = join ",", @neworder;
         my $put_result = &Apache::lonnet::put('environment',          my $put_result = &Apache::lonnet::put('environment',
                            {'metadata.addedorder'=>$ordered_fields},$dom,$crs);                          {'metadata.addedorder'=>$ordered_fields},$dom,$crs);
     &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.metadata.addedorder' => $ordered_fields});          &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.metadata.addedorder' => $ordered_fields});
     }      }
     my $fields = &get_added_meta_fieldnames($env{'request.course.id'});      my $fields = &get_added_meta_fieldnames($env{'request.course.id'});
     my $ordered_fields;      my $ordered_fields;
     my @fields_in_order = split /,/,$env{'course.'.$env{'request.course.id'}.'.metadata.addedorder'};      my @fields_in_order = split(/,/,$env{'course.'.$env{'request.course.id'}.'.metadata.addedorder'});
     if (!@fields_in_order) {      if (!@fields_in_order) {
         # no order found, pick sorted order then create metadata.addedorder key.          # no order found, pick sorted order then create metadata.addedorder key.
         foreach my $key (sort keys %$fields) {          foreach my $key (sort(keys(%$fields))) {
             push @fields_in_order, $key;              push @fields_in_order, $key;
             $ordered_fields = join ",", @fields_in_order;              $ordered_fields = join ",", @fields_in_order;
         }          }
Line 4044  sub addmetafield { Line 5192  sub addmetafield {
   
   
   
   # Display or save portfolio metadata.
 sub setrestrictmeta {  sub setrestrictmeta {
     my ($r)=@_;      my ($r)=@_;
     my $next_meta;      my $next_meta;
Line 4084  sub setrestrictmeta { Line 5233  sub setrestrictmeta {
                         $options.='deleted,';                          $options.='deleted,';
                     }                      }
                     my $name = $save_field;                      my $name = $save_field;
                      $put_result = &Apache::lonnet::put('environment',                      $put_result = &Apache::lonnet::put('environment',
                                                   {'metadata.'.$meta_field.'.options'=>$options,                          {'metadata.'.$meta_field.'.options'=>$options,
                                                    'metadata.'.$meta_field.'.values'=>$env{'form.'.$meta_field.'_values'},                          'metadata.'.$meta_field.'.values'=>$env{'form.'.$meta_field.'_values'},
                                                    },$dom,$crs);                          },$dom,$crs);
                 }                  }
             }              }
         }          }
Line 4103  sub setrestrictmeta { Line 5252  sub setrestrictmeta {
     foreach my $field (sort(keys(%metadata_fields))) {      foreach my $field (sort(keys(%metadata_fields))) {
         if ($field ne 'courserestricted') {          if ($field ne 'courserestricted') {
             $row_alt = $row_alt ? 0 : 1;              $row_alt = $row_alt ? 0 : 1;
         $output.= &output_row($r, $field, $metadata_fields{$field});              $output.= &output_row($r, $field, $metadata_fields{$field});
     }          }
     }      }
     my $buttons = (<<ENDButtons);      my $buttons = (<<ENDButtons);
         <input type="submit" name="restrictmeta" value="Save" />          <input type="submit" name="restrictmeta" value="Save" />
Line 4134  ENDenv Line 5283  ENDenv
 }  }
   
   
   
 sub get_added_meta_fieldnames {  sub get_added_meta_fieldnames {
     my ($cid) = @_;      my ($cid) = @_;
     my %fields;      my %fields;
Line 4149  sub get_added_meta_fieldnames { Line 5297  sub get_added_meta_fieldnames {
 }  }
   
   
   
 sub get_deleted_meta_fieldnames {  sub get_deleted_meta_fieldnames {
     my ($cid) = @_;      my ($cid) = @_;
     my %fields;      my %fields;
Line 4164  sub get_deleted_meta_fieldnames { Line 5311  sub get_deleted_meta_fieldnames {
     }      }
     return \%fields;      return \%fields;
 }  }
   
   
   ##################################################
   # PARAMETER SETTINGS DEFAULT ACTIONS
   ##################################################
   
   # UI to change parameter setting default actions
 sub defaultsetter {  sub defaultsetter {
     my ($r) = @_;      my ($r) = @_;
   
Line 4196  sub defaultsetter { Line 5350  sub defaultsetter {
                 \%mapp, \%symbp,\%maptitles,\%uris,                  \%mapp, \%symbp,\%maptitles,\%uris,
                 \%keyorder,\%defkeytype);                  \%keyorder,\%defkeytype);
     if ($env{'form.storerules'}) {      if ($env{'form.storerules'}) {
     my %newrules=();          my %newrules=();
     my @delrules=();          my @delrules=();
     my %triggers=();          my %triggers=();
     foreach my $key (keys(%env)) {          foreach my $key (keys(%env)) {
             if ($key=~/^form\.(\w+)\_action$/) {              if ($key=~/^form\.(\w+)\_action$/) {
         my $tempkey=$1;                  my $tempkey=$1;
         my $action=$env{$key};                  my $action=$env{$key};
                 if ($action) {                  if ($action) {
             $newrules{$tempkey.'_action'}=$action;                      $newrules{$tempkey.'_action'}=$action;
             if ($action ne 'default') {                      if ($action ne 'default') {
             my ($whichaction,$whichparm)=($action=~/^(.*\_)([^\_]+)$/);                          my ($whichaction,$whichparm)=($action=~/^(.*\_)([^\_]+)$/);
             $triggers{$whichparm}.=$tempkey.':';                          $triggers{$whichparm}.=$tempkey.':';
             }                      }
             $newrules{$tempkey.'_type'}=$defkeytype{$tempkey};                      $newrules{$tempkey.'_type'}=$defkeytype{$tempkey};
             if (&isdateparm($defkeytype{$tempkey})) {                      if (&isdateparm($defkeytype{$tempkey})) {
             $newrules{$tempkey.'_days'}=$env{'form.'.$tempkey.'_days'};                          $newrules{$tempkey.'_days'}=$env{'form.'.$tempkey.'_days'};
             $newrules{$tempkey.'_hours'}=$env{'form.'.$tempkey.'_hours'};                          $newrules{$tempkey.'_hours'}=$env{'form.'.$tempkey.'_hours'};
             $newrules{$tempkey.'_min'}=$env{'form.'.$tempkey.'_min'};                          $newrules{$tempkey.'_min'}=$env{'form.'.$tempkey.'_min'};
             $newrules{$tempkey.'_sec'}=$env{'form.'.$tempkey.'_sec'};                          $newrules{$tempkey.'_sec'}=$env{'form.'.$tempkey.'_sec'};
             } else {                      } else {
             $newrules{$tempkey.'_value'}=$env{'form.'.$tempkey.'_value'};                          $newrules{$tempkey.'_value'}=$env{'form.'.$tempkey.'_value'};
             $newrules{$tempkey.'_triggervalue'}=$env{'form.'.$tempkey.'_triggervalue'};                          $newrules{$tempkey.'_triggervalue'}=$env{'form.'.$tempkey.'_triggervalue'};
                       }
                   } else {
                       push(@delrules,$tempkey.'_action');
                       push(@delrules,$tempkey.'_type');
                       push(@delrules,$tempkey.'_hours');
                       push(@delrules,$tempkey.'_min');
                       push(@delrules,$tempkey.'_sec');
                       push(@delrules,$tempkey.'_value');
                   }
             }              }
         } else {  
             push(@delrules,$tempkey.'_action');  
             push(@delrules,$tempkey.'_type');  
             push(@delrules,$tempkey.'_hours');  
             push(@delrules,$tempkey.'_min');  
             push(@delrules,$tempkey.'_sec');  
             push(@delrules,$tempkey.'_value');  
         }          }
           foreach my $key (keys(%allparms)) {
               $newrules{$key.'_triggers'}=$triggers{$key};
         }          }
     }          &Apache::lonnet::put('parmdefactions',\%newrules,$cdom,$cnum);
     foreach my $key (keys %allparms) {          &Apache::lonnet::del('parmdefactions',\@delrules,$cdom,$cnum);
         $newrules{$key.'_triggers'}=$triggers{$key};          &resetrulescache();
     }  
     &Apache::lonnet::put('parmdefactions',\%newrules,$cdom,$cnum);  
     &Apache::lonnet::del('parmdefactions',\@delrules,$cdom,$cnum);  
     &resetrulescache();  
     }      }
     my %lt=&Apache::lonlocal::texthash('days' => 'Days',      my %lt=&Apache::lonlocal::texthash('days' => 'Days',
                        'hours' => 'Hours',                         'hours' => 'Hours',
Line 4247  sub defaultsetter { Line 5401  sub defaultsetter {
     my @dateoptions=('','default');      my @dateoptions=('','default');
     my @datedisplay=('',&mt('Default value when manually setting'));      my @datedisplay=('',&mt('Default value when manually setting'));
     foreach my $tempkey (&keysindisplayorder(\%allparms,\%keyorder)) {      foreach my $tempkey (&keysindisplayorder(\%allparms,\%keyorder)) {
     unless ($tempkey) { next; }          unless ($tempkey) { next; }
     push @standardoptions,'when_setting_'.$tempkey;          push @standardoptions,'when_setting_'.$tempkey;
     push @standarddisplay,&mt('Automatically set when setting ').$tempkey;          push @standarddisplay,&mt('Automatically set when setting ').$tempkey;
     if (&isdateparm($defkeytype{$tempkey})) {          if (&isdateparm($defkeytype{$tempkey})) {
         push @dateoptions,'later_than_'.$tempkey;              push @dateoptions,'later_than_'.$tempkey;
         push @datedisplay,&mt('Automatically set later than ').$tempkey;              push @datedisplay,&mt('Automatically set later than ').$tempkey;
         push @dateoptions,'earlier_than_'.$tempkey;              push @dateoptions,'earlier_than_'.$tempkey;
         push @datedisplay,&mt('Automatically set earlier than ').$tempkey;              push @datedisplay,&mt('Automatically set earlier than ').$tempkey;
     }          }
     }      }
 $r->print(&mt('Manual setting rules apply to all interfaces.').'<br />'.  $r->print(&mt('Manual setting rules apply to all interfaces.').'<br />'.
       &mt('Automatic setting rules apply to table mode interfaces only.'));        &mt('Automatic setting rules apply to table mode interfaces only.'));
Line 4265  $r->print(&mt('Manual setting rules appl Line 5419  $r->print(&mt('Manual setting rules appl
           &mt('Action').'</th><th>'.&mt('Value').'</th>'.            &mt('Action').'</th><th>'.&mt('Value').'</th>'.
           &Apache::loncommon::end_data_table_header_row());            &Apache::loncommon::end_data_table_header_row());
     foreach my $tempkey (&keysindisplayorder(\%allparms,\%keyorder)) {      foreach my $tempkey (&keysindisplayorder(\%allparms,\%keyorder)) {
     unless ($tempkey) { next; }          unless ($tempkey) { next; }
     $r->print("\n".&Apache::loncommon::start_data_table_row().          $r->print("\n".&Apache::loncommon::start_data_table_row().
           "<td>".$allparms{$tempkey}."\n<br />(".$tempkey.')</td><td>');              "<td>".$allparms{$tempkey}."\n<br />(".$tempkey.')</td><td>');
     my $action=&rulescache($tempkey.'_action');          my $action=&rulescache($tempkey.'_action');
     $r->print('<select name="'.$tempkey.'_action">');          $r->print('<select name="'.$tempkey.'_action">');
     if (&isdateparm($defkeytype{$tempkey})) {          if (&isdateparm($defkeytype{$tempkey})) {
         for (my $i=0;$i<=$#dateoptions;$i++) {              for (my $i=0;$i<=$#dateoptions;$i++) {
         if ($dateoptions[$i]=~/\_$tempkey$/) { next; }              if ($dateoptions[$i]=~/\_$tempkey$/) { next; }
         $r->print("\n<option value='$dateoptions[$i]'".              $r->print("\n<option value='$dateoptions[$i]'".
               ($dateoptions[$i] eq $action?' selected="selected"':'').                  ($dateoptions[$i] eq $action?' selected="selected"':'').
               ">$datedisplay[$i]</option>");                  ">$datedisplay[$i]</option>");
               }
           } else {
               for (my $i=0;$i<=$#standardoptions;$i++) {
               if ($standardoptions[$i]=~/\_$tempkey$/) { next; }
               $r->print("\n<option value='$standardoptions[$i]'".
                   ($standardoptions[$i] eq $action?' selected="selected"':'').
                   ">$standarddisplay[$i]</option>");
               }
         }          }
     } else {          $r->print('</select>');
         for (my $i=0;$i<=$#standardoptions;$i++) {          unless (&isdateparm($defkeytype{$tempkey})) {
         if ($standardoptions[$i]=~/\_$tempkey$/) { next; }              $r->print("\n<br />".&mt('Triggering value(s) of other parameter (optional, comma-separated):').
         $r->print("\n<option value='$standardoptions[$i]'".                  '<input type="text" size="20" name="'.$tempkey.'_triggervalue" value="'.&rulescache($tempkey.'_triggervalue').'" />');
               ($standardoptions[$i] eq $action?' selected="selected"':'').  
               ">$standarddisplay[$i]</option>");  
         }          }
     }          $r->print("\n</td><td>\n");
     $r->print('</select>');  
     unless (&isdateparm($defkeytype{$tempkey})) {  
         $r->print("\n<br />".&mt('Triggering value(s) of other parameter (optional, comma-separated):').  
               '<input type="text" size="20" name="'.$tempkey.'_triggervalue" value="'.&rulescache($tempkey.'_triggervalue').'" />');  
     }  
     $r->print("\n</td><td>\n");  
   
         if (&isdateparm($defkeytype{$tempkey})) {          if (&isdateparm($defkeytype{$tempkey})) {
         my $days=&rulescache($tempkey.'_days');              my $days=&rulescache($tempkey.'_days');
         my $hours=&rulescache($tempkey.'_hours');              my $hours=&rulescache($tempkey.'_hours');
         my $min=&rulescache($tempkey.'_min');              my $min=&rulescache($tempkey.'_min');
         my $sec=&rulescache($tempkey.'_sec');              my $sec=&rulescache($tempkey.'_sec');
         $r->print(<<ENDINPUTDATE);              $r->print(<<ENDINPUTDATE);
 <input name="$tempkey\_days" type="text" size="4" value="$days" />$lt{'days'}<br />      <input name="$tempkey\_days" type="text" size="4" value="$days" />$lt{'days'}<br />
 <input name="$tempkey\_hours" type="text" size="4" value="$hours" />$lt{'hours'}<br />      <input name="$tempkey\_hours" type="text" size="4" value="$hours" />$lt{'hours'}<br />
 <input name="$tempkey\_min" type="text" size="4" value="$min" />$lt{'min'}<br />      <input name="$tempkey\_min" type="text" size="4" value="$min" />$lt{'min'}<br />
 <input name="$tempkey\_sec" type="text" size="4" value="$sec" />$lt{'sec'}      <input name="$tempkey\_sec" type="text" size="4" value="$sec" />$lt{'sec'}
 ENDINPUTDATE      ENDINPUTDATE
     } elsif ($defkeytype{$tempkey} eq 'string_yesno') {          } elsif ($defkeytype{$tempkey} eq 'string_yesno') {
             my $yeschecked='';                  my $yeschecked='';
             my $nochecked='';                  my $nochecked='';
             if (&rulescache($tempkey.'_value') eq 'yes') { $yeschecked=' checked="checked"'; }                  if (&rulescache($tempkey.'_value') eq 'yes') { $yeschecked=' checked="checked"'; }
             if (&rulescache($tempkey.'_value') eq 'no') { $nochecked=' checked="checked"'; }                  if (&rulescache($tempkey.'_value') eq 'no') { $nochecked=' checked="checked"'; }
   
         $r->print(<<ENDYESNO);              $r->print(<<ENDYESNO);
 <label><input type="radio" name="$tempkey\_value" value="yes"$yeschecked /> $lt{'yes'}</label><br />      <label><input type="radio" name="$tempkey\_value" value="yes"$yeschecked /> $lt{'yes'}</label><br />
 <label><input type="radio" name="$tempkey\_value" value="no"$nochecked /> $lt{'no'}</label>      <label><input type="radio" name="$tempkey\_value" value="no"$nochecked /> $lt{'no'}</label>
 ENDYESNO      ENDYESNO
         } else {          } else {
         $r->print('<input type="text" size="20" name="'.$tempkey.'_value" value="'.&rulescache($tempkey.'_value').'" />');              $r->print('<input type="text" size="20" name="'.$tempkey.'_value" value="'.&rulescache($tempkey.'_value').'" />');
     }          }
         $r->print('</td>'.&Apache::loncommon::end_data_table_row());          $r->print('</td>'.&Apache::loncommon::end_data_table_row());
     }      }
     $r->print(&Apache::loncommon::end_data_table().      $r->print(&Apache::loncommon::end_data_table().
Line 4326  ENDYESNO Line 5480  ENDYESNO
     return;      return;
 }  }
   
   ##################################################
   # PARAMETER CHANGES LOG
   ##################################################
   
 sub components {  sub components {
     my ($key,$uname,$udom,$exeuser,$exedomain,$typeflag)=@_;      my ($key,$uname,$udom,$exeuser,$exedomain,$typeflag)=@_;
   
     if ($typeflag) {      if ($typeflag) {
     $key=~s/\.type$//;          $key=~s/\.type$//;
     }      }
   
     my ($middle,$part,$name)=      my ($middle,$part,$name)=
     ($key=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s]+)\.(\w+)$/);          ($key=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s]+)\.(\w+)$/);
     my $issection;      my $issection;
   
     my $section=&mt('All Students');      my $section=&mt('All Students');
     if ($middle=~/^\[(.*)\]/) {      if ($middle=~/^\[(.*)\]/) {
     $issection=$1;          $issection=$1;
     $section=&mt('Group/Section').': '.$issection;          $section=&mt('Group/Section').': '.$issection;
     $middle=~s/^\[(.*)\]//;          $middle=~s/^\[(.*)\]//;
     }      }
     $middle=~s/\.+$//;      $middle=~s/\.+$//;
     $middle=~s/^\.+//;      $middle=~s/^\.+//;
     if ($uname) {      if ($uname) {
     $section=&mt('User').": ".&Apache::loncommon::plainname($uname,$udom);          $section=&mt('User').": ".&Apache::loncommon::plainname($uname,$udom);
     $issection='';          $issection='';
     }      }
     my $realm='<span class="LC_parm_scope_all">'.&mt('All Resources').'</span>';      my $realm='<span class="LC_parm_scope_all">'.&mt('All Resources').'</span>';
     my $realmdescription=&mt('all resources');      my $realmdescription=&mt('all resources');
     if ($middle=~/^(.+)\_\_\_\(all\)$/) {      if ($middle=~/^(.+)\_\_\_\((all|rec)\)$/) {
     $realm='<span class="LC_parm_scope_folder">'.&mt('Folder/Map').': '.&Apache::lonnet::gettitle($1).' <span class="LC_parm_folder"><br />('.$1.')</span></span>';          my $mapurl = $1;
      $realmdescription=&mt('folder').' '.&Apache::lonnet::gettitle($1);          my $maplevel = $2;
    } elsif ($middle) {          my $leveltitle = &mt('Folder/Map');
     my ($map,$id,$url)=&Apache::lonnet::decode_symb($middle);          if ($maplevel eq 'rec') {
     $realm='<span class="LC_parm_scope_resource">'.&mt('Resource').': '.&Apache::lonnet::gettitle($middle).' <br /><span class="LC_parm_symb">('.$url.' in '.$map.' id: '.$id.')</span></span>';              $leveltitle = &mt('Recursive');
     $realmdescription=&mt('resource').' '.&Apache::lonnet::gettitle($middle);          }
           $realm='<span class="LC_parm_scope_folder">'.$leveltitle.
               ': '.&Apache::lonnet::gettitle($mapurl).' <span class="LC_parm_folder"><br />('.
               $mapurl.')</span></span>';
           $realmdescription=&mt('folder').' '.&Apache::lonnet::gettitle($mapurl);
       } elsif ($middle) {
           my ($map,$id,$url)=&Apache::lonnet::decode_symb($middle);
           $realm='<span class="LC_parm_scope_resource">'.&mt('Resource').
               ': '.&Apache::lonnet::gettitle($middle).' <br /><span class="LC_parm_symb">('.$url.
               ' in '.$map.' id: '.$id.')</span></span>';
           $realmdescription=&mt('resource').' '.&Apache::lonnet::gettitle($middle);
     }      }
     my $what=$part.'.'.$name;      my $what=$part.'.'.$name;
     return ($realm,$section,$name,$part,      return ($realm,$section,$name,$part,
Line 4370  my %standard_parms_types; Line 5538  my %standard_parms_types;
 sub load_parameter_names {  sub load_parameter_names {
     open(my $config,"<$Apache::lonnet::perlvar{'lonTabDir'}/packages.tab");      open(my $config,"<$Apache::lonnet::perlvar{'lonTabDir'}/packages.tab");
     while (my $configline=<$config>) {      while (my $configline=<$config>) {
     if ($configline !~ /\S/ || $configline=~/^\#/) { next; }          if ($configline !~ /\S/ || $configline=~/^\#/) { next; }
     chomp($configline);          chomp($configline);
     my ($short,$plain)=split(/:/,$configline);          my ($short,$plain)=split(/:/,$configline);
     my (undef,$name,$type)=split(/\&/,$short,3);          my (undef,$name,$type)=split(/\&/,$short,3);
     if ($type eq 'display') {          if ($type eq 'display') {
         $standard_parms{$name} = $plain;              $standard_parms{$name} = $plain;
         } elsif ($type eq 'type') {          } elsif ($type eq 'type') {
             $standard_parms_types{$name} = $plain;                  $standard_parms_types{$name} = $plain;
         }          }
     }      }
     close($config);      close($config);
Line 4388  sub load_parameter_names { Line 5556  sub load_parameter_names {
 sub standard_parameter_names {  sub standard_parameter_names {
     my ($name)=@_;      my ($name)=@_;
     if (!%standard_parms) {      if (!%standard_parms) {
     &load_parameter_names();          &load_parameter_names();
     }      }
     if ($standard_parms{$name}) {      if ($standard_parms{$name}) {
     return $standard_parms{$name};          return $standard_parms{$name};
     } else {      } else {
     return $name;          return $name;
     }      }
 }  }
   
Line 4408  sub standard_parameter_types { Line 5576  sub standard_parameter_types {
     return;      return;
 }  }
   
   sub standard_parameter_levels {
       my ($name)=@_;
       my %levels = (
                       'resourcelevel'   => 'a single resource',
                       'maplevel'        => 'the enclosing map/folder', 
                       'maplevelrecurse' => 'the enclosing map/folder (recursive into sub-folders)',
                       'courselevel'     => 'the general (course) level',
                    );
       if ($levels{$name}) {
           return $levels{$name};
       }
       return;
   }
   
   # Display log for parameter changes, blog postings, user notification changes.
 sub parm_change_log {  sub parm_change_log {
     my ($r)=@_;      my ($r)=@_;
     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};      my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
Line 4449  sub parm_change_log { Line 5632  sub parm_change_log {
     my $shown=0;      my $shown=0;
     my $folder='';      my $folder='';
     if ($env{'form.displayfilter'} eq 'currentfolder') {      if ($env{'form.displayfilter'} eq 'currentfolder') {
     my $last='';          my $last='';
     if (tie(my %hash,'GDBM_File',$env{'request.course.fn'}.'_symb.db',          if (tie(my %hash,'GDBM_File',$env{'request.course.fn'}.'_symb.db',
         &GDBM_READER(),0640)) {                  &GDBM_READER(),0640)) {
         $last=$hash{'last_known'};              $last=$hash{'last_known'};
         untie(%hash);              untie(%hash);
     }          }
     if ($last) { ($folder) = &Apache::lonnet::decode_symb($last); }          if ($last) { ($folder) = &Apache::lonnet::decode_symb($last); }
     }      }
     foreach my $id (sort      foreach my $id (sort {
             {                  if ($parmlog{$b}{'exe_time'} ne $parmlog{$a}{'exe_time'}) {
             if ($parmlog{$b}{'exe_time'} ne $parmlog{$a}{'exe_time'}) {                      return $parmlog{$b}{'exe_time'} <=>$parmlog{$a}{'exe_time'}
                 return $parmlog{$b}{'exe_time'} <=>$parmlog{$a}{'exe_time'}                  }
             }                  my $aid = (split('00000',$a))[-1];
             my $aid = (split('00000',$a))[-1];                  my $bid = (split('00000',$b))[-1];
             my $bid = (split('00000',$b))[-1];                  return $bid<=>$aid;
             return $bid<=>$aid;  
             } (keys(%parmlog))) {              } (keys(%parmlog))) {
         my @changes=keys(%{$parmlog{$id}{'logentry'}});          my @changes=keys(%{$parmlog{$id}{'logentry'}});
     my $count = 0;          my $count = 0;
     my $time =          my $time =
         &Apache::lonlocal::locallocaltime($parmlog{$id}{'exe_time'});              &Apache::lonlocal::locallocaltime($parmlog{$id}{'exe_time'});
     my $plainname =          my $plainname =
         &Apache::loncommon::plainname($parmlog{$id}{'exe_uname'},              &Apache::loncommon::plainname($parmlog{$id}{'exe_uname'},
                       $parmlog{$id}{'exe_udom'});                          $parmlog{$id}{'exe_udom'});
     my $about_me_link =          my $about_me_link =
         &Apache::loncommon::aboutmewrapper($plainname,              &Apache::loncommon::aboutmewrapper($plainname,
                            $parmlog{$id}{'exe_uname'},                              $parmlog{$id}{'exe_uname'},
                            $parmlog{$id}{'exe_udom'});                              $parmlog{$id}{'exe_udom'});
     my $send_msg_link='';          my $send_msg_link='';
     if ((($parmlog{$id}{'exe_uname'} ne $env{'user.name'})          if ((($parmlog{$id}{'exe_uname'} ne $env{'user.name'})
          || ($parmlog{$id}{'exe_udom'} ne $env{'user.domain'}))) {              || ($parmlog{$id}{'exe_udom'} ne $env{'user.domain'}))) {
         $send_msg_link ='<br />'.              $send_msg_link ='<br />'.
         &Apache::loncommon::messagewrapper(&mt('Send message'),              &Apache::loncommon::messagewrapper(&mt('Send message'),
                            $parmlog{$id}{'exe_uname'},                              $parmlog{$id}{'exe_uname'},
                            $parmlog{$id}{'exe_udom'});                              $parmlog{$id}{'exe_udom'});
     }          }
     my $row_start=&Apache::loncommon::start_data_table_row();          my $row_start=&Apache::loncommon::start_data_table_row();
     my $makenewrow=0;          my $makenewrow=0;
     my %istype=();          my %istype=();
     my $output;          my $output;
     foreach my $changed (reverse(sort(@changes))) {          foreach my $changed (reverse(sort(@changes))) {
             my $value=$parmlog{$id}{'logentry'}{$changed};                  my $value=$parmlog{$id}{'logentry'}{$changed};
         my $typeflag = ($changed =~/\.type$/ &&              my $typeflag = ($changed =~/\.type$/ &&
                 !exists($parmlog{$id}{'logentry'}{$changed.'.type'}));                      !exists($parmlog{$id}{'logentry'}{$changed.'.type'}));
             my ($realm,$section,$parmname,$part,$what,$middle,$uname,$udom,$issection,$realmdescription)=              my ($realm,$section,$parmname,$part,$what,$middle,$uname,$udom,$issection,$realmdescription)=
         &components($changed,$parmlog{$id}{'uname'},$parmlog{$id}{'udom'},undef,undef,$typeflag);                  &components($changed,$parmlog{$id}{'uname'},$parmlog{$id}{'udom'},undef,undef,$typeflag);
         if ($env{'form.displayfilter'} eq 'currentfolder') {              if ($env{'request.course.sec'} ne '') {
         if ($folder) {                  next if (($issection ne '') && ($issection ne $env{'request.course.sec'}));
             if ($middle!~/^\Q$folder\E/) { next; }                  if ($uname ne '') {
         }                      my $stusection = &Apache::lonnet::getsection($uname,$udom,$env{'request.course.id'});
         }                      next if (($stusection ne '-1') && ($stusection ne $env{'request.course.sec'})); 
         if ($typeflag) {                  }
         $istype{$parmname}=$value;              }
         if (!$env{'form.includetypes'}) { next; }              if ($env{'form.displayfilter'} eq 'currentfolder') {
         }                  if ($folder) {
         $count++;                      if ($middle!~/^\Q$folder\E/) { next; }
         if ($makenewrow) {                  }
         $output .= $row_start;              }
         } else {              if ($typeflag) {
         $makenewrow=1;                  $istype{$parmname}=$value;
         }                  if (!$env{'form.includetypes'}) { next; }
               }
               $count++;
               if ($makenewrow) {
                   $output .= $row_start;
               } else {
                   $makenewrow=1;
               }
             my $parmitem = &standard_parameter_names($parmname);              my $parmitem = &standard_parameter_names($parmname);
         $output .='<td>'.$realm.'</td><td>'.$section.'</td><td>'.              $output .='<td>'.$realm.'</td><td>'.$section.'</td><td>'.
               &mt($parmitem).'</td><td>'.                  &mt($parmitem).'</td><td>'.
               ($part?&mt('Part: [_1]',$part):&mt('All Parts')).'</td><td>';                  ($part?&mt('Part: [_1]',$part):&mt('All Parts')).'</td><td>';
         my $stillactive=0;              my $stillactive=0;
         if ($parmlog{$id}{'delflag'}) {              if ($parmlog{$id}{'delflag'}) {
         $output .= &mt('Deleted');                  $output .= &mt('Deleted');
         } else {              } else {
         if ($typeflag) {                  if ($typeflag) {
                     my $parmitem = &standard_parameter_names($value);                       my $parmitem = &standard_parameter_names($value); 
                     $parmitem = &mt($parmitem);                      $parmitem = &mt($parmitem);
             $output .= &mt('Type: [_1]',$parmitem);                      $output .= &mt('Type: [_1]',$parmitem);
         } else {                  } else {
             my ($level,@all)=&parmval_by_symb($what,$middle,&Apache::lonnet::metadata($middle,$what),                      my ($level,@all)=&parmval_by_symb($what,$middle,
                               $uname,$udom,$issection,$issection,$courseopt);                          &Apache::lonnet::metadata($middle,$what),
                           $uname,$udom,$issection,$issection,$courseopt);
                     my $showvalue = $value;                      my $showvalue = $value;
                     if ($istype{$parmname} eq '') {                      if ($istype{$parmname} eq '') {
                         my $type = &standard_parameter_types($parmname);                          my $type = &standard_parameter_types($parmname);
Line 4535  sub parm_change_log { Line 5725  sub parm_change_log {
                             }                              }
                         }                          }
                     } else {                      } else {
                 if (&isdateparm($istype{$parmname})) {                          if (&isdateparm($istype{$parmname})) {
                 $showvalue =                               $showvalue = &Apache::lonlocal::locallocaltime($value);
                                 &Apache::lonlocal::locallocaltime($value);                          }
                 }  
                     }                      }
                     $output .= $showvalue;                      $output .= $showvalue;
             if ($value ne $all[$level]) {                      if ($value ne $all[$level]) {
             $output .= '<br /><span class="LC_warning">'.&mt('Not active anymore').'</span>';                          $output .= '<br /><span class="LC_warning">'.&mt('Not active anymore').'</span>';
             } else {                      } else {
             $stillactive=1;                          $stillactive=1;
                       }
                   }
             }              }
         }              $output .= '</td><td>';
         }                  
         $output .= '</td><td>';              if ($stillactive) {
               
         if ($stillactive) {  
                 my $parmitem = &standard_parameter_names($parmname);                  my $parmitem = &standard_parameter_names($parmname);
                 $parmitem = &mt($parmitem);                  $parmitem = &mt($parmitem);
         my $title=&mt('Changed [_1]',$parmitem);                  my $title=&mt('Changed [_1]',$parmitem);
                 my $description=&mt('Changed [_1] for [_2] to [_3]',                  my $description=&mt('Changed [_1] for [_2] to [_3]',
                                     $parmitem,$realmdescription,                      $parmitem,$realmdescription,
                     (&isdateparm($istype{$parmname})?&Apache::lonlocal::locallocaltime($value):$value));                      (&isdateparm($istype{$parmname})?&Apache::lonlocal::locallocaltime($value):$value));
         if (($uname) && ($udom)) {                  if (($uname) && ($udom)) {
             $output .=                      $output .=
             &Apache::loncommon::messagewrapper('Notify User',                      &Apache::loncommon::messagewrapper('Notify User',
                                $uname,$udom,$title,                                      $uname,$udom,$title,
                                $description);                                      $description);
         } else {                  } else {
             $output .=                      $output .=
             &Apache::lonrss::course_blog_link($id,$title,                      &Apache::lonrss::course_blog_link($id,$title,
                               $description);                                      $description);
         }                  }
               }
               $output .= '</td>'.&Apache::loncommon::end_data_table_row();
         }          }
         $output .= '</td>'.&Apache::loncommon::end_data_table_row();  
     }  
         if ($env{'form.displayfilter'} eq 'containing') {          if ($env{'form.displayfilter'} eq 'containing') {
         my $wholeentry=$about_me_link.':'.              my $wholeentry=$about_me_link.':'.
         $parmlog{$id}{'exe_uname'}.':'.$parmlog{$id}{'exe_udom'}.':'.              $parmlog{$id}{'exe_uname'}.':'.$parmlog{$id}{'exe_udom'}.':'.
         $output;              $output;
         if ($wholeentry!~/\Q$env{'form.containingphrase'}\E/i) { next; }              if ($wholeentry!~/\Q$env{'form.containingphrase'}\E/i) { next; }
     }          }
         if ($count) {          if ($count) {
         $r->print($row_start.'<td rowspan="'.$count.'">'.$time.'</td>              $r->print($row_start.'<td rowspan="'.$count.'">'.$time.'</td>
                        <td rowspan="'.$count.'">'.$about_me_link.                          <td rowspan="'.$count.'">'.$about_me_link.
           '<br /><tt>'.$parmlog{$id}{'exe_uname'}.              '<br /><tt>'.$parmlog{$id}{'exe_uname'}.
                       ':'.$parmlog{$id}{'exe_udom'}.'</tt>'.                          ':'.$parmlog{$id}{'exe_udom'}.'</tt>'.
           $send_msg_link.'</td>'.$output);              $send_msg_link.'</td>'.$output);
         $shown++;              $shown++;
     }          }
     if (!($env{'form.show'} eq &mt('all')          if (!($env{'form.show'} eq &mt('all')
           || $shown<=$env{'form.show'})) { last; }              || $shown<=$env{'form.show'})) { last; }
     }      }
     $r->print(&Apache::loncommon::end_data_table());      $r->print(&Apache::loncommon::end_data_table());
     &endSettingsScreen($r);      &endSettingsScreen($r);
     $r->print(&Apache::loncommon::end_page());      $r->print(&Apache::loncommon::end_page());
 }  }
   
   ##################################################
   # MISC !
   ##################################################
   
   # Used by table UI
 sub update_slots {  sub update_slots {
     my ($slot_name,$cdom,$cnum,$symb,$uname,$udom) = @_;      my ($slot_name,$cdom,$cnum,$symb,$uname,$udom) = @_;
     my %slot=&Apache::lonnet::get_slot($slot_name);      my %slot=&Apache::lonnet::get_slot($slot_name);
Line 4645  sub update_slots { Line 5839  sub update_slots {
     return $success;      return $success;
 }  }
   
   # Used by table UI
 sub delete_slots {  sub delete_slots {
     my ($slot_name,$cdom,$cnum,$uname,$udom,$symb) = @_;      my ($slot_name,$cdom,$cnum,$uname,$udom,$symb) = @_;
     my $delresult;      my $delresult;
Line 4680  sub delete_slots { Line 5875  sub delete_slots {
     return $delresult;      return $delresult;
 }  }
   
   # Used by handler
 sub check_for_course_info {  sub check_for_course_info {
     my $navmap = Apache::lonnavmaps::navmap->new();      my $navmap = Apache::lonnavmaps::navmap->new();
     return 1 if ($navmap);      return 1 if ($navmap);
Line 4696  sub parameter_release_vars { Line 5892  sub parameter_release_vars {
 }  }
   
 sub parameter_releasecheck {  sub parameter_releasecheck {
     my ($name,$value,$needsrelease,$cmajor,$cminor) = @_;      my ($name,$value,$valmatch,$namematch,$needsrelease,$cmajor,$cminor) = @_;
     my $needsnewer;      my $needsnewer;
     my ($needsmajor,$needsminor) = split(/\./,$needsrelease);      my ($needsmajor,$needsminor) = split(/\./,$needsrelease);
     if (($cmajor < $needsmajor) ||       if (($cmajor < $needsmajor) || 
         ($cmajor == $needsmajor && $cminor < $needsminor)) {          ($cmajor == $needsmajor && $cminor < $needsminor)) {
         $needsnewer = 1;          $needsnewer = 1;
     } else {      } elsif ($name) {
         &Apache::lonnet::update_released_required($Apache::lonnet::needsrelease{'parameter:'.$name.':'.$value});          if ($valmatch) {
               &Apache::lonnet::update_released_required($Apache::lonnet::needsrelease{'parameter:'.$name.'::'.$valmatch.':'});
           } elsif ($value) { 
               &Apache::lonnet::update_released_required($Apache::lonnet::needsrelease{'parameter:'.$name.':'.$value.'::'});
           }
       } elsif ($namematch) {
           &Apache::lonnet::update_released_required($Apache::lonnet::needsrelease{'parameter::::'.$namematch});
     }      }
     return $needsnewer;      return $needsnewer;
 }  }
   
 sub oldversion_warning {  ##################################################
     my ($name,$value,$chostname,$cmajor,$cminor,$needsrelease) = @_;  # HANDLER
     my $desc;  ##################################################
     my %stringtypes = (  
                         type         => 'string_questiontype',  
                         lenient      => 'string_lenient',  
                         retrypartial => 'string_yesno',  
                         discussvote  => 'string_discussvote',  
                         examcode     => 'string_examcode',  
                       );  
     if (exists($stringtypes{$name})) {  
         if ($name eq 'examcode') {  
             $desc = $value;  
         } elsif (ref($strings{$stringtypes{$name}}) eq 'ARRAY') {  
             foreach my $possibilities (@{ $strings{$stringtypes{$name}} }) {  
                 next unless (ref($possibilities) eq 'ARRAY');  
                 my ($parmval, $description) = @{ $possibilities };  
                 if ($parmval eq $value) {  
                     $desc = $description;  
                     last;  
                 }  
             }  
         }  
     }  
     my $standard_name = &standard_parameter_names($name);  
     return '<p class="LC_warning">'.  
            &mt('[_1] was [_2]not[_3] set to [_4].',  
                $standard_name,'<b>','</b>','"'.$desc.'"').'<br />'.  
            &mt('LON-CAPA version ([_1]) installed on home server ([_2]) does not meet version requirements ([_3] or newer).',  
            $cmajor.'.'.$cminor,$chostname,  
            $needsrelease).  
            '</p>';  
 }  
   
   # Main handler for lonparmset.
   # Sub called based on request parameters action and command:
   # no command or action: print_main_menu
   # command 'set': assessparms (direct access to table mode for a resource)
   #                (this can also be accessed simply with the symb parameter)
   # action 'setoverview': overview (display all existing parameter settings)
   # action 'addmetadata': addmetafield (called to add a portfolio metadata field)
   # action 'ordermetadata': order_meta_fields (called to order portfolio metadata fields)
   # action 'setrestrictmeta': setrestrictmeta (display or save portfolio metadata)
   # action 'newoverview': newoverview (overview mode)
   # action 'setdefaults': defaultsetter (UI to change parameter setting default actions)
   # action 'settable': assessparms (table mode)
   # action 'parameterchangelog': parm_change_log (display log for parameter changes,
   #                              blog postings, user notification changes)
   # action 'cleanparameters': clean_parameters (unused)
   # action 'dateshift1': date_shift_one (overview mode, shift all dates)
   # action 'dateshift2': date_shift_two (overview mode, shift all dates)
 sub handler {  sub handler {
     my $r=shift;      my $r=shift;
   
Line 4782  sub handler { Line 5971  sub handler {
         # Check first if coming from someone else headed directly for          # Check first if coming from someone else headed directly for
         #  the table mode          #  the table mode
         if ((($env{'form.command'} eq 'set') && ($env{'form.url'})          if ((($env{'form.command'} eq 'set') && ($env{'form.url'})
          && (!$env{'form.dis'})) || ($env{'form.symb'})) {                  && (!$env{'form.dis'})) || ($env{'form.symb'})) {
         &assessparms($r);              &assessparms($r);
         } elsif (! exists($env{'form.action'})) {          } elsif (! exists($env{'form.action'})) {
             &print_main_menu($r,$parm_permission);              &print_main_menu($r,$parm_permission);
         } elsif ($env{'form.action'} eq 'setoverview') {          } elsif ($env{'form.action'} eq 'setoverview') {
         &overview($r);              &overview($r);
     } elsif ($env{'form.action'} eq 'addmetadata') {          } elsif ($env{'form.action'} eq 'addmetadata') {
         &addmetafield($r);              &addmetafield($r);
     } elsif ($env{'form.action'} eq 'ordermetadata') {          } elsif ($env{'form.action'} eq 'ordermetadata') {
         &order_meta_fields($r);              &order_meta_fields($r);
         } elsif ($env{'form.action'} eq 'setrestrictmeta') {          } elsif ($env{'form.action'} eq 'setrestrictmeta') {
         &setrestrictmeta($r);              &setrestrictmeta($r);
         } elsif ($env{'form.action'} eq 'newoverview') {          } elsif ($env{'form.action'} eq 'newoverview') {
         &newoverview($r);              &newoverview($r);
         } elsif ($env{'form.action'} eq 'setdefaults') {          } elsif ($env{'form.action'} eq 'setdefaults') {
         &defaultsetter($r);              &defaultsetter($r);
     } elsif ($env{'form.action'} eq 'settable') {          } elsif ($env{'form.action'} eq 'settable') {
         &assessparms($r);              &assessparms($r);
         } elsif ($env{'form.action'} eq 'parameterchangelog') {          } elsif ($env{'form.action'} eq 'parameterchangelog') {
         &parm_change_log($r);              &parm_change_log($r);
         } elsif ($env{'form.action'} eq 'cleanparameters') {          } elsif ($env{'form.action'} eq 'cleanparameters') {
         &clean_parameters($r);              &clean_parameters($r);
         } elsif ($env{'form.action'} eq 'dateshift1') {          } elsif ($env{'form.action'} eq 'dateshift1') {
             &date_shift_one($r);              &date_shift_one($r);
         } elsif ($env{'form.action'} eq 'dateshift2') {          } elsif ($env{'form.action'} eq 'dateshift2') {
Line 4811  sub handler { Line 6000  sub handler {
         }          }
     } else {      } else {
 # ----------------------------- Not in a course, or not allowed to modify parms  # ----------------------------- Not in a course, or not allowed to modify parms
     if ($exists) {          if ($exists) {
         $env{'user.error.msg'}=              $env{'user.error.msg'}=
         "/adm/parmset:opa:0:0:Cannot modify assessment parameters";              "/adm/parmset:opa:0:0:Cannot modify assessment parameters";
     } else {          } else {
         $env{'user.error.msg'}=              $env{'user.error.msg'}=
         "/adm/parmset::0:1:Course environment gone, reinitialize the course";              "/adm/parmset::0:1:Course environment gone, reinitialize the course";
     }          }
     return HTTP_NOT_ACCEPTABLE;          return HTTP_NOT_ACCEPTABLE;
     }      }
     &reset_caches();      &reset_caches();
   

Removed from v.1.545  
changed lines
  Added in v.1.561


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>