Diff for /loncom/interface/lonparmset.pm between versions 1.355 and 1.428

version 1.355, 2006/12/14 20:49:22 version 1.428, 2009/02/03 21:11:16
Line 44  This module sets coursewide and assessme Line 44  This module sets coursewide and assessme
   
 =head1 INTERNAL SUBROUTINES  =head1 INTERNAL SUBROUTINES
   
 =over 4  =over
   
 =cut  
   
 ###################################################################  
 ###################################################################  
   
 package Apache::lonparmset;  
   
 use strict;  
 use Apache::lonnet;  
 use Apache::Constants qw(:common :http REDIRECT);  
 use Apache::lonhtmlcommon();  
 use Apache::loncommon;  
 use GDBM_File;  
 use Apache::lonhomework;  
 use Apache::lonxml;  
 use Apache::lonlocal;  
 use Apache::lonnavmaps;  
 use Apache::longroup;  
 use Apache::lonrss;  
 use LONCAPA qw(:DEFAULT :match);  
   
 # --- Caches local to lonparmset  
   
 my $parmhashid;  
 my %parmhash;  
 my $symbsid;  
 my %symbs;  
 my $rulesid;  
 my %rules;  
   
 # --- end local caches  
   
 ##################################################  
 ##################################################  
   
 =pod  =pod
   
 =item parmval  =item parmval()
   
 Figure out a cascading parameter.  Figure out a cascading parameter.
   
Line 108  Returns:  A list, the first item is the Line 73  Returns:  A list, the first item is the
 2 - Map or Folder level for specific student  2 - Map or Folder level for specific student
 1 - resource level for specific student  1 - resource level for specific student
   
   =item parmval_by_symb()
   
   =item reset_caches()
   
   =item cacheparmhash() 
   
   =item parmhash()
   
   =item symbcache()
   
   =item preset_defaults()
   
   =item date_sanity_info()
   
   =item storeparm()
   
   Store a parameter by symb
   
       Takes
       - symb
       - name of parameter
       - level
       - new value
       - new type
       - username
       - userdomain
   
   =item log_parmset()
   
   =item storeparm_by_symb_inner()
   
   =item valout()
   
   Format a value for output.
   
   Inputs:  $value, $type, $editable
   
   Returns: $value, formatted for output.  If $type indicates it is a date,
   localtime($value) is returned.
   $editable will return an icon to click on
   
   =item plink()
   
   Produces a link anchor.
   
   Inputs: $type,$dis,$value,$marker,$return,$call
   
   Returns: scalar with html code for a link which will envoke the 
   javascript function 'pjump'.
   
   =item page_js()
   
   =item startpage()
   
   =item print_row()
   
   =item print_td()
   
   =item print_usergroups()
   
   =item parm_control_group()
   
   =item extractResourceInformation() : 
   
   Given the course data hash, extractResourceInformation extracts lots of information about the course's resources into a variety of hashes.
   
   Input: See list below:
   
   =item * B<ids> : An array that will contain all of the ids in the course.
   
   =item * B<typep> : hash, id->type, where "type" contains the extension of the file, thus, I<problem exam quiz assess survey form>.
   
   =item * B<keyp> : hash, id->key list, will contain a comma separated list of the meta-data keys available for the given id
   
   =item * B<allparms> : hash, name of parameter->display value (what is the display value?)
   
   =item * B<allparts> : hash, part identification->text representation of part, where the text representation is "[Part $part]"
   
   =item * B<allkeys> : hash, full key to part->display value (what's display value?)
   
   =item * B<allmaps> : hash, ???
   
   =item * B<fcat> : ???
   
   =item * B<defp> : hash, ???
   
   =item * B<mapp> : ??
   
   =item * B<symbp> : hash, id->full sym?
   
   
   
   =item isdateparm()
   
   =item parmmenu()
   
   =item partmenu()
   
   =item usermenu()
   
   =item displaymenu()
   
   =item mapmenu()
   
   =item levelmenu()
   
   =item sectionmenu()
   
   =item keysplit()
   
   =item keysinorder()
   
   =item keysinorder_bytype()
   
   =item keysindisplayorder()
   
   =item standardkeyorder()
   
   =item assessparms() : 
   
   Show assessment data and parameters.  This is a large routine that should
   be simplified and shortened... someday.
   
   Inputs: $r
   
   Returns: nothing
   
   Variables used (guessed by Jeremy):
   
   =item * B<pscat>: ParameterS CATegories? ends up a list of the types of parameters that exist, e.g., tol, weight, acc, opendate, duedate, answerdate, sig, maxtries, type.
   
   =item * B<psprt>: ParameterS PaRTs? a list of the parts of a problem that we are displaying? Used to display only selected parts?
   
   =item * B<@catmarker> contains list of all possible parameters including part #s
   
   =item * B<$fullkeyp> contains the full part/id # for the extraction of proper parameters
   
   =item * B<$tempkeyp> contains part 0 only (no ids - ie, subparts)
           When storing information, store as part 0
           When requesting information, request from full part
   
   =item crsenv()
   
   Show and set course data and parameters.  This is a large routine that should
   be simplified and shortened... someday.
   
   Inputs: $r
   
   Returns: nothing
   
   =item can_modify_catsettings()
   
   =item assign_course_categories()
   
   =item tablestart()
   
   =item tableend()
   
   =item extractuser()
   
   =item parse_listdata_key()
   
   =item listdata()
   
   =item date_interval_selector()
   
   =item get_date_interval_from_form()
   
   =item default_selector()
   
   =item string_selector()
   
   =item dateshift()
   
   =item newoverview()
   
   =item secgroup_lister()
   
   =item overview()
   
   =item clean_parameters()
   
   =item date_shift_one()
   
   =item date_shift_two()
   
   =item parse_key()
   
   =item check_cloners() :
   
   Checks if new users included in list of allowed cloners
   are valid users.  Replaces supplied list with 
   cleaned list containing only users with valid usernames
   and domains.
   
   Inputs: $clonelist, $oldcloner 
   where $clonelist is ref to array of requested cloners,
   and $oldcloner is ref to array of currently allowed
   cloners.
   
   Returns: string - comma separated list of requested
   cloners (username:domain) who do not exist in system.
   
   =item change_clone() :
   
   Modifies the list of courses a user can clone (stored
   in the user's environment.db file), called when a
   change is made to the list of users allowed to clone
   a course.
   
   Inputs: $action,$cloner
   where $action is add or drop, and $cloner is identity of 
   user for whom cloning ability is to be changed in course. 
   
   
   =item check_cloners()
   
   =item change_clone()
   
   =item header()
   
   Output html header for page
   
   =item print_main_menu()
   
   =item output_row()
   
   Set portfolio metadata
   
   =item order_meta_fields()
   
   =item addmetafield()
   
   =item setrestrictmeta()
   
   =item get_added_meta_fieldnames()
   
   =item get_deleted_meta_fieldnames()
   
   =item defaultsetter()
   
   =item components()
   
   =item load_parameter_names()
   
   =item parm_change_log()
   
   =item handler() : 
   
   Main handler.  Calls &assessparms and &crsenv subroutines.
   
   
   =back
   
 =cut  =cut
   
 ##################################################  ###################################################################
   ###################################################################
   
   package Apache::lonparmset;
   
   use strict;
   use Apache::lonnet;
   use Apache::Constants qw(:common :http REDIRECT);
   use Apache::lonhtmlcommon();
   use Apache::loncommon;
   use GDBM_File;
   use Apache::lonhomework;
   use Apache::lonxml;
   use Apache::lonlocal;
   use Apache::lonnavmaps;
   use Apache::longroup;
   use Apache::lonrss;
   use LONCAPA qw(:DEFAULT :match);
   
   
 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,
Line 119  sub parmval { Line 357  sub parmval {
   
 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)=@_;
 # load caches  
     &cacheparmhash();  
   
     my $useropt;      my $useropt;
     if ($uname ne '' && $udom ne '') {      if ($uname ne '' && $udom ne '') {
Line 167  sub parmval_by_symb { Line 403  sub parmval_by_symb {
   
 # ------------------------------------------------------ third, check map parms  # ------------------------------------------------------ third, check map parms
   
     my $thisparm=$parmhash{$symbparm};      my $thisparm=&parmhash($symbparm);
     if (defined($thisparm)) { $outpar[11]=$thisparm; $result=11; }      if (defined($thisparm)) { $outpar[11]=$thisparm; $result=11; }
   
     if (defined($$courseopt{$courselevelr})) {      if (defined($$courseopt{$courselevelr})) {
Line 228  sub parmval_by_symb { Line 464  sub parmval_by_symb {
     return ($result,@outpar);      return ($result,@outpar);
 }  }
   
 sub resetparmhash {  
     $parmhashid='';  
 }  
   
 sub cacheparmhash {  
     if ($parmhashid eq  $env{'request.course.fn'}) { return; }  
     my %parmhashfile;  
     if (tie(%parmhashfile,'GDBM_File',  
       $env{'request.course.fn'}.'_parms.db',&GDBM_READER(),0640)) {  
  %parmhash=%parmhashfile;  
  untie %parmhashfile;  
  $parmhashid=$env{'request.course.fn'};  
     }  
 }  
   
 sub resetsymbcache {  # --- Caches local to lonparmset
     $symbsid='';  
       
   sub reset_caches {
       &resetparmhash();
       &resetsymbcache();
       &resetrulescache();
 }  }
   
 sub symbcache {  {
     my $id=shift;      my $parmhashid;
     if ($symbsid ne $env{'request.course.id'}) {      my %parmhash;
  %symbs=();      sub resetparmhash {
    undef($parmhashid);
    undef(%parmhash);
     }      }
     unless ($symbs{$id}) {      
  my $navmap = Apache::lonnavmaps::navmap->new();      sub cacheparmhash {
  if ($id=~/\./) {   if ($parmhashid eq  $env{'request.course.fn'}) { return; }
     my $resource=$navmap->getById($id);   my %parmhashfile;
     $symbs{$id}=$resource->symb();   if (tie(%parmhashfile,'GDBM_File',
  } else {   $env{'request.course.fn'}.'_parms.db',&GDBM_READER(),0640)) {
     my $resource=$navmap->getByMapPc($id);      %parmhash=%parmhashfile;
     $symbs{$id}=&Apache::lonnet::declutter($resource->src());      untie(%parmhashfile);
       $parmhashid=$env{'request.course.fn'};
  }   }
  $symbsid=$env{'request.course.id'};  
     }      }
     return $symbs{$id};   
 }      sub parmhash {
    my ($id) = @_;
 sub resetrulescache {   &cacheparmhash();
     $rulesid='';   return $parmhash{$id};
 }      }
    }
   
   {   
       my $symbsid;
       my %symbs;
       sub resetsymbcache {
    undef($symbsid);
    undef(%symbs);
       }
       
       sub symbcache {
    my $id=shift;
    if ($symbsid ne $env{'request.course.id'}) {
       undef(%symbs);
    }
    if (!$symbs{$id}) {
       my $navmap = Apache::lonnavmaps::navmap->new();
       if ($id=~/\./) {
    my $resource=$navmap->getById($id);
    $symbs{$id}=$resource->symb();
       } else {
    my $resource=$navmap->getByMapPc($id);
    $symbs{$id}=&Apache::lonnet::declutter($resource->src());
       }
       $symbsid=$env{'request.course.id'};
    }
    return $symbs{$id};
       }
    }
   
 sub rulescache {  {   
     my $id=shift;      my $rulesid;
     if ($rulesid ne $env{'request.course.id'}      my %rules;
  && !defined($rules{$id})) {      sub resetrulescache {
  my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};   undef($rulesid);
  my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};   undef(%rules);
  %rules=&Apache::lonnet::dump('parmdefactions',$dom,$crs);      }
  $rulesid=$env{'request.course.id'};      
       sub rulescache {
    my $id=shift;
    if ($rulesid ne $env{'request.course.id'}
       && !defined($rules{$id})) {
       my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
       my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
       %rules=&Apache::lonnet::dump('parmdefactions',$dom,$crs);
       $rulesid=$env{'request.course.id'};
    }
    return $rules{$id};
     }      }
     return $rules{$id};  
 }  }
   
   
   
 sub preset_defaults {  sub preset_defaults {
     my $type=shift;      my $type=shift;
     if (&rulescache($type.'_action') eq 'default') {      if (&rulescache($type.'_action') eq 'default') {
Line 296  sub preset_defaults { Line 566  sub preset_defaults {
     }      }
 }  }
   
 ##################################################  
   
   
 sub date_sanity_info {  sub date_sanity_info {
    my $checkdate=shift;     my $checkdate=shift;
Line 305  sub date_sanity_info { Line 576  sub date_sanity_info {
    my $crsprefix='course.'.$env{'request.course.id'}.'.';     my $crsprefix='course.'.$env{'request.course.id'}.'.';
    if ($env{$crsprefix.'default_enrollment_end_date'}) {     if ($env{$crsprefix.'default_enrollment_end_date'}) {
       if ($checkdate>$env{$crsprefix.'default_enrollment_end_date'}) {        if ($checkdate>$env{$crsprefix.'default_enrollment_end_date'}) {
          $result.='<br />'.&mt('After course enrollment end!');           $result.='<div class="LC_warning">'
                    .&mt('After course enrollment end!')
                    .'</div>';
       }        }
    }     }
    if ($env{$crsprefix.'default_enrollment_start_date'}) {     if ($env{$crsprefix.'default_enrollment_start_date'}) {
       if ($checkdate<$env{$crsprefix.'default_enrollment_start_date'}) {        if ($checkdate<$env{$crsprefix.'default_enrollment_start_date'}) {
          $result.='<br />'.&mt('Before course enrollment start!');           $result.='<div class="LC_warning">'
                    .&mt('Before course enrollment start!')
                    .'</div>';
       }        }
    }     }
   # Preparation for additional warnings about dates in the past/future.
   # An improved, more context sensitive version is recommended,
   # e.g. warn for due and answer dates which are defined before the corresponding open date, etc.
   #   if ($checkdate<time) {
   #      $result.='<div class="LC_info">'
   #              .'('.&mt('in the past').')'
   #              .'</div>';
   #      }
   #   if ($checkdate>time) {
   #      $result.='<div class="LC_info">'
   #              .'('.&mt('in the future').')'
   #              .'</div>';
   #      }
    return $result;     return $result;
 }  }
 ##################################################  ##################################################
Line 334  sub storeparm { Line 622  sub storeparm {
     &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);
 }  }
   
 #  
 # Store a parameter by symb  
 #  
 # Takes  
 # - symb  
 # - name of parameter  
 # - level  
 # - new value  
 # - new type  
 # - username  
 # - userdomain  
   
 my %recstack;  my %recstack;
 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)=@_;
Line 500  sub storeparm_by_symb_inner { Line 776  sub storeparm_by_symb_inner {
     return '';      return '';
 }  }
   
 ##################################################  
 ##################################################  
   
 =pod  
   
 =item valout  
   
 Format a value for output.  
   
 Inputs:  $value, $type, $editable  
   
 Returns: $value, formatted for output.  If $type indicates it is a date,  
 localtime($value) is returned.  
 $editable will return an icon to click on  
   
 =cut  
   
 ##################################################  
 ##################################################  
 sub valout {  sub valout {
     my ($value,$type,$editable)=@_;      my ($value,$type,$editable)=@_;
     my $result = '';      my $result = '';
Line 532  sub valout { Line 790  sub valout {
     } else {      } else {
         if ($type eq 'date_interval') {          if ($type eq 'date_interval') {
             my ($sec,$min,$hour,$mday,$mon,$year)=gmtime($value);              my ($sec,$min,$hour,$mday,$mon,$year)=gmtime($value);
               my @timer;
             $year=$year-70;              $year=$year-70;
             $mday--;              $mday--;
             if ($year) {              if ($year) {
  $result.=$year.' yrs ';  #               $result.=&mt('[quant,_1,yr]',$year).' ';
                   push(@timer,&mt('[quant,_1,yr]',$year));
             }              }
             if ($mon) {              if ($mon) {
  $result.=$mon.' mths ';  #               $result.=&mt('[quant,_1,mth]',$mon).' ';
                   push(@timer,&mt('[quant,_1,mth]',$mon));
             }              }
             if ($mday) {              if ($mday) {
  $result.=$mday.' days ';  #               $result.=&mt('[quant,_1,day]',$mday).' ';
                   push(@timer,&mt('[quant,_1,day]',$mday));
             }              }
             if ($hour) {              if ($hour) {
  $result.=$hour.' hrs ';  #               $result.=&mt('[quant,_1,hr]',$hour).' ';
                   push(@timer,&mt('[quant,_1,hr]',$hour));
             }              }
             if ($min) {              if ($min) {
  $result.=$min.' mins ';  #               $result.=&mt('[quant,_1,min]',$min).' ';
                   push(@timer,&mt('[quant,_1,min]',$min));
             }              }
             if ($sec) {              if ($sec) {
  $result.=$sec.' secs ';  #               $result.=&mt('[quant,_1,sec]',$sec).' ';
                   push(@timer,&mt('[quant,_1,sec]',$sec));
               }
   #           $result=~s/\s+$//;
               if (!@timer) { # Special case: all entries 0 -> display "0 secs" intead of empty field to keep this field editable
                   push(@timer,&mt('[quant,_1,sec]',0));
             }              }
             $result=~s/\s+$//;              $result.=join(", ",@timer);
         } elsif (&isdateparm($type)) {          } elsif (&isdateparm($type)) {
             $result = localtime($value).&date_sanity_info($value);              $result = &Apache::lonlocal::locallocaltime($value).
    &date_sanity_info($value);
         } else {          } else {
             $result = $value;              $result = $value;
       $result = &HTML::Entities::encode($result,'"<>&');
         }          }
     }      }
     return $result;      return $result;
 }  }
   
 ##################################################  
 ##################################################  
   
 =pod  
   
 =item plink  
   
 Produces a link anchor.  
   
 Inputs: $type,$dis,$value,$marker,$return,$call  
   
 Returns: scalar with html code for a link which will envoke the   
 javascript function 'pjump'.  
   
 =cut  
   
 ##################################################  
 ##################################################  
 sub plink {  sub plink {
     my ($type,$dis,$value,$marker,$return,$call)=@_;      my ($type,$dis,$value,$marker,$return,$call)=@_;
     my $winvalue=$value;      my $winvalue=$value;
Line 593  sub plink { Line 847  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);
       foreach my $item (\$type, \$dis, \$winvalue, \$marker, \$return, \$call,
         \$hour, \$min, \$sec) {
    $$item = &HTML::Entities::encode($$item,'"<>&');
    $$item =~ s/\'/\\\'/g;
       }
     return '<table width="100%"><tr valign="top" align="right"><td><a name="'.$marker.'" /></td></tr><tr><td align="center">'.      return '<table width="100%"><tr valign="top" align="right"><td><a name="'.$marker.'" /></td></tr><tr><td align="center">'.
  '<a href="javascript:pjump('."'".$type."','".$dis."','".$winvalue."','"   '<a href="javascript:pjump('."'".$type."','".$dis."','".$winvalue."','"
     .$marker."','".$return."','".$call."','".$hour."','".$min."','".$sec."'".');">'.      .$marker."','".$return."','".$call."','".$hour."','".$min."','".$sec."'".');">'.
  &valout($value,$type,1).'</a></td></tr></table>';      $valout.'</a></td></tr></table>';
 }  }
   
 sub page_js {  sub page_js {
Line 656  sub startpage { Line 916  sub startpage {
     my %loaditems = ('onunload' => "pclose()",      my %loaditems = ('onunload' => "pclose()",
      'onload'   => "group_or_section('cgroup')",);       'onload'   => "group_or_section('cgroup')",);
   
       if ((($env{'form.command'} eq 'set') && ($env{'form.url'})
        && (!$env{'form.dis'})) || ($env{'form.symb'})) {
    &Apache::lonhtmlcommon::add_breadcrumb({help=>'Problem_Parameters',
       text=>"Problem Parameters"});
       } else {
    &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=settable',
      text=>"Table Mode",
      help => 'Course_Setting_Parameters'});
       }
     my $start_page =       my $start_page = 
  &Apache::loncommon::start_page('Set/Modify Course Parameters',   &Apache::loncommon::start_page('Set/Modify Course Parameters',
        &page_js(),         &page_js(),
Line 666  sub startpage { Line 935  sub startpage {
 $start_page  $start_page
 $breadcrumbs  $breadcrumbs
 <form method="post" action="/adm/parmset?action=settable" name="parmform">  <form method="post" action="/adm/parmset?action=settable" name="parmform">
 <input type="hidden" value='' name="pres_value" />  <input type="hidden" value="" name="pres_value" />
 <input type="hidden" value='' name="pres_type" />  <input type="hidden" value="" name="pres_type" />
 <input type="hidden" value='' name="pres_marker" />  <input type="hidden" value="" name="pres_marker" />
 <input type="hidden" value='1' name="prevvisit" />  <input type="hidden" value="1" name="prevvisit" />
 ENDHEAD  ENDHEAD
 }  }
   
Line 701  sub print_row { Line 970  sub print_row {
     my $parm=$$display{$which};      my $parm=$$display{$which};
   
     if ($parmlev eq 'full') {      if ($parmlev eq 'full') {
         $r->print('<td bgcolor='.$defbgtwo.' align="center">'          $r->print('<td style="background-color:'.$defbgtwo.';" align="center">'
                   .$$part{$which}.'</td>');                    .$$part{$which}.'</td>');
     } else {          } else {    
         $parm=~s|\[.*\]\s||g;          $parm=~s|\[.*\]\s||g;
           $parm=&mt($parm);
     }      }
     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 bgcolor='.$defbgone.'>'.$parm.'</td>');      $r->print('<td>'.$parm.'</td>');
         
     my $thismarker=$which;      my $thismarker=$which;
     $thismarker=~s/^parameter\_//;      $thismarker=~s/^parameter\_//;
Line 787  sub print_row { Line 1057  sub print_row {
  }   }
   
     } # end of $parmlev if/else      } # end of $parmlev if/else
     $r->print('<td bgcolor="#CCCCFF" align="center">'.$effective_parm.'</td>');      $r->print('<td style="background-color:#CCCCFF;" align="center">'.$effective_parm.'</td>');
   
     if ($parmlev eq 'full') {      if ($parmlev eq 'full') {
         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 bgcolor="#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).'&nbsp;'.
                   '</font></td>');                    '</font></td>');
     }      }
Line 804  sub print_row { Line 1074  sub print_row {
   
 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)=@_;
     $r->print('<td bgcolor='.(($result==$which)?'"#AAFFAA"':$defbg).      $r->print('<td style="background-color:'.(($result==$which)?'#AAFFAA':$defbg).
               ' align="center">');                ';" align="center">');
     if ($which<11 || $which > 12) {      if ($which<11 || $which > 12) {
  $r->print(&plink($$typeoutpar[$which],   $r->print(&plink($$typeoutpar[$which],
  $$display{$value},$$outpar[$which],   $$display{$value},$$outpar[$which],
Line 831  sub print_usergroups { Line 1101  sub print_usergroups {
     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);
         }          }
         $grp_parm = &valout($coursereply,$resulttype);          $grp_parm = &valout($coursereply,$resulttype);
         $output = '<td bgcolor='.$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;
         } else {          } else {
Line 843  sub print_usergroups { Line 1113  sub print_usergroups {
         }          }
         $output .= '</td>';          $output .= '</td>';
     } else {      } else {
         $output .= '<td bgcolor='.$bgcolor.'>&nbsp;</td>';          $output .= '<td style="background-color:'.$bgcolor.';">&nbsp;</td>';
     }      }
     return ($coursereply,$output,$grp_parm,$resultgroup);      return ($coursereply,$output,$grp_parm,$resultgroup);
 }  }
Line 872  sub parm_control_group { Line 1142  sub parm_control_group {
     return($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype);      return($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype);
 }  }
   
 =pod  
   
 =item B<extractResourceInformation>: Given the course data hash, extractResourceInformation extracts lots of information about the course's resources into a variety of hashes.  
   
 Input: See list below:  
   
 =over 4  
   
 =item B<ids>: An array that will contain all of the ids in the course.  
   
 =item B<typep>: hash, id->type, where "type" contains the extension of the file, thus, I<problem exam quiz assess survey form>.  
   
 =item B<keyp>: hash, id->key list, will contain a comma separated list of the meta-data keys available for the given id  
   
 =item B<allparms>: hash, name of parameter->display value (what is the display value?)  
   
 =item B<allparts>: hash, part identification->text representation of part, where the text representation is "[Part $part]"  
   
 =item B<allkeys>: hash, full key to part->display value (what's display value?)  
   
 =item B<allmaps>: hash, ???  
   
 =item B<fcat>: ???  
   
 =item B<defp>: hash, ???  
   
 =item B<mapp>: ??  
   
 =item B<symbp>: hash, id->full sym?  
   
 =back  
   
 =cut  
   
 sub extractResourceInformation {  sub extractResourceInformation {
     my $ids = shift;      my $ids = shift;
Line 934  sub extractResourceInformation { Line 1172  sub extractResourceInformation {
  $$typep{$id}=$1;   $$typep{$id}=$1;
  $$keyp{$id}='';   $$keyp{$id}='';
         $$uris{$id}=$srcf;          $$uris{$id}=$srcf;
  foreach (split(/\,/,&Apache::lonnet::metadata($srcf,'allpossiblekeys'))) {   foreach my $key (split(/\,/,&Apache::lonnet::metadata($srcf,'allpossiblekeys'))) {
     if ($_=~/^parameter\_(.*)/) {      next if ($key!~/^parameter_/);
  my $key=$_;  
 # Hidden parameters  # Hidden parameters
  if (&Apache::lonnet::metadata($srcf,$key.'.hidden') eq 'parm') {      next if (&Apache::lonnet::metadata($srcf,$key.'.hidden') eq 'parm');
     next;  
  }  
  my $display= &Apache::lonnet::metadata($srcf,$key.'.display');  
  my $name=&Apache::lonnet::metadata($srcf,$key.'.name');  
  my $part= &Apache::lonnet::metadata($srcf,$key.'.part');  
 #  #
 # allparms is a hash of parameter names  # allparms is a hash of parameter names
 #  #
       my $name=&Apache::lonnet::metadata($srcf,$key.'.name');
       if (!exists($$allparms{$name}) || $$allparms{$name} =~ m/^\s*$/ ) {
    my $display= &Apache::lonnet::metadata($srcf,$key.'.display');
  my $parmdis = $display;   my $parmdis = $display;
  $parmdis =~ s/\[Part.*$//g;   $parmdis =~ s/\s*\[Part.*$//g;
                 $$allparms{$name}=$parmdis;   $$allparms{$name}=$parmdis;
  $$defkeytype{$name}=&Apache::lonnet::metadata($srcf,$key.'.type');   if (ref($defkeytype)) {
       $$defkeytype{$name}=
    &Apache::lonnet::metadata($srcf,$key.'.type');
    }
       }
   
 #  #
 # allparts is a hash of all parts  # allparts is a hash of all parts
 #  #
  $$allparts{$part} = "Part: $part";      my $part= &Apache::lonnet::metadata($srcf,$key.'.part');
       $$allparts{$part} = &mt('Part: [_1]',$part);
 #  #
 # Remember all keys going with this resource  # Remember all keys going with this resource
 #  #
  if ($$keyp{$id}) {      if ($$keyp{$id}) {
     $$keyp{$id}.=','.$key;   $$keyp{$id}.=','.$key;
  } else {      } else {
     $$keyp{$id}=$key;   $$keyp{$id}=$key;
  }      }
 #  #
 # Put in order  # Put in order
 #   # 
                 unless ($$keyorder{$key}) {      unless ($$keyorder{$key}) {
                     $$keyorder{$key}=$keyordercnt;   $$keyorder{$key}=$keyordercnt;
                     $keyordercnt++;   $keyordercnt++;
  }  
   
     }      }
  }   }
  $$mapp{$id}=  
     &Apache::lonnet::declutter($resource->enclosing_map_src());  
  $$mapp{$mapid}=$$mapp{$id};   if (!exists($$mapp{$mapid})) {
  $$allmaps{$mapid}=$$mapp{$id};      $$mapp{$id}=
  if ($mapid eq '1') {   &Apache::lonnet::declutter($resource->enclosing_map_src());
     $$maptitles{$mapid}='Main Course Documents';      $$mapp{$mapid}=$$mapp{$id};
       $$allmaps{$mapid}=$$mapp{$id};
       if ($mapid eq '1') {
    $$maptitles{$mapid}=&mt('Main Course Documents');
       } else {
    $$maptitles{$mapid}=
       &Apache::lonnet::gettitle($$mapp{$id});    
       }
       $$maptitles{$$mapp{$id}}=$$maptitles{$mapid};
       $$symbp{$mapid}=$$mapp{$id}.'___(all)';
  } else {   } else {
     $$maptitles{$mapid}=&Apache::lonnet::gettitle(&Apache::lonnet::clutter($$mapp{$id}));      $$mapp{$id} = $$mapp{$mapid};
  }   }
  $$maptitles{$$mapp{$id}}=$$maptitles{$mapid};  
  $$symbp{$id}=&Apache::lonnet::encode_symb($$mapp{$id},$resid,$srcf);   $$symbp{$id}=&Apache::lonnet::encode_symb($$mapp{$id},$resid,$srcf);
  $$symbp{$mapid}=$$mapp{$id}.'___(all)';  
     }      }
 }  }
   
   
 ##################################################  
 ##################################################  
   
 sub isdateparm {  sub isdateparm {
     my $type=shift;      my $type=shift;
Line 1063  sub parmmenu { Line 1308  sub parmmenu {
 </script>  </script>
 ENDSCRIPT  ENDSCRIPT
     $r->print();      $r->print();
     $r->print("\n<table id=\"LC_parm_overview_parm_menu\"><tr>");      $r->print("\n".'<table id="LC_parm_overview_parm_menu"><tr>');
     my $cnt=0;      my $cnt=0;
     foreach $tempkey (&keysindisplayorder($allparms,$keyorder)) {      foreach $tempkey (&keysindisplayorder($allparms,$keyorder)) {
  $r->print("\n<td><label><input type='checkbox' name='pscat' ");   $r->print("\n".'<td><label><input type="checkbox" name="pscat" ');
  $r->print('value="'.$tempkey.'"');   $r->print('value="'.$tempkey.'"');
  if ($$pscat[0] eq "all" || grep $_ eq $tempkey, @{$pscat}) {   if ($$pscat[0] eq "all" || grep $_ eq $tempkey, @{$pscat}) {
     $r->print(' checked');      $r->print(' checked="checked"');
  }   }
  $r->print('>'.$$allparms{$tempkey}.'</label></td>');          my $displaykey;
           if ($$allparms{$tempkey}=~/\S/) {
               $displaykey = $$allparms{$tempkey};
           } else {
               $displaykey = $tempkey;
           }
           $displaykey =~ s/(\[|\])/~$1/g;
           $r->print(' />'.&mt($displaykey).'</label></td>');
   $cnt++;    $cnt++;
         if ($cnt==3) {          if ($cnt==3) {
     $r->print("</tr>\n<tr>");      $r->print("</tr>\n<tr>");
     $cnt=0;      $cnt=0;
  }   }
     }      }
     $r->print('      $r->print('</tr>'
 </tr><tr id=\"LC_parm_overview_parm_menu_selectors\"><td>               .'<tr id="LC_parm_overview_parm_menu_selectors">'
 <a href="javascript:checkall(true, \'pscat\')">Select&nbsp;All</a><br />               .'<td valign="top">'
 <a href="javascript:checkstandard()">Select&nbsp;Common&nbsp;Only</a>               .'<fieldset><legend><b>'.&mt('Parameter Selection').'</b></legend>'
 </td><td>               .'<span class="LC_nobreak">'
 <a href="javascript:checkdates()">Add&nbsp;Problem&nbsp;Dates</a>               .'&bull; <a href="javascript:checkall(true, \'pscat\')">'.&mt('Select All').'</a>'
 <a href="javascript:checkcontdates()">Add&nbsp;Content&nbsp;Dates</a><br />               .'</span>'
 <a href="javascript:checkdisset()">Add&nbsp;Discussion&nbsp;Settings</a>               .'<br />'
 <a href="javascript:checkvisi()">Add&nbsp;Visibilities</a><br />               .'<span class="LC_nobreak">'
 <a href="javascript:checkparts()">Add&nbsp;Part&nbsp;Parameters</a>               .'&bull; <a href="javascript:checkstandard()">'.&mt('Select Common Only').'</a>'
 </td><td>               .'</span>'
 <a href="javascript:checkall(false, \'pscat\')">Unselect&nbsp;All</a>               .'<br />'
 </td>               .'<span class="LC_nobreak">'
 ');               .'&bull; <a href="javascript:checkall(false, \'pscat\')">'.&mt('Unselect All').'</a>'
     $r->print('</tr></table>');               .'</span>'
                .'</fieldset>'
                .'</td>'
                .'<td colspan="2" valign="top">'
                .'<fieldset><legend><b>'.&mt('Add Selection for...').'</b></legend>'
                .'<span class="LC_nobreak">'
                .'&bull; <a href="javascript:checkdates()">'.&mt('Problem Dates').'</a>'
                .'</span>'
                .'<span class="LC_nobreak">'
                .' &bull; <a href="javascript:checkcontdates()">'.&mt('Content Dates').'</a>'
                .'</span>'
   #            .'<br />'
                .'<span class="LC_nobreak">'
                .' &bull; <a href="javascript:checkdisset()">'.&mt('Discussion Settings').'</a>'
                .'</span>'
                .'<span class="LC_nobreak">'
                .' &bull; <a href="javascript:checkvisi()">'.&mt('Visibilities').'</a>'
                .'</span>'
   #            .'<br />'
                .'<span class="LC_nobreak">'
                .' &bull; <a href="javascript:checkparts()">'.&mt('Part Parameters').'</a>'
                .'</span>'
                .'</fieldset>'
                .'</td>'
                .'</tr></table>'
       );
 }  }
   
 sub partmenu {  sub partmenu {
     my ($r,$allparts,$psprt)=@_;      my ($r,$allparts,$psprt)=@_;
     $r->print('<select multiple name="psprt" size="8">');      $r->print('<select multiple="multiple" name="psprt" size="8">');
     $r->print('<option value="all"');      $r->print('<option value="all"');
     $r->print(' selected') unless (@{$psprt});      $r->print(' selected="selected"') unless (@{$psprt});
     $r->print('>'.&mt('All Parts').'</option>');      $r->print('>'.&mt('All Parts').'</option>');
     my %temphash=();      my %temphash=();
     foreach (@{$psprt}) { $temphash{$_}=1; }      foreach (@{$psprt}) { $temphash{$_}=1; }
Line 1109  sub partmenu { Line 1386  sub partmenu {
  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');   $r->print(' selected="selected"');
     }      }
     $r->print('>'.$$allparts{$tempkey}.'</option>');      $r->print('>'.$$allparts{$tempkey}.'</option>');
  }   }
Line 1122  sub usermenu { Line 1399  sub usermenu {
     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();
     my %lt=&Apache::lonlocal::texthash(  
     'se'    => "Section",  
                     'gr'    => "Group",  
     'fu'    => "For User",  
     'oi'    => "or ID",  
     'ad'    => "at Domain"  
        );  
     my $sections='';      my $sections='';
     my %sectionhash = &Apache::loncommon::get_sections();      my %sectionhash = &Apache::loncommon::get_sections();
   
     my $groups;      my $groups;
     my %grouphash = &Apache::longroup::coursegroups();      my %grouphash = &Apache::longroup::coursegroups();
   
       my $g_s_header='';
       my $g_s_footer='';
   
     if (%sectionhash) {      if (%sectionhash) {
         $sections=$lt{'se'}.': <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')" |;
         }          }
Line 1148  sub usermenu { Line 1422  sub usermenu {
         }          }
         $sections.='</select>';          $sections.='</select>';
     }      }
   
     if (%sectionhash && %grouphash && $parmlev ne 'full') {      if (%sectionhash && %grouphash && $parmlev ne 'full') {
         $sections .= '&nbsp;or&nbsp;';          $sections .= '&nbsp;'.&mt('or').'&nbsp;';
         $sections .= qq|          $sections .= qq|
 <script type="text/javascript">  <script type="text/javascript">
 function group_or_section(caller) {  function group_or_section(caller) {
Line 1176  function group_or_section(caller) { Line 1451  function group_or_section(caller) {
     }       } 
   
     if (%grouphash) {      if (%grouphash) {
         $groups=$lt{'gr'}.': <select name="cgroup"';          $groups=&mt('Group:').' <select name="cgroup"';
         if (%sectionhash && $env{'form.action'} eq 'settable') {          if (%sectionhash && $env{'form.action'} eq 'settable') {
             $groups .= qq| onchange="group_or_section('cgroup')" |;              $groups .= qq| onchange="group_or_section('cgroup')" |;
         }          }
Line 1198  function group_or_section(caller) { Line 1473  function group_or_section(caller) {
         }          }
         $groups.='</select>';          $groups.='</select>';
     }      }
     $r->print(<<ENDMENU);  
 <b>      if (%sectionhash || %grouphash) {
 $sections          $g_s_header='<fieldset><legend>'.&mt('Group/Section').'</legend><div>';
 $groups          $g_s_footer='</div></fieldset>';
 <br />      }
 $lt{'fu'}   
 <input type="text" value="$uname" size="12" name="uname" />      $r->print('<b>'
 $lt{'oi'}               .$g_s_header
 <input type="text" value="$id" size="12" name="id" />                .$sections
 $lt{'ad'}               .$groups
 $chooseopt               .$g_s_footer
 </b>               .'<fieldset><legend>'.&mt('User').'</legend><div>'
 ENDMENU               .&mt('For User [_1] or Student/Employee ID [_2] at Domain [_3]'
                    ,'<input type="text" value="'.$uname.'" size="12" name="uname" />'
                    ,'<input type="text" value="'.$id.'" size="12" name="id" /> '
                    ,$chooseopt)
                .'</div></fieldset>'
                .'</b>'
       );
 }  }
   
 sub displaymenu {  sub displaymenu {
Line 1218  sub displaymenu { Line 1499  sub displaymenu {
     $r->print('<table border="1"><tr><th>'.&mt('Select Parameters to View').'</th><th>'.      $r->print('<table border="1"><tr><th>'.&mt('Select Parameters to View').'</th><th>'.
      &mt('Select Parts to View').'</th></tr><tr><td>');         &mt('Select Parts to View').'</th></tr><tr><td>');  
     &parmmenu($r,$allparms,$pscat,$keyorder);      &parmmenu($r,$allparms,$pscat,$keyorder);
     $r->print('</td><td>');      $r->print('</td><td valign="top" align="center">');
     &partmenu($r,$allparts,$psprt);      &partmenu($r,$allparts,$psprt);
     $r->print('</td></tr></table>');      $r->print('</td></tr></table>');
 }  }
Line 1230  sub mapmenu { Line 1511  sub mapmenu {
     $r->print('<option value="all">'.&mt('All Maps or Folders').'</option>');      $r->print('<option value="all">'.&mt('All Maps or Folders').'</option>');
     foreach (sort {$$allmaps{$a} cmp $$allmaps{$b}} keys %{$allmaps}) {      foreach (sort {$$allmaps{$a} cmp $$allmaps{$b}} keys %{$allmaps}) {
  $r->print('<option value="'.$_.'"');   $r->print('<option value="'.$_.'"');
  if (($pschp eq $_)) { $r->print(' selected'); }   if (($pschp eq $_)) { $r->print(' selected="selected"'); }
  $r->print('>'.$$maptitles{$_}.($$allmaps{$_}!~/^uploaded/?' ['.$$allmaps{$_}.']':'').'</option>');   $r->print('>'.$$maptitles{$_}.($$allmaps{$_}!~/^uploaded/?' ['.$$allmaps{$_}.']':'').'</option>');
     }      }
     $r->print("</select>");      $r->print("</select>");
Line 1244  sub levelmenu { Line 1525  sub levelmenu {
     foreach (reverse sort keys %{$alllevs}) {      foreach (reverse sort keys %{$alllevs}) {
  $r->print('<option value="'.$$alllevs{$_}.'"');   $r->print('<option value="'.$$alllevs{$_}.'"');
  if ($parmlev eq $$alllevs{$_}) {   if ($parmlev eq $$alllevs{$_}) {
     $r->print(' selected');       $r->print(' selected="selected"'); 
  }   }
  $r->print('>'.$_.'</option>');   $r->print('>'.&mt($_).'</option>');
     }      }
     $r->print("</select>");      $r->print("</select>");
 }  }
Line 1257  sub sectionmenu { Line 1538  sub sectionmenu {
     my %sectionhash = &Apache::loncommon::get_sections();      my %sectionhash = &Apache::loncommon::get_sections();
     return if (!%sectionhash);      return if (!%sectionhash);
   
     $r->print('<select name="Section" multiple="true" size="8" >');      $r->print('<select name="Section" multiple="multiple" size="8">');
     foreach my $s ('all',sort keys %sectionhash) {      foreach my $s ('all',sort keys %sectionhash) {
  $r->print('    <option value="'.$s.'"');   $r->print('    <option value="'.$s.'"');
  foreach (@{$selectedsections}) {   foreach (@{$selectedsections}) {
     if ($s eq $_) {      if ($s eq $_) {
  $r->print(' selected');   $r->print(' selected="selected"');
  last;   last;
     }      }
  }   }
Line 1276  sub groupmenu { Line 1557  sub groupmenu {
     my %grouphash = &Apache::longroup::coursegroups();      my %grouphash = &Apache::longroup::coursegroups();
     return if (!%grouphash);      return if (!%grouphash);
   
     $r->print('<select name="Group" multiple="true" size="8" >');      $r->print('<select name="Group" multiple="multiple" size="8">');
     foreach my $group (sort(keys(%grouphash))) {      foreach my $group (sort(keys(%grouphash))) {
  $r->print('    <option value="'.$group.'"');   $r->print('    <option value="'.$group.'"');
  foreach (@{$selectedgroups}) {   foreach (@{$selectedgroups}) {
     if ($group eq $_) {      if ($group eq $_) {
  $r->print(' selected');   $r->print(' selected="selected"');
  last;   last;
     }      }
  }   }
Line 1326  sub sortmenu { Line 1607  sub sortmenu {
     my ($r,$sortorder)=@_;      my ($r,$sortorder)=@_;
     $r->print('<br /><label><input type="radio" name="sortorder" value="realmstudent"');      $r->print('<br /><label><input type="radio" name="sortorder" value="realmstudent"');
     if ($sortorder eq 'realmstudent') {      if ($sortorder eq 'realmstudent') {
        $r->print(' checked="on"');         $r->print(' checked="checked"');
     }      }
     $r->print(' />'.&mt('Sort by realm first, then student (group/section)'));      $r->print(' />'.&mt('Sort by realm first, then student (group/section)'));
     $r->print('</label><br /><label><input type="radio" name="sortorder" value="studentrealm"');      $r->print('</label><br /><label><input type="radio" name="sortorder" value="studentrealm"');
     if ($sortorder eq 'studentrealm') {      if ($sortorder eq 'studentrealm') {
        $r->print(' checked="on"');         $r->print(' checked="checked"');
     }      }
     $r->print(' />'.&mt('Sort by student (group/section) first, then realm').      $r->print(' />'.&mt('Sort by student (group/section) first, then realm').
       '</label>');        '</label>');
Line 1360  sub standardkeyorder { Line 1641  sub standardkeyorder {
             'parameter_0_discusshide' => 20);              'parameter_0_discusshide' => 20);
 }  }
   
 ##################################################  
 ##################################################  
   
 =pod  
   
 =item assessparms  
   
 Show assessment data and parameters.  This is a large routine that should  
 be simplified and shortened... someday.  
   
 Inputs: $r  
   
 Returns: nothing  
   
 Variables used (guessed by Jeremy):  
   
 =over 4  
   
 =item B<pscat>: ParameterS CATegories? ends up a list of the types of parameters that exist, e.g., tol, weight, acc, opendate, duedate, answerdate, sig, maxtries, type.  
   
 =item B<psprt>: ParameterS PaRTs? a list of the parts of a problem that we are displaying? Used to display only selected parts?  
   
 =item B<allmaps>:  
   
 =back  
   
 =cut  
   
 ##################################################  
 ##################################################  
 sub assessparms {  sub assessparms {
   
     my $r=shift;      my $r=shift;
Line 1563  sub assessparms { Line 1815  sub assessparms {
     foreach ('tolerance','date_default','date_start','date_end',      foreach ('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="'.
   $env{'form.recent_'.$_}.'" name="recent_'.$_.'" />');    &HTML::Entities::encode($env{'form.recent_'.$_},'"&<>').
     '" name="recent_'.$_.'" />');
     }      }
                                                   
     if (!$pssymb) {      if (!$pssymb) {
         $r->print('<table border="1"><tr><td>');          $r->print('<table border="1"><tr><td>');
         &levelmenu($r,\%alllevs,$parmlev);          &levelmenu($r,\%alllevs,$parmlev);
           $r->print('</td>');
  if ($parmlev ne 'general') {   if ($parmlev ne 'general') {
             $r->print('<td>');              $r->print('<td>');
     &mapmenu($r,\%allmaps,$pschp,\%maptitles);      &mapmenu($r,\%allmaps,$pschp,\%maptitles);
     $r->print('</td>');      $r->print('</td>');
  }   }
         $r->print('</td></tr></table>');          $r->print('</tr></table>');
  &displaymenu($r,\%allparms,\%allparts,\@pscat,\@psprt,\%keyorder);   &displaymenu($r,\%allparms,\%allparts,\@pscat,\@psprt,\%keyorder);
     } else {      } else {
         my ($map,$id,$resource)=&Apache::lonnet::decode_symb($pssymb);          my ($map,$id,$resource)=&Apache::lonnet::decode_symb($pssymb);
Line 1611  sub assessparms { Line 1865  sub assessparms {
               $coursespan += 3;                $coursespan += 3;
            }              } 
               
            $r->print('<p><table border=2>');             $r->print('<p><table border="2">');
            $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 ++;
Line 1639  sub assessparms { Line 1893  sub assessparms {
   '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 $lt{'at'} $csudom)</th>  <th rowspan="3">$lt{'csv'}<br />($csuname $lt{'at'} $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="2">$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="3">'.
   &mt("in Section")." $csec</th>");    &mt("in Section")." $csec</th>");
            }             }
            if ($cgroup) {             if ($cgroup) {
                 $r->print("<th colspan=3>".                  $r->print('<th colspan="3">'.
                           &mt("in Group")." $cgroup</th>");                            &mt("in Group")." $cgroup</th>");
            }             }
            $r->print(<<ENDTABLEHEADFOUR);             $r->print(<<ENDTABLEHEADFOUR);
Line 1691  ENDTABLEHEADFOUR Line 1945  ENDTABLEHEADFOUR
     ||      ||
     ($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';
                     } else {                      } else {
                         $defbgone='"#E0E099"';                          $defbgone='#E0E099';
                     }                      }
                     if ($defbgtwo eq '"#FFFF99"') {                      if ($defbgtwo eq '#FFFF99') {
                         $defbgtwo='"#FFFFDD"';                          $defbgtwo='#FFFFDD';
                     } else {                      } else {
                         $defbgtwo='"#FFFF99"';                          $defbgtwo='#FFFF99';
                     }                      }
                     if ($defbgthree eq '"#FFBB99"') {                      if ($defbgthree eq '#FFBB99') {
                         $defbgthree='"#FFBBDD"';                          $defbgthree='#FFBBDD';
                     } else {                      } else {
                         $defbgthree='"#FFBB99"';                          $defbgthree='#FFBB99';
                     }                      }
   
                     my $thistitle='';                      my $thistitle='';
Line 1733  ENDTABLEHEADFOUR Line 1987  ENDTABLEHEADFOUR
                     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 bgcolor='.$defbgone.                          $r->print('<tr><td style="background-color:'.$defbgone.';"'.
                              ' rowspan='.$totalparms.                               ' rowspan='.$totalparms.
                              '><tt><font size=-1>'.                               '><tt><font size="-1">'.
                              join(' / ',split(/\//,$uri)).                               join(' / ',split(/\//,$uri)).
                              '</font></tt><p><b>'.                               '</font></tt><p><b>'.
                              "<a href=\"javascript:openWindow('".                               "<a href=\"javascript:openWindow('".
Line 1748  ENDTABLEHEADFOUR Line 2002  ENDTABLEHEADFOUR
                             $r->print(' ('.$thistitle.')');                              $r->print(' ('.$thistitle.')');
                         }                          }
                         $r->print('</a></b></td>');                          $r->print('</a></b></td>');
                         $r->print('<td bgcolor='.$defbgtwo.                          $r->print('<td style="background-color:'.$defbgtwo.';"'.
                                       ' rowspan='.$totalparms.'>'.$typep{$rid}.                                        ' rowspan='.$totalparms.'>'.$typep{$rid}.
                                       '</td>');                                        '</td>');
   
                         $r->print('<td bgcolor='.$defbgone.                          $r->print('<td style="background-color:'.$defbgone.';"'.
                                       ' rowspan='.$totalparms.                                        ' rowspan='.$totalparms.
                                       '>'.$maptitles{$mapp{$rid}}.'</td>');                                        '>'.$maptitles{$mapp{$rid}}.'</td>');
   
Line 1775  ENDTABLEHEADFOUR Line 2029  ENDTABLEHEADFOUR
         } # end of  full          } # end of  full
 #--------------------------------------------------- Entry for parm level map  #--------------------------------------------------- Entry for parm level map
         if ($parmlev eq 'map') {          if ($parmlev eq 'map') {
             my $defbgone = '"E0E099"';              my $defbgone = '#E0E099';
             my $defbgtwo = '"FFFF99"';              my $defbgtwo = '#FFFF99';
             my $defbgthree = '"FFBB99"';              my $defbgthree = '#FFBB99';
   
             my %maplist;              my %maplist;
   
Line 1842  ENDTABLEHEADFOUR Line 2096  ENDTABLEHEADFOUR
 #---------------------------------------------------- print header information  #---------------------------------------------------- print header information
                 my $foldermap=&mt($maptitle=~/^uploaded/?'Folder':'Map');                  my $foldermap=&mt($maptitle=~/^uploaded/?'Folder':'Map');
                 my $showtitle=$maptitles{$maptitle}.($maptitle!~/^uploaded/?' ['.$maptitle.']':'');                  my $showtitle=$maptitles{$maptitle}.($maptitle!~/^uploaded/?' ['.$maptitle.']':'');
                 $r->print(<<ENDMAPONE);                  my $tmp="";
 <center><h4>  
 Set Defaults for All Resources in $foldermap<br />  
 <font color="red"><i>$showtitle</i></font><br />  
 Specifically for  
 ENDMAPONE  
                 if ($uname) {                  if ($uname) {
     my $person=&Apache::loncommon::plainname($uname,$udom);      my $person=&Apache::loncommon::plainname($uname,$udom);
                     $r->print(&mt("User")." <font color=\"red\"><i>$uname \($person\) </i></font> ".                      $tmp.=&mt("User")." <font color=\"red\"><i>$uname \($person\) </i></font> ".
                         &mt('in')." \n");                          &mt('in')." \n";
                 } else {                  } else {
                     $r->print("<font color=\"red\"><i>".&mt('all').'</i></font> '.&mt('users in')." \n");                      $tmp.="<font color=\"red\"><i>".&mt('all').'</i></font> '.&mt('users in')." \n";
                 }                  }
                 if ($cgroup) {                  if ($cgroup) {
                     $r->print(&mt("Group")." <font color=\"red\"><i>$cgroup".                      $tmp.=&mt("Group")." <font color=\"red\"><i>$cgroup".
                               "</i></font> ".&mt('of')." \n");                                "</i></font> ".&mt('of')." \n";
                     $csec = '';                      $csec = '';
                 } elsif ($csec) {                  } elsif ($csec) {
                     $r->print(&mt("Section")." <font color=\"red\"><i>$csec".                      $tmp.=&mt("Section")." <font color=\"red\"><i>$csec".
                               "</i></font> ".&mt('of')." \n");                                "</i></font> ".&mt('of')." \n";
                 }                  }
                 $r->print("<font color=\"red\"><i>$coursename</i></font><br />");                  $r->print('<div align="center"><h4>'
                 $r->print("</h4>\n");                           .&mt('Set Defaults for All Resources in [_1]Specifically for [_2][_3]'
                                ,$foldermap.'<br /><font color="red"><i>'.$showtitle.'</i></font><br />'
                                ,$tmp
                                ,'<font color="red"><i>'.$coursename.'</i></font>'
                                )
                            ."<br /></h4>\n"
                   );
 #---------------------------------------------------------------- print table  #---------------------------------------------------------------- print table
                 $r->print('<p><table border="2">');                  $r->print('<p>'.&Apache::loncommon::start_data_table()
                 $r->print('<tr><th>'.&mt('Parameter Name').'</th>');                           .&Apache::loncommon::start_data_table_header_row()
                 $r->print('<th>'.&mt('Default Value').'</th>');                           .'<th>'.&mt('Parameter Name').'</th>'
                 $r->print('<th>'.&mt('Parameter in Effect').'</th></tr>');                           .'<th>'.&mt('Default Value').'</th>'
                            .'<th>'.&mt('Parameter in Effect').'</th>'
                            .&Apache::loncommon::end_data_table_header_row()
                   );
   
         foreach (&keysinorder(\%name,\%keyorder)) {          foreach (&keysinorder(\%name,\%keyorder)) {
                     $r->print('<tr>');                      $r->print(&Apache::loncommon::start_data_table_row());
                     &print_row($r,$_,\%part,\%name,\%symbp,$mapid,\%default,                      &print_row($r,$_,\%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);
                 }                  }
                 $r->print("</table></center>");                  $r->print(&Apache::loncommon::end_data_table().'</p>'
                            .'</div>'
                   );
             } # end each map              } # end each map
         } # end of $parmlev eq map          } # end of $parmlev eq map
 #--------------------------------- Entry for parm level general (Course level)  #--------------------------------- Entry for parm level general (Course level)
         if ($parmlev eq 'general') {          if ($parmlev eq 'general') {
             my $defbgone = '"E0E099"';              my $defbgone = '#E0E099';
             my $defbgtwo = '"FFFF99"';              my $defbgtwo = '#FFFF99';
             my $defbgthree = '"FFBB99"';              my $defbgthree = '#FFBB99';
   
 #-------------------------------------------- for each map, gather information  #-------------------------------------------- for each map, gather information
             my $mapid="0.0";              my $mapid="0.0";
Line 1928  ENDMAPONE Line 2188  ENDMAPONE
 #---------------------------------------------------- print header information  #---------------------------------------------------- print header information
     my $setdef=&mt("Set Defaults for All Resources in Course");      my $setdef=&mt("Set Defaults for All Resources in Course");
             $r->print(<<ENDMAPONE);              $r->print(<<ENDMAPONE);
 <center><h4>$setdef  <center>
   <h4>$setdef
 <font color="red"><i>$coursename</i></font><br />  <font color="red"><i>$coursename</i></font><br />
 ENDMAPONE  ENDMAPONE
             if ($uname) {              if ($uname) {
Line 1942  ENDMAPONE Line 2203  ENDMAPONE
             if ($cgroup) {$r->print(&mt("Group")."<font color=\"red\"> <i>$cgroup</i></font>\n")};              if ($cgroup) {$r->print(&mt("Group")."<font color=\"red\"> <i>$cgroup</i></font>\n")};
             $r->print("</h4>\n");              $r->print("</h4>\n");
 #---------------------------------------------------------------- print table  #---------------------------------------------------------------- print table
             $r->print('<p><table border="2">');              $r->print('<p>'.&Apache::loncommon::start_data_table()
             $r->print('<tr><th>'.&mt('Parameter Name').'</th>');                       .&Apache::loncommon::start_data_table_header_row()
             $r->print('<th>'.&mt('Default Value').'</th>');                       .'<th>'.&mt('Parameter Name').'</th>'
             $r->print('<th>'.&mt('Parameter in Effect').'</th></tr>');                       .'<th>'.&mt('Default Value').'</th>'
                        .'<th>'.&mt('Parameter in Effect').'</th>'
                        .&Apache::loncommon::end_data_table_header_row()
               );
   
     foreach (&keysinorder(\%name,\%keyorder)) {      foreach (&keysinorder(\%name,\%keyorder)) {
                 $r->print('<tr>');                  $r->print(&Apache::loncommon::start_data_table_row());
                 &print_row($r,$_,\%part,\%name,\%symbp,$mapid,\%default,                  &print_row($r,$_,\%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);
             }              }
             $r->print("</table></center>");              $r->print(&Apache::loncommon::end_data_table()
                        .'</p>'
                        .'</center>'
               );
         } # end of $parmlev eq general          } # end of $parmlev eq general
     }      }
     $r->print('</form>'.&Apache::loncommon::end_page());      $r->print('</form>'.&Apache::loncommon::end_page());
 } # end sub assessparms  } # end sub assessparms
   
   
 ##################################################  
 ##################################################  
   
 =pod  
   
 =item crsenv  
   
 Show and set course data and parameters.  This is a large routine that should  
 be simplified and shortened... someday.  
   
 Inputs: $r  
   
 Returns: nothing  
   
 =cut  
   
 ##################################################  
 ##################################################  
 sub crsenv {  sub crsenv {
     my $r=shift;      my $r=shift;
     my $setoutput='';      my $setoutput='';
   
       &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=crsenv',
    text=>"Course Environment"});
     my $breadcrumbs =       my $breadcrumbs = 
  &Apache::lonhtmlcommon::breadcrumbs('Edit Course Environment');   &Apache::lonhtmlcommon::breadcrumbs('Edit Course Environment');
     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 (%crsinfo,$chome);
   
     #      #
     # Go through list of changes      # Go through list of changes
     foreach (keys %env) {      foreach (keys %env) {
Line 2034  sub crsenv { Line 2288  sub crsenv {
         if ($name =~ /^default_enrollment_(start|end)_date$/) {          if ($name =~ /^default_enrollment_(start|end)_date$/) {
             $value=&Apache::lonhtmlcommon::get_date_from_form($name.'_value');              $value=&Apache::lonhtmlcommon::get_date_from_form($name.'_value');
         }          }
    #
           # Deal with the emails
           if ($name =~ /\.email$/) {
       foreach my $specifier (split(',',$value)) {
    my ($user,$sections_or_groups)=
       ($specifier=~/^([^\(]+)\(([^\)]+)\)/);
    if (!$sections_or_groups) {
       $user = $specifier;
    }
    my ($name,$domain) = split(':',$user);
    if (!defined($user) || !defined($domain)) {
       $setoutput.= '<br /> <span class="LC_error">'.
    &mt("Invalid e-mail address specified, address must be of the form username:domain what was specified was ([_1])",$user).
    '</span>';
       undef($value);
    } elsif (&Apache::lonnet::homeserver($user,$domain) eq 'no_host') {
       $setoutput.= '<br /> <span class="LC_error">'.
    &mt("Invalid e-mail address specified, user [_1] is unknown.",$name).
    '</span>';
       undef($value);
    }
       }
           }
         # Get existing cloners          # Get existing cloners
         my @oldcloner = ();          my @oldcloner = ();
         if ($name eq 'cloners') {          if ($name eq 'cloners') {
Line 2047  sub crsenv { Line 2324  sub crsenv {
         #          #
         # Let the user know we made the changes          # Let the user know we made the changes
         if ($name && defined($value)) {          if ($name && defined($value)) {
             my $failed_cloners;              my %failed_cloners;
             if ($name eq 'cloners') {              if ($name eq 'cloners') {
                 $value =~ s/\s//g;                  $value =~ s/\s//g;
                 $value =~ s/^,//;                  $value =~ s/^,//;
                 $value =~ s/,$//;                  $value =~ s/,$//;
                 # check requested clones are valid users.                  # check requested clones are valid users.
                 $failed_cloners = &check_cloners(\$value,\@oldcloner);                  %failed_cloners = &check_cloners(\$value,\@oldcloner);
             }              }
             my $put_result = &Apache::lonnet::put('environment',              my $put_result = &Apache::lonnet::put('environment',
                                                   {$name=>$value},$dom,$crs);                                                    {$name=>$value},$dom,$crs);
             if ($put_result eq 'ok') {              if ($put_result eq 'ok') {
                 $setoutput.=&mt('Set').' <b>'.$name.'</b> '.&mt('to').' <b>'.$value.'</b>.<br />';                  $setoutput.=&mt('Set').' <b>'.$name.'</b> '.&mt('to').' <b>';
                   if ($name =~ /^default_enrollment_(start|end)_date$/) {
                       $setoutput .= &Apache::lonlocal::locallocaltime($value);
                   } elsif ($name eq 'categories') {
                       $setoutput .= $env{'form.categories_display'};
                   } else {
                       $setoutput .= $value;
                   }
                   $setoutput .= '</b>.<br />';
                 if ($name eq 'cloners') {                  if ($name eq 'cloners') {
                     &change_clone($value,\@oldcloner);                      &change_clone($value,\@oldcloner);
                 }                  }
                 # Flush the course logs so course description is immediately updated                  # Update environment and nohist_courseids.db
                   if (($name eq 'description') || ($name eq 'cloners') || 
                       ($name eq 'hidefromcat') || ($name eq 'categories')) {
                       if ($chome eq '') {
                           %crsinfo =
                               &Apache::lonnet::courseiddump($dom,'.',1,'.','.',
                                                    $crs,undef,undef,'.');
                           $chome = &Apache::lonnet::homeserver($crs,$dom);
                       }
                   }
                 if ($name eq 'description' && defined($value)) {                  if ($name eq 'description' && defined($value)) {
                     &Apache::lonnet::flushcourselogs();                      &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.description' => $value});
                       if (ref($crsinfo{$env{'request.course.id'}}) eq 'HASH') {
                           $crsinfo{$env{'request.course.id'}}{'description'} = $value; 
                           my $putresult =
                               &Apache::lonnet::courseidput($dom,\%crsinfo,
                                                            $chome,'notime');
                       }
                   }
                   if (($name eq 'cloners') || ($name eq 'hidefromcat') || ($name eq 'categories')) {
                       if (ref($crsinfo{$env{'request.course.id'}}) eq 'HASH') {
                           &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.'.$name => $value});
                           $crsinfo{$env{'request.course.id'}}{$name} = $value;
                           my $putresult =
                               &Apache::lonnet::courseidput($dom,\%crsinfo,
                                                            $chome,'notime');
                       }
                 }                  }
             } else {              } else {
                 $setoutput.=&mt('Unable to set').' <b>'.$name.'</b> '.&mt('to').                  $setoutput.=&mt('Unable to set').' <b>'.$name.'</b> '.&mt('to').
     ' <b>'.$value.'</b> '.&mt('due to').' '.$put_result.'.<br />';      ' <b>'.$value.'</b> '.&mt('due to').' '.$put_result.'.<br />';
             }              }
             if (($name eq 'cloners') && ($failed_cloners)) {              if (($name eq 'cloners') && (keys(%failed_cloners) > 0)) {
                 $setoutput.= &mt('Unable to include').' - <b>'.$failed_cloners.'</b>, '.                  $setoutput.= &mt('Unable to include').': ';
                  &mt('reason').' - '.&mt('LON-CAPA user(s) do(es) not exist').                  my @fails;
                  '.<br />'.&mt('Please ').                  my $num = 0;
                  ' <a href="/adm/createuser">'.                  if (defined($failed_cloners{'format'})) {
                  &mt('add the user(s)').'</a>, '.                      $fails[$num] .= '<b>'.$failed_cloners{'format'}.
                  &mt('and then return to the ').                                    '</b>, '.&mt('reason').' - '.
                  '<a href="/admparmset?action=crsenv">'.                                    &mt('Invalid format');
                  &mt('Course Parameters page').'</a> '.                      $num ++;
                  &mt('to add the new user(s) to the list of possible cloners').                  }
                  '.<br />';                  if (defined($failed_cloners{'domain'})) {
                       $fails[$num] .= '<b>'.$failed_cloners{'domain'}.
                                     '</b>, '.&mt('reason').' - '.
                                     &mt('Domain does not exist');
                       $num ++;
                   }
                   if (defined($failed_cloners{'newuser'})) {
                       $fails[$num] .= '<b>'.$failed_cloners{'newuser'}.                                   '</b>, '.&mt('reason').' - '.
                           &mt('LON-CAPA user(s) do(es) not exist.').
                           '.<br />'.&mt('Please ').
                           ' <a href="/adm/createuser">'.
                           &mt('add the user(s)').'</a>, '.
                           &mt('and then return to the ').
                           '<a href="/adm/parmset?action=crsenv">'.
                           &mt('Course Parameters page').'</a> '.
                           &mt('to add the new user(s) to the list of possible cloners');
                   }
                   $setoutput .= join(';&nbsp;&nbsp;',@fails).'.<br />';
             }              }
         }          }
     }      }
Line 2099  sub crsenv { Line 2425  sub crsenv {
     my $SelectStyleFile=&mt('Select Style File');      my $SelectStyleFile=&mt('Select Style File');
     my $SelectSpreadsheetFile=&mt('Select Spreadsheet File');      my $SelectSpreadsheetFile=&mt('Select Spreadsheet File');
     my $output='';      my $output='';
       my $can_categorize;
     if (! exists($values{'con_lost'})) {      if (! exists($values{'con_lost'})) {
         my %descriptions=          my %descriptions=
     ('url'            => '<b>'.&mt('Top Level Map').'</b> '.      ('url'            => '<b>'.&mt('Top Level Map').'</b><br />'.
                                  '<a href="javascript:openbrowser'.                                   '<a href="javascript:openbrowser'.
                                  "('envform','url','sequence')\">".                                   "('envform','url','sequence')\">".
                                  &mt('Select Map').'</a><br /><span class="LC_warning"> '.                                   &mt('Select Map').'</a><br /><span class="LC_warning"> '.
                                  &mt('Modification may make assessment data inaccessible').                                   &mt('Modification may make assessment data inaccessible!').
                                  '</span>',                                   '</span>',
              'description'    => '<b>'.&mt('Course Description').'</b>',               'description'    => '<b>'.&mt('Course Description').'</b>',
              'courseid'       => '<b>'.&mt('Course ID or number').               'courseid'       => '<b>'.&mt('Course ID or number').
                                  '</b><br />'.                                   '</b><br />'.
                                  '('.&mt('internal').', '.&mt('optional').')',                                   '('.&mt('internal, optional').')',
              'cloners'        => '<b>'.&mt('Users allowed to clone course').'</b><br /><tt>(user:domain,user:domain)</tt><br />'.&mt('Users with active Course Coordinator role in the course automatically have the right to clone it, and can be omitted from list.'),               'cloners'        => '<b>'.&mt('Users allowed to clone course').'</b><br />'
                                   .'("<tt>'.&mt('user:domain,user:domain,*:domain').'</tt>")<br />'
                                   .&mt('Users with active Course Coordinator role in this course are permitted to clone and need not be included.').'<br />'
                                   .&mt('Use [_1] to allow course to be cloned by anyone in the specified domain.','"<tt>*:domain</tt>"').'<br />'
                                   .&mt('Use [_1] to allow unrestricted cloning in all domains.','"<tt>*</tt>"'),
              'grading'        => '<b>'.&mt('Grading').'</b><br />'.               'grading'        => '<b>'.&mt('Grading').'</b><br />'.
                                  '<tt>"standard", "external", or "spreadsheet"</tt> '.&Apache::loncommon::help_open_topic('GradingOptions'),                                   &mt('[_1], [_2], or [_3]','"<tt>standard</tt>"','"<tt>external</tt>"','"<tt>spreadsheet</tt>"').&Apache::loncommon::help_open_topic('GradingOptions'),
              'default_xml_style' => '<b>'.&mt('Default XML Style File').'</b> '.       'task_grading'   => '<b>'.&mt('Bridge Task Grading').'</b><br />'
                                   .&mt('Instructors and TAs in sections, when grading bridge tasks, should be allowed to grade other sections.').'<br />'
                                   .'('.&mt('[_1]: they are allowed (this is the default). [_2]: no, they can only grade their own section.','"<tt>any</tt>"','"<tt>section</tt>"').')',
                'default_xml_style' => '<b>'.&mt('Default XML Style File').'</b><br />'.
                     '<a href="javascript:openbrowser'.                      '<a href="javascript:openbrowser'.
                     "('envform','default_xml_style'".                      "('envform','default_xml_style'".
                     ",'sty')\">$SelectStyleFile</a><br />",                      ",'sty')\">$SelectStyleFile</a><br />",
              'question.email' => '<b>'.&mt('Feedback Addresses for Resource Content Question').               'question.email' => '<b>'.&mt('Feedback Addresses for Resource Content Question').'</b><br />'
                                  '</b><br />(<tt>user:domain,'.                                  .'("<tt>'.&mt('user:domain,user:domain(section;section;...;*;...),...').'</tt>")',
                                  'user:domain(section;section;...;*;...),...</tt>)',               'question.email.text' => '<b>'.&mt('Custom Text for Resource Content Question Option in Feedback').'</b>',
              'comment.email'  => '<b>'.&mt('Feedback Addresses for Course Content Comments').'</b><br />'.               'comment.email'  => '<b>'.&mt('Feedback Addresses for Course Content Comments').'</b><br />'
                                  '(<tt>user:domain,user:domain(section;section;...;*;...),...</tt>)',                                  .'("<tt>'.&mt('user:domain,user:domain(section;section;...;*;...),...').'</tt>")',
              'policy.email'   => '<b>'.&mt('Feedback Addresses for Course Policy').'</b>'.               'comment.email.text' => '<b>'.&mt('Custom Text for Course Content Option in Feedback').'</b>',
                                  '<br />(<tt>user:domain,user:domain(section;section;...;*;...),...</tt>)',               'policy.email'   => '<b>'.&mt('Feedback Addresses for Course Policy').'</b><br />'
              'hideemptyrows'  => '<b>'.&mt('Hide Empty Rows in Spreadsheets').'</b><br />'.                                   .'("<tt>'.&mt('user:domain,user:domain(section;section;...;*;...),...').'</tt>")',
                                  '('.&mt('"[_1]" for default hiding','<tt>yes</tt>').')',               'policy.email.text' => '<b>'.&mt('Custom Text for Course Policy Option in Feedback').'</b>',
              'pageseparators'  => '<b>'.&mt('Visibly Separate Items on Pages').'</b><br />'.               'hideemptyrows'  => '<b>'.&mt('Hide Empty Rows in Spreadsheets').'</b><br />'
                                  '('.&mt('"[_1]" for visible separation','<tt>yes</tt>').', '.                                  .'('.&mt('[_1] for default hiding','"<tt>yes</tt>"').')',
                                  &mt('changes will not show until next login').')',               'pageseparators'  => '<b>'.&mt('Visibly Separate Items on Pages').'</b><br />'
              'student_classlist_view' => '<b>'.&mt('Allow students to view classlist.').'</b>'.&mt('("all":students can view all sections,"section":students can only view their own section.blank or "disabled" prevents student view.'),                                   .'('.&mt('[_1] for visible separation.','"<tt>yes</tt>"').' '
                                    .&mt('Changes will not show until next login.').')',
              'plc.roles.denied'=> '<b>'.&mt('Disallow live chatroom use for Roles').               'student_classlist_view' => '<b>'.&mt('Allow students to view classlist.').'</b><br />'
                                   '</b><br />"<tt>st</tt>": '.                                          .'('.&mt('[_1]: students can view all sections. [_2]: students can only view their own section. blank or [_3] prevents student view.','"<tt>all</tt>"','"<tt>section</tt>"','"<tt>disabled</tt>"').')',
                                   &mt('student').', "<tt>ta</tt>": '.               'student_classlist_portfiles' => '<b>'.&mt('Include link to accessible portfolio files').'</b><br />'
                                   'TA, "<tt>in</tt>": '.                                               .'('.&mt("[_1] for link to each a listing of each student's files.",'"<tt>yes</tt>"').')',
                                   &mt('instructor').';<br /><tt>'.&mt('role,role,...').'</tt>) '.               'student_classlist_opt_in' => '<b>'.&mt("Student's agreement needed for listing in student-viewable roster").'</b><br />'
        Apache::loncommon::help_open_topic("Course_Disable_Discussion"),                                             .'('.&mt('[_1] to require students to opt-in to listing in the roster (on the roster page).','"<tt>yes</tt>"').')',
                'plc.roles.denied'=> '<b>'.&mt('Disallow live chatroom use for Roles').'</b><br />'
                                    .'('.&mt('[_1]: student, [_2]: TA, [_3]: instructor','"<tt>st</tt>"','"<tt>ta</tt>"','"<tt>in</tt>"').')<br />'
                                    .'("<tt>'.&mt('role,role,...').'</tt>") '
                            .Apache::loncommon::help_open_topic("Course_Disable_Discussion"),
              'plc.users.denied' =>                'plc.users.denied' => 
                           '<b>'.&mt('Disallow live chatroom use for Users').'</b><br />'.                            '<b>'.&mt('Disallow live chatroom use for Users').'</b><br />'.
                                  '(<tt>user:domain,user:domain,...</tt>)',                                    '("<tt>'.&mt('user:domain,user:domain,...').'</tt>")',
   
              'pch.roles.denied'=> '<b>'.&mt('Disallow Resource Discussion for Roles').               'pch.roles.denied'=> '<b>'.&mt('Disallow Resource Discussion for Roles').'</b><br />'
                                   '</b><br />"<tt>st</tt>": '.                                   .'('.&mt('[_1]: student, [_2]: TA, [_3]: instructor','"<tt>st</tt>"','"<tt>ta</tt>"','"<tt>in</tt>"')
                                   'student, "<tt>ta</tt>": '.                                   .'("<tt>'.&mt('role,role,...').'</tt>") '
                                   'TA, "<tt>in</tt>": '.                                   .Apache::loncommon::help_open_topic("Course_Disable_Discussion"),
                                   'instructor;<br /><tt>role,role,...</tt>) '.  
        Apache::loncommon::help_open_topic("Course_Disable_Discussion"),  
              'pch.users.denied' =>                'pch.users.denied' => 
                           '<b>'.&mt('Disallow Resource Discussion for Users').'</b><br />'.                            '<b>'.&mt('Disallow Resource Discussion for Users').'</b><br />'.
                                  '(<tt>user:domain,user:domain,...</tt>)',                                   '("<tt>'.&mt('user:domain,user:domain,...').'</tt>")',
              'spreadsheet_default_classcalc'                'spreadsheet_default_classcalc' 
                  => '<b>'.&mt('Default Course Spreadsheet').'</b> '.                   => '<b>'.&mt('Default Course Spreadsheet').'</b> '.
                     '<a href="javascript:openbrowser'.                      '<a href="javascript:openbrowser'.
                     "('envform','spreadsheet_default_classcalc'".                      "('envform','spreadsheet_default_classcalc'".
                     ",'spreadsheet')\">$SelectSpreadsheetFile</a><br />",                      ",'spreadsheet')\">$SelectSpreadsheetFile</a><br />",
              'spreadsheet_default_studentcalc'                'spreadsheet_default_studentcalc' 
                  => '<b>'.&mt('Default Student Spreadsheet').'</b> '.                   => '<b>'.&mt('Default Student Spreadsheet').'</b><br />'.
                     '<a href="javascript:openbrowser'.                      '<a href="javascript:openbrowser'.
                     "('envform','spreadsheet_default_calc'".                      "('envform','spreadsheet_default_calc'".
                     ",'spreadsheet')\">$SelectSpreadsheetFile</a><br />",                      ",'spreadsheet')\">$SelectSpreadsheetFile</a><br />",
Line 2168  sub crsenv { Line 2504  sub crsenv {
                     ",'spreadsheet')\">$SelectSpreadsheetFile</a><br />",                      ",'spreadsheet')\">$SelectSpreadsheetFile</a><br />",
      'allow_limited_html_in_feedback'       'allow_limited_html_in_feedback'
          => '<b>'.&mt('Allow limited HTML in discussion posts').'</b><br />'.           => '<b>'.&mt('Allow limited HTML in discussion posts').'</b><br />'.
             '('.&mt('Set value to "[_1]" to allow',"<tt>yes</tt>").')',              '('.&mt('Set value to [_1] to allow.','"<tt>yes</tt>"').')',
              'allow_discussion_post_editing'               'allow_discussion_post_editing'
                  => '<b>'.&mt('Allow users with specified roles to edit/delete their own discussion posts').'</b><br />"<tt>st</tt>": '.                   => '<b>'.&mt('Allow users with specified roles to edit/delete their own discussion posts').'</b><br />'
                                   &mt('student').', "<tt>ta</tt>": '.                     .'('.&mt('[_1]: student, [_2]: TA, [_3]: instructor','"<tt>st</tt>"','"<tt>ta</tt>"','"<tt>in</tt>"').')<br />'
                                   'TA, "<tt>in</tt>": '.                     .'('.&mt('Set value to [_1] to allow all roles.','"<tt>yes</tt>"').')'
                                   &mt('instructor').';&nbsp;(<tt>'.&mt('role:section,role:section,..., e.g., st:001,st:002,in,cc would permit students in sections 001 and 002 and instructors in any section, and course coordinators to edit their own posts.').'</tt>)<br />'.                     .'("<tt>'.&mt('role:section,role:section,...').'</tt>")<br />'
                     '('.&mt('or set value to "[_1]" to allow all roles',"<tt>yes</tt>").')',                     .'('.&mt('Example: "<tt>st:001,st:002,in,cc</tt>" would permit students in sections 001 and 002 and instructors in any section, and course coordinators to edit their own posts.').')',
      'rndseed'       'rndseed'
          => '<b>'.&mt('Randomization algorithm used').'</b> <br />'.           => '<b>'.&mt('Randomization algorithm used').'</b><br />'
                     '<span class="LC_error">'.&mt('Modifying this will make problems').' '.                     .'<span class="LC_error">'
                     &mt('have different numbers and answers').'</span>',                     .&mt('Modifying this will make problems have different numbers and answers!')
                      .'</span>',
      'receiptalg'       'receiptalg'
          => '<b>'.&mt('Receipt algorithm used').'</b> <br />'.           => '<b>'.&mt('Receipt algorithm used').'</b> <br />'.
                     &mt('This controls how receipt numbers are generated.'),                      &mt('This controls how receipt numbers are generated.'),
              'suppress_tries'               'suppress_tries'
                  => '<b>'.&mt('Suppress number of tries in printing').'</b><br />'.                   => '<b>'.&mt('Suppress number of tries in printing').'</b><br />'.
                     ' ('.&mt('"[_1]" to suppress, anything else to not suppress','<tt>yes</tt>').')',                      ' ('.&mt('[_1] to suppress, anything else to not suppress','"<tt>yes</tt>"').')',
              'problem_stream_switch'               'problem_stream_switch'
                  => '<b>'.&mt('Allow problems to be split over pages').'</b><br />'.                   => '<b>'.&mt('Allow problems to be split over pages').'</b><br />'.
                     ' ('.&mt('"[_1]" if allowed, anything else if not','<tt>yes</tt>').')',                      ' ('.&mt('[_1] if allowed, anything else if not','"<tt>yes</tt>"').')',
              'default_paper_size'                'default_paper_size' 
                  => '<b>'.&mt('Default paper type').'</b><br />'.                   => '<b>'.&mt('Default paper type').'</b><br />'.
                     ' ('.&mt('supported types').': Letter [8 1/2x11 in], Legal [8 1/2x14 in],'.                       ' ('.&mt('supported types').': Letter [8 1/2x11 in], Legal [8 1/2x14 in],'. 
                     ' Tabloid [11x17 in], Executive [7 1/2x10 in], A2 [420x594 mm],'.                       ' Tabloid [11x17 in], Executive [7 1/2x10 in], A2 [420x594 mm],'. 
                     ' A3 [297x420 mm], A4 [210x297 mm], A5 [148x210 mm], A6 [105x148 mm])',                      ' A3 [297x420 mm], A4 [210x297 mm], A5 [148x210 mm], A6 [105x148 mm])',
      'print_header_format'       'print_header_format'
          => '<b>Print header format; substitutions</b>:  %n student name %c course id %a assignment note, numbers after the % limit the field size',           => ' <b>'.&mt('Print header format').'</b><br />'
              'anonymous_quiz'                     .&mt('Substitutions:<br />[_1]: student name, [_2]: course id, [_3]: assignment note. Numbers after the <tt>%</tt> limit the field size.','"<tt>%n</tt>"','"<tt>%c</tt>"','"<tt>%a</tt>"'),
                  => '<b>'.&mt('Anonymous quiz/exam').'</b><br />'.  
                     ' (<tt><b>'.&mt('yes').'</b> '.&mt('to avoid print students names').' </tt>)',  
              'default_enrollment_start_date' => '<b>'.&mt('Default beginning date for student access.').'</b>',               'default_enrollment_start_date' => '<b>'.&mt('Default beginning date for student access.').'</b>',
              'default_enrollment_end_date'   => '<b>'.&mt('Default ending date for student access.').'</b>',               'default_enrollment_end_date'   => '<b>'.&mt('Default ending date for student access.').'</b>',
              'nothideprivileged'   => '<b>'.&mt('Privileged users that should not be hidden on staff listings').'</b>'.               'nothideprivileged'   => '<b>'.&mt('Privileged users that should not be hidden on staff listings').'</b><br />'
                                  '<br />(<tt>user:domain,user:domain,...</tt>)',                                       .'("<tt>'.&mt('user:domain,user:domain,*:domain').'</tt>")',
              'languages' => '<b>'.&mt('Languages used').'</b>',               'languages' => '<b>'.&mt('Languages used').'</b>',
              'disable_receipt_display'               'disable_receipt_display'
                  => '<b>'.&mt('Disable display of problem receipts').'</b><br />'.                   => '<b>'.&mt('Disable display of problem receipts').'</b><br />'.
                     ' ('.&mt('"[_1]" to disable, anything else if not','<tt>yes</tt>').')',                      ' ('.&mt('"[_1]" to disable, anything else if not','<tt>yes</tt>').')',
      'task_messages'       'task_messages'
          => '<b>'.&mt('Send message to student when clicking Done on Tasks. [_1] to send a message only to student, [_2] to send message to student and add record to user information page for instructors. Leave blank to disable.','<tt>only_student</tt>','<tt>student_and_user_notes_screen</tt>').'</b>',           => '<b>'.&mt('Send message to student when clicking Done on Tasks').'</b><br /> ('.&mt('[_1] to send a message only to student, [_2] to send message to student and add record to user information page for instructors. Leave blank to disable.','"<tt>only_student</tt>"','"<tt>student_and_user_notes_screen</tt>"').')',
      'disablesigfigs'       'disablesigfigs'
          => '<b>'.&mt('Disable checking of Significant Figures').'</b><br />'.           => '<b>'.&mt('Disable checking of Significant Figures').'</b><br />'.
                     ' ('.&mt('"[_1]" to disable, anything else if not','<tt>yes</tt>').')',                      ' ('.&mt('"[_1]" to disable, anything else if not','<tt>yes</tt>').')',
Line 2217  sub crsenv { Line 2552  sub crsenv {
              'externalsyllabus'               'externalsyllabus'
                  => '<b>'.&mt('URL of Syllabus (not using internal handler)').'</b>',                   => '<b>'.&mt('URL of Syllabus (not using internal handler)').'</b>',
      'tthoptions'       'tthoptions'
          => '<b>'.&mt('Default set of options to pass to tth/m when converting tex').'</b>'           => '<b>'.&mt('Default set of options to pass to tth/m when converting tex').'</b>',
              );   
         my @Display_Order = ('url','description','courseid','cloners','grading',       'texengine'
            => '<b>'.&mt('Force all students in the course to use a specific math rendering engine.').'</b><br />'
                      .'('.&mt("[_1], [_2] (Convert to Images), [_3] (TeX to HTML), or blank for student's preference",'"<tt>jsMath</tt>"','"<tt>mimetex</tt>"','"<tt>tth</tt>"').')',
                'timezone'
                    => '<b>'.&mt('Timezone in which the course takes place').'</b>',
   
                'suppress_embed_prompt'
                    => '<b>'.&mt('Suppress prompt to upload items referenced in a web page being uploaded to portfolio, when current role is student.').'</b><br />'.
                       ' ('.&mt('[_1] to suppress, anything else to not suppress','"<tt>yes</tt>"').')',
                'hidefromcat'
                    => '<b>'.&mt('Exclude from course catalog').'</b><br />'.
                       ' ('.&mt('[_1] to exclude, anything else to include - included if assigned an institutional code, or manually catagorized','"<tt>yes</tt>"').')',
                'categories'
                    => '<b>'.&mt('Categorize course').'</b> <a href="javascript:catsbrowser()">'.
                       &mt('Display Categories').'</a>',
                'datelocale' 
                    => '<b>'.&mt('Locale used for course calendar').'</b>',
                );
           my @Display_Order = ('url','description','courseid','cloners');
           (my $can_toggle_cat,$can_categorize) = &can_modify_catsettings($dom);
           if ($can_toggle_cat) {
               push(@Display_Order,'hidefromcat');
           }
           if ($can_categorize) {
               push(@Display_Order,'categories');
           }
           push (@Display_Order,('grading',
                              'externalsyllabus',                               'externalsyllabus',
                              'default_xml_style','pageseparators',                               'default_xml_style','pageseparators',
                              'question.email','comment.email','policy.email',                               'question.email','question.email.text','comment.email',
                                'comment.email.text','policy.email','policy.email.text',
                              'student_classlist_view',                               'student_classlist_view',
                                'student_classlist_opt_in',
                                'student_classlist_portfiles',
                              'plc.roles.denied','plc.users.denied',                               'plc.roles.denied','plc.users.denied',
                              'pch.roles.denied','pch.users.denied',                               'pch.roles.denied','pch.users.denied',
                              'allow_limited_html_in_feedback',                               'allow_limited_html_in_feedback',
                              'allow_discussion_post_editing',                               'allow_discussion_post_editing',
                              'languages',                               'languages',
                                'timezone',
                                'datelocale',
      'nothideprivileged',       'nothideprivileged',
                              'rndseed',                               'rndseed',
                              'receiptalg',                               'receiptalg',
                              'problem_stream_switch',                               'problem_stream_switch',
      'suppress_tries',       'suppress_tries',
                                'suppress_embed_prompt',
                              'default_paper_size',                               'default_paper_size',
      'print_header_format',       'print_header_format',
                              'disable_receipt_display',                               'disable_receipt_display',
Line 2244  sub crsenv { Line 2611  sub crsenv {
                              'default_enrollment_start_date',                               'default_enrollment_start_date',
                              'default_enrollment_end_date',                               'default_enrollment_end_date',
      'tthoptions',       'tthoptions',
        'texengine',
      'disablesigfigs',       'disablesigfigs',
      'disableexampointprint',       'disableexampointprint',
      'task_messages'       'task_messages','task_grading'));
                              );  
  foreach my $parameter (sort(keys(%values))) {   foreach my $parameter (sort(keys(%values))) {
             unless (($parameter =~ m/^internal\./)||($parameter =~ m/^metadata\./)) {              unless (($parameter =~ m/^internal\./)||($parameter =~ m/^metadata\./) ||
                       ($parameter =~ m/^selfenroll_/) || ($parameter =~ /_selfenroll$/)
                       || ($parameter eq 'type')) {
                 if (! $descriptions{$parameter}) {                  if (! $descriptions{$parameter}) {
                     $descriptions{$parameter}=$parameter;                      $descriptions{$parameter}=$parameter;
                     push(@Display_Order,$parameter);                      push(@Display_Order,$parameter);
Line 2272  sub crsenv { Line 2641  sub crsenv {
                                                         $values{$parameter},                                                          $values{$parameter},
                                                         $onchange).                                                          $onchange).
                                                         '</td>';                                                          '</td>';
               } elsif ($parameter eq 'timezone') {
                   my $includeempty = 1;
                   my $timezone = &Apache::lonlocal::gettimezone();
                   $output .= '<td>'.
                       &Apache::loncommon::select_timezone($parameter.'_value',
                                                           $timezone,
                                                           $onchange,$includeempty).'</td>';
               } elsif ($parameter eq 'datelocale') {
                   my $includeempty = 1;
                   my $locale_obj = &Apache::lonlocal::getdatelocale();
                   my $currdatelocale;
                   if (ref($locale_obj)) {
                       $currdatelocale = $locale_obj->id();
                   }
                   $output .= '<td>'.
                       &Apache::loncommon::select_datelocale($parameter.'_value',
                                                             $currdatelocale,
                                                             $onchange,$includeempty).'</td>'; 
               } elsif ($parameter eq 'categories') {
                   my $catdisplay;
                   if ($values{'categories'} ne '') {
                       my @curritems = split(/\&/,$values{'categories'});
                       foreach my $item (@curritems) {
                           my ($name,$parent,$pos) = split(/:/,$item);
                           $catdisplay .= &unescape($name).'&';
                       }
                       $catdisplay =~ s/\&$//;
                   } 
                   $output .= '<td>'.
                              '<input type="hidden" name="categories_value" value="'.
                              $values{'categories'}.'" />'.
                              '<input type="textbox" name="categories_display" value="'.
                              $catdisplay.'" readonly="readonly" size="40" /></td>';
             } else {              } else {
                 $output .= '<td>'.                  $output .= '<td>'.
                     &Apache::lonhtmlcommon::textbox($parameter.'_value',                      &Apache::lonhtmlcommon::textbox($parameter.'_value',
Line 2288  sub crsenv { Line 2690  sub crsenv {
             '.checked=true;"';              '.checked=true;"';
  $output.=&Apache::loncommon::start_data_table_row().   $output.=&Apache::loncommon::start_data_table_row().
     '<td><i>'.&mt('Create New Environment Variable').'</i><br />'.      '<td><i>'.&mt('Create New Environment Variable').'</i><br />'.
     '<input type="text" size=40 name="newp_name" '.      '<input type="text" size="40" name="newp_name" '.
                 $onchange.' /></td><td>'.                  $onchange.' /></td><td>'.
             '<input type="text" size=40 name="newp_value" '.              '<input type="text" size="40" name="newp_value" '.
                 $onchange.' /></td><td>'.                  $onchange.' /></td><td>'.
     '<input type="checkbox" name="newp_setparmval" /></td>'.      '<input type="checkbox" name="newp_setparmval" /></td>'.
     &Apache::loncommon::end_data_table_row()."\n";      &Apache::loncommon::end_data_table_row()."\n";
Line 2298  sub crsenv { Line 2700  sub crsenv {
     my %lt=&Apache::lonlocal::texthash(      my %lt=&Apache::lonlocal::texthash(
     'par'   => 'Parameter',      'par'   => 'Parameter',
     'val'   => 'Value',      'val'   => 'Value',
     'set'   => 'Set',      'set'   => 'Set?',
     'sce'   => 'Set Course Environment'      'sav'   => 'Save'
        );         );
   
     my $Parameter=&mt('Parameter');      my $Parameter=&mt('Parameter');
     my $Value=&mt('Value');      my $Value=&mt('Value');
     my $Set=&mt('Set');      my $Set=&mt('Set');
     my $browse_js=      my ($jscript,$categorize_js);
  '<script type="text/javascript" language="Javascript">'.      my $browse_js = &Apache::loncommon::browser_and_searcher_javascript('parmset');
  &Apache::loncommon::browser_and_searcher_javascript('parmset').      if ($can_categorize) {
  '</script>';          $categorize_js = <<ENDSCRIPT;
       function catsbrowser() {
       var catswin = null;
       var url = '/adm/parmset?action=categorizecourse';
       if (!catswin || catswin.closed) {
           catswin=window.open(url,'categorieswin','height=480,width=600,resizable=yes,scrollbars=yes,location=no,menubar=no,toolbar=no');
       } else {
           catswin.focus();
       }
   } 
   ENDSCRIPT
       }
       $jscript = '<script type="text/javascript" language="Javascript">'."\n".
                  $browse_js."\n".$categorize_js."\n".'</script>';
     my $start_page =       my $start_page = 
  &Apache::loncommon::start_page('Set Course Environment',   &Apache::loncommon::start_page('Set Course Environment',
        $browse_js);         $jscript);
     my $end_page =       my $end_page = 
  &Apache::loncommon::end_page();   &Apache::loncommon::end_page();
     my $end_table=&Apache::loncommon::end_data_table();      my $end_table=&Apache::loncommon::end_data_table();
Line 2321  $start_page Line 2735  $start_page
 $breadcrumbs  $breadcrumbs
 <form method="post" action="/adm/parmset?action=crsenv" name="envform">  <form method="post" action="/adm/parmset?action=crsenv" name="envform">
 $setoutput  $setoutput
   <div><input type="submit" name="crsenv" value="$lt{'sav'}" /></div>
 $start_table  $start_table
 $start_header_row  $start_header_row
 <th>$lt{'par'}</th><th>$lt{'val'}</th><th>$lt{'set'}?</th>  <th>$lt{'par'}</th><th>$lt{'val'}</th><th>$lt{'set'}</th>
 $end_header_row  $end_header_row
 $output  $output
 $end_table  $end_table
 <input type="submit" name="crsenv" value="$lt{'sce'}">  <input type="submit" name="crsenv" value="$lt{'sav'}" />
 </form>  </form>
 $end_page  $end_page
 ENDENV  ENDENV
 }  }
   
   sub can_modify_catsettings {
       my ($dom) = @_;
       my %domconf = &Apache::lonnet::get_dom('configuration',['coursecategories'],$dom);
       my ($can_toggle_cat,$can_categorize);
       if (ref($domconf{'coursecategories'}) eq 'HASH') {
           if ($domconf{'coursecategories'}{'togglecats'} eq 'crs') {
               $can_toggle_cat = 1;
           }
           if ($domconf{'coursecategories'}{'categorize'} eq 'crs') {
               $can_categorize = 1;
           }
       }
       return ($can_toggle_cat,$can_categorize);
   }
   
   sub assign_course_categories {
       my ($r) = @_;
       my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
       my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
       my $hascats = 0;
       my $cathash;
       my %domconf = &Apache::lonnet::get_dom('configuration',['coursecategories'],$cdom);
       if (ref($domconf{'coursecategories'}) eq 'HASH') {
           $cathash = $domconf{'coursecategories'}{'cats'};
           if (ref($cathash) eq 'HASH') {
               $hascats = 1;   
           }
       }
       my $catwin_js;
       if ($hascats) {
           my $alert = &mt('Use \"Save\" in the main window to save course categories');
           $catwin_js = <<ENDSCRIPT;
   <script type="text/javascript">
   
   function updateCategories() {
       var newcategories = '';
       var unescapedcats = '';
       if (document.chgcats.usecategory.length) {
           for (var i=0; i<document.chgcats.usecategory.length; i++) {
               if (document.chgcats.usecategory[i].checked == true) {
                   newcategories = newcategories + document.chgcats.usecategory[i].value + '&';
                   unescapedcats = unescapedcats + document.chgcats.catname[i].value + ' & ';
               }
           }
           if (newcategories.length > 0) {
               newcategories = newcategories.slice(0,-1);
           }
           if (unescapedcats.length > 0) {
               unescapedcats = unescapedcats.slice(0,-3);
           }
       } else {
            if (document.chgcats.usecategory.checked == true) {
                newcategories = document.chgcats.usecategory.value;
                unescapedcats = document.chgcats.catname.value;
            }
       }
       opener.document.envform.categories_value.value = newcategories;
       opener.document.envform.categories_display.value = unescapedcats;
       opener.document.envform.categories_setparmval.checked = true;
       alert("$alert");
       self.close();
       return;
   }
   
   </script>
   ENDSCRIPT
       } else {
           my $onload; 
       }
       my $start_page =
           &Apache::loncommon::start_page('Course Categories',$catwin_js,
                                          {'only_body'      => 1,});
       my $end_page = &Apache::loncommon::end_page();
       my $categoriesform = '<h3>'.&mt('Categorize Course').'</h3>';
       if ($hascats) {
           my %currsettings =
               &Apache::lonnet::get('environment',['hidefromcat','categories'],$cdom,$cnum);
           $categoriesform .= &mt('Assign one or more categories to this course.').'<br /><br />'.
                                  '<form name="chgcats" action="/adm/parmset" method="post">'."\n"
                                  .&Apache::loncommon::assign_categories_table($cathash,
                                                          $currsettings{'categories'})."\n"
                                  .'<br /><input type="button" name="changes" value="'
                                  .&mt('Copy to main window').'" '
                                  .'onclick="javascript:updateCategories()" /></form><br />';
       } else {
           $categoriesform .= &mt('No categories defined for this domain');
       }
       $r->print($start_page.$categoriesform.$end_page);
       return;
   }
   
 ##################################################  ##################################################
 # Overview mode  # Overview mode
 ##################################################  ##################################################
Line 2400  sub storedata { Line 2907  sub storedata {
             if ($tuname) {              if ($tuname) {
  $tkey=~s/\.\[useropt\:$tuname\:$tudom\]\./\./;   $tkey=~s/\.\[useropt\:$tuname\:$tudom\]\./\./;
     }      }
     if ($cmd eq 'set') {      if ($cmd eq 'set' || $cmd eq 'datepointer' || $cmd eq 'dateinterval') {
  my $data=$env{$_};   my ($data, $typeof, $text);
                 my $typeof=$env{'form.typeof_'.$thiskey};   if ($cmd eq 'set') {
   if ($$olddata{$thiskey} ne $data) {       $data=$env{$_};
       $typeof=$env{'form.typeof_'.$thiskey};
       $text = &mt('Saved modified parameter for');
    } elsif ($cmd eq 'datepointer') {
       $data=&Apache::lonhtmlcommon::get_date_from_form($env{$_});
       $typeof=$env{'form.typeof_'.$thiskey};
       $text = &mt('Saved modified date for');
    } elsif ($cmd eq 'dateinterval') {
       $data=&get_date_interval_from_form($thiskey);
       $typeof=$env{'form.typeof_'.$thiskey};
       $text = &mt('Saved modified date for');
    }
    if (defined($data) and $$olddata{$thiskey} ne $data) { 
     if ($tuname) {      if ($tuname) {
  if (&Apache::lonnet::put('resourcedata',{$tkey=>$data,   if (&Apache::lonnet::put('resourcedata',{$tkey=>$data,
  $tkey.'.type' => $typeof},   $tkey.'.type' => $typeof},
  $tudom,$tuname) eq 'ok') {   $tudom,$tuname) eq 'ok') {
     &log_parmset({$tkey=>$data,$tkey.'.type' => $typeof},0,$tuname,$tudom);      &log_parmset({$tkey=>$data,$tkey.'.type' => $typeof},0,$tuname,$tudom);
     $r->print('<br />'.&mt('Stored modified parameter for').' '.      $r->print('<br />'.$text.' '.
       &Apache::loncommon::plainname($tuname,$tudom));        &Apache::loncommon::plainname($tuname,$tudom));
  } else {   } else {
     $r->print('<div class="LC_error">'.      $r->print('<div class="LC_error">'.
       &mt('Error storing parameters').'</div>');        &mt('Error saving parameters').'</div>');
  }   }
  &Apache::lonnet::devalidateuserresdata($tuname,$tudom);   &Apache::lonnet::devalidateuserresdata($tuname,$tudom);
     } else {      } else {
Line 2434  sub storedata { Line 2953  sub storedata {
  } else {   } else {
     push (@deldata,$thiskey,$thiskey.'.type');      push (@deldata,$thiskey,$thiskey.'.type');
  }   }
     } elsif ($cmd eq 'datepointer') {  
  my $data=&Apache::lonhtmlcommon::get_date_from_form($env{$_});  
                 my $typeof=$env{'form.typeof_'.$thiskey};  
  if (defined($data) and $$olddata{$thiskey} ne $data) {   
     if ($tuname) {  
  if (&Apache::lonnet::put('resourcedata',{$tkey=>$data,  
  $tkey.'.type' => $typeof},  
  $tudom,$tuname) eq 'ok') {  
     &log_parmset({$tkey=>$data,$tkey.'.type' => $typeof},0,$tuname,$tudom);  
     $r->print('<br />'.&mt('Stored modified date for').' '.&Apache::loncommon::plainname($tuname,$tudom));  
  } else {  
     $r->print('<div class="LC_error">'.  
       &mt('Error storing parameters').'</div>');  
  }  
  &Apache::lonnet::devalidateuserresdata($tuname,$tudom);  
     } else {  
  $newdata{$thiskey}=$data;  
  $newdata{$thiskey.'.type'}=$typeof;   
     }  
  }  
     }      }
  }   }
     }      }
Line 2475  sub storedata { Line 2974  sub storedata {
     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('Stored [_1] parameter(s)',$putentries/2).'</h3>');      $r->print('<h3>'.&mt('Saved [_1] parameter(s)',$putentries/2).'</h3>');
  } else {   } else {
     $r->print('<div class="LC_error">'.      $r->print('<div class="LC_error">'.
       &mt('Error storing parameters').'</div>');        &mt('Error saving parameters').'</div>');
  }   }
  &Apache::lonnet::devalidatecourseresdata($crs,$dom);   &Apache::lonnet::devalidatecourseresdata($crs,$dom);
     }      }
Line 2489  sub extractuser { Line 2988  sub extractuser {
     return ($key=~/^$env{'request.course.id'}.\[useropt\:($match_username)\:($match_domain)\]\./);      return ($key=~/^$env{'request.course.id'}.\[useropt\:($match_username)\:($match_domain)\]\./);
 }  }
   
   sub parse_listdata_key {
       my ($key,$listdata) = @_;
       # split into student/section affected, and
       # the realm (folder/resource part and parameter
       my ($student,$realm) = 
    ($key=~/^\Q$env{'request.course.id'}\E\.\[([^\.]+)\]\.(.+)$/);
       # if course wide student would be undefined
       if (!defined($student)) {
    ($realm)=($key=~/^\Q$env{'request.course.id'}\E\.(.+)$/);
       }
       # strip off the .type if it's not the Question type parameter
       if ($realm=~/\.type$/ && !exists($listdata->{$key.'.type'})) {
    $realm=~s/\.type//;
       }
       # split into resource+part and parameter name
       my ($res,    $parm) = ($realm=~/^(.*)\.(.*)$/);
          ($res, my $part) = ($res  =~/^(.*)\.(.*)$/);
       return ($student,$res,$part,$parm);
   }
   
 sub listdata {  sub listdata {
     my ($r,$resourcedata,$listdata,$sortorder)=@_;      my ($r,$resourcedata,$listdata,$sortorder)=@_;
 # Start list output  # Start list output
Line 2500  sub listdata { Line 3019  sub listdata {
     $tableopen=0;      $tableopen=0;
     my $foundkeys=0;      my $foundkeys=0;
     my %keyorder=&standardkeyorder();      my %keyorder=&standardkeyorder();
   
     foreach my $thiskey (sort {      foreach my $thiskey (sort {
    my ($astudent,$ares,$apart,$aparm) = &parse_listdata_key($a,$listdata);
    my ($bstudent,$bres,$bpart,$bparm) = &parse_listdata_key($b,$listdata);
   
    # get the numerical order for the param
    $aparm=$keyorder{'parameter_0_'.$aparm};
    $bparm=$keyorder{'parameter_0_'.$bparm};
   
    my $result=0;
   
  if ($sortorder eq 'realmstudent') {   if ($sortorder eq 'realmstudent') {
     my ($astudent,$arealm)=($a=~/^\Q$env{'request.course.id'}\E\.\[([^\.]+)\]\.(.+)\.[^\.]+$/);              if ($ares     ne $bres    ) {
     my ($bstudent,$brealm)=($b=~/^\Q$env{'request.course.id'}\E\.\[([^\.]+)\]\.(.+)\.[^\.]+$/);   $result = ($ares     cmp $bres);
     if (!defined($astudent)) {              } elsif ($astudent ne $bstudent) { 
  ($arealm)=($a=~/^\Q$env{'request.course.id'}\E\.(.+)$/);   $result = ($astudent cmp $bstudent);
     }      } elsif ($apart    ne $bpart   ) {
     if (!defined($bstudent)) {   $result = ($apart    cmp $bpart);
  ($brealm)=($b=~/^\Q$env{'request.course.id'}\E\.(.+)$/);  
     }  
     $arealm=~s/\.type//;  
     my ($ares, $aparm) = ($arealm=~/^(.*)\.(.*)$/);  
     $aparm=$keyorder{'parameter_0_'.$aparm};  
     $brealm=~s/\.type//;  
     my ($bres, $bparm) = ($brealm=~/^(.*)\.(.*)$/);  
     $bparm=$keyorder{'parameter_0_'.$bparm};     
     if ($ares eq $bres) {  
  if (defined($aparm) && defined($bparm)) {  
     ($aparm <=> $bparm);  
  } elsif (defined($aparm)) {  
     -1;  
  } elsif (defined($bparm)) {  
     1;  
  } else {  
     ($arealm cmp $brealm) || ($astudent cmp $bstudent);  
  }  
     } else {  
  ($arealm cmp $brealm) || ($astudent cmp $bstudent);  
     }      }
  } else {   } else {
     $a cmp $b;      if      ($astudent ne $bstudent) { 
    $result = ($astudent cmp $bstudent);
       } elsif ($ares     ne $bres    ) {
    $result = ($ares     cmp $bres);
       } elsif ($apart    ne $bpart   ) {
    $result = ($apart    cmp $bpart);
       }
  }   }
       
    if (!$result) {
               if (defined($aparm) && defined($bparm)) {
    $result = ($aparm <=> $bparm);
               } elsif (defined($aparm)) {
    $result = -1;
               } elsif (defined($bparm)) {
    $result = 1;
       }
    }
   
    $result;
     } keys %{$listdata}) {      } keys %{$listdata}) {
     
  if ($$listdata{$thiskey.'.type'}) {   if ($$listdata{$thiskey.'.type'}) {
             my $thistype=$$listdata{$thiskey.'.type'};              my $thistype=$$listdata{$thiskey.'.type'};
             if ($$resourcedata{$thiskey.'.type'}) {              if ($$resourcedata{$thiskey.'.type'}) {
Line 2585  sub listdata { Line 3112  sub listdata {
     }      }
     if ($part ne $oldpart) {      if ($part ne $oldpart) {
  $r->print(&tableend().   $r->print(&tableend().
   "\n<span class=\"LC_parm_part\">".&mt('Part').": $part</span>");    "\n".'<span class="LC_parm_part">'.&mt('Part').": $part</span>");
  $oldpart=$part;   $oldpart=$part;
     }      }
 #  #
Line 2606  sub listdata { Line 3133  sub listdata {
       $$resourcedata{$thiskey},        $$resourcedata{$thiskey},
       '',1,'','').        '',1,'','').
 '<input type="hidden" name="datepointer_'.$thiskey.'" value="'.$jskey.'" />'.  '<input type="hidden" name="datepointer_'.$thiskey.'" value="'.$jskey.'" />'.
   (($$resourcedata{$thiskey}!=0)?'<span class="LC_nobreak"><a href="/adm/parmset?&action=dateshift1&timebase='.$$resourcedata{$thiskey}.'">'.
   &mt('Shift all dates based on this date').'</a></span>':'').
 &date_sanity_info($$resourcedata{$thiskey})  &date_sanity_info($$resourcedata{$thiskey})
   );    );
     } elsif ($thistype eq 'string_yesno') {      } elsif ($thistype eq 'date_interval') {
  my $showval;   $r->print(&date_interval_selector($thiskey,
  if (defined($$resourcedata{$thiskey})) {    $$resourcedata{$thiskey}));
     $showval=$$resourcedata{$thiskey};      } elsif ($thistype =~ m/^string/) {
  }   $r->print(&string_selector($thistype,$thiskey,
  $r->print('<label><input type="radio" name="set_'.$thiskey.     $$resourcedata{$thiskey}));
   '" value="yes"');  
  if ($showval eq 'yes') {  
     $r->print(' checked="checked"');  
  }  
                 $r->print(' />'.&mt('Yes').'</label> ');  
  $r->print('<label><input type="radio" name="set_'.$thiskey.  
   '" value="no"');  
  if ($showval eq 'no') {  
     $r->print(' checked="checked"');  
  }  
                 $r->print(' />'.&mt('No').'</label>');  
     } else {      } else {
  my $showval;   $r->print(&default_selector($thiskey,$$resourcedata{$thiskey}));
  if (defined($$resourcedata{$thiskey})) {  
     $showval=$$resourcedata{$thiskey};  
  }  
  $r->print('<input type="text" name="set_'.$thiskey.'" value="'.  
   $showval.'">');  
     }      }
     $r->print('<input type="hidden" name="typeof_'.$thiskey.'" value="'.      $r->print('<input type="hidden" name="typeof_'.$thiskey.'" value="'.
       $thistype.'">');        $thistype.'" />');
     $r->print('</td>'.&Apache::loncommon::end_data_table_row());      $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 {
       my ($key) = @_;
       my $seconds = 0;
       foreach my $which (['days', 86400],
          ['hours', 3600],
          ['minutes', 60],
          ['seconds',  1]) {
    my ($name, $factor) = @{ $which };
    if (defined($env{'form.'.$name.'_'.$key})) {
       $seconds += $env{'form.'.$name.'_'.$key} * $factor;
    }
       }
       return $seconds;
   }
   
   
   sub default_selector {
       my ($thiskey, $showval) = @_;
       return '<input type="text" name="set_'.$thiskey.'" value="'.$showval.'" />';
   }
   
   my %strings = 
       (
        'string_yesno'
                => [[ 'yes', 'Yes' ],
    [ 'no', 'No' ]],
        'string_problemstatus'
                => [[ 'yes', 'Yes' ],
    [ 'answer', 'Yes, and show correct answer if they exceed the maximum number of tries.' ],
    [ 'no', 'No, don\'t show correct/incorrect feedback.' ],
    [ 'no_feedback_ever', 'No, show no feedback at all.' ]],
        );
   
   
   sub string_selector {
       my ($thistype, $thiskey, $showval) = @_;
       
       if (!exists($strings{$thistype})) {
    return &default_selector($thiskey,$showval);
       }
   
       my $result;
       foreach my $possibilities (@{ $strings{$thistype} }) {
    my ($name, $description) = @{ $possibilities };
    $result .= '<label><input type="radio" name="set_'.$thiskey.
     '" value="'.$name.'"';
    if ($showval eq $name) {
       $result .= ' checked="checked"';
    }
    $result .= ' />'.&mt($description).'</label> ';
       }
       return $result;
   }
   
   #
   # Shift all start and end dates by $shift
   #
   
   sub dateshift {
       my ($shift)=@_;
       my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
       my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
       my %data=&Apache::lonnet::dump('resourcedata',$dom,$crs);
   # ugly retro fix for broken version of types
       foreach my $key (keys %data) {
           if ($key=~/\wtype$/) {
               my $newkey=$key;
               $newkey=~s/type$/\.type/;
               $data{$newkey}=$data{$key};
               delete $data{$key};
           }
       }
       my %storecontent=();
   # go through all parameters and look for dates
       foreach my $key (keys %data) {
          if ($data{$key.'.type'}=~/^date_(start|end)$/) {
             my $newdate=$data{$key}+$shift;
             $storecontent{$key}=$newdate;
          }
       }
       my $reply=&Apache::lonnet::cput
                   ('resourcedata',\%storecontent,$dom,$crs);
       if ($reply eq 'ok') {
          &log_parmset(\%storecontent);
       }
       &Apache::lonnet::devalidatecourseresdata($crs,$dom);
       return $reply;
   }
   
 sub newoverview {  sub newoverview {
     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'};
       &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview',
       text=>"Overview Mode"});
     my $start_page = &Apache::loncommon::start_page('Set Parameters');      my $start_page = &Apache::loncommon::start_page('Set Parameters');
     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview');      my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview');
     $r->print(<<ENDOVER);      $r->print(<<ENDOVER);
Line 2682  ENDOVER Line 3308  ENDOVER
     my @selected_sections =       my @selected_sections = 
  &Apache::loncommon::get_env_multiple('form.Section');   &Apache::loncommon::get_env_multiple('form.Section');
     @selected_sections = ('all') if (! @selected_sections);      @selected_sections = ('all') if (! @selected_sections);
     foreach (@selected_sections) {      foreach my $sec (@selected_sections) {
         if ($_ eq 'all') {          if ($sec eq 'all') {
             @selected_sections = ('all');              @selected_sections = ('all');
         }          }
     }      }
Line 2703  ENDOVER Line 3329  ENDOVER
  \%mapp, \%symbp,\%maptitles,\%uris,   \%mapp, \%symbp,\%maptitles,\%uris,
  \%keyorder,\%defkeytype);   \%keyorder,\%defkeytype);
   
       if (grep {$_ eq 'all'} (@psprt)) {
    @psprt = keys(%allparts);
       }
 # Menu to select levels, etc  # Menu to select levels, etc
   
     $r->print('<table id="LC_parm_overview_scope">      $r->print('<table id="LC_parm_overview_scope">
Line 2759  ENDOVER Line 3388  ENDOVER
  &listdata($r,$resourcedata,$listdata,$sortorder);   &listdata($r,$resourcedata,$listdata,$sortorder);
     }      }
     $r->print(&tableend().      $r->print(&tableend().
      ((($env{'form.store'}) || ($env{'form.dis'}))?'<p><input type="submit" name="store" value="'.&mt('Store').'" /></p>':'').       ((($env{'form.store'}) || ($env{'form.dis'}))?'<p><input type="submit" name="store" value="'.&mt('Save').'" /></p>':'').
       '</form>'.&Apache::loncommon::end_page());        '</form>'.&Apache::loncommon::end_page());
 }  }
   
Line 2803  sub overview { Line 3432  sub overview {
     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'};
   
       &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview',
    text=>"Overview Mode"});
     my $start_page=&Apache::loncommon::start_page('Modify Parameters');      my $start_page=&Apache::loncommon::start_page('Modify Parameters');
     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview');      my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview');
     $r->print(<<ENDOVER);      $r->print(<<ENDOVER);
Line 2837  sub clean_parameters { Line 3468  sub clean_parameters {
     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'};
   
       &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=cleanparameters',
       text=>"Clean Parameters"});
     my $start_page=&Apache::loncommon::start_page('Clean Parameters');      my $start_page=&Apache::loncommon::start_page('Clean Parameters');
     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Clean');      my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Clean');
     $r->print(<<ENDOVER);      $r->print(<<ENDOVER);
Line 2857  ENDOVER Line 3490  ENDOVER
     $r->print('<h3>'.      $r->print('<h3>'.
       &mt('These parameters refer to resources that do not exist.').        &mt('These parameters refer to resources that do not exist.').
       '</h3>'.        '</h3>'.
       '<input type="submit" value="'.&mt('Delete Checked Parameters').'" />'.'<br />'.        '<input type="submit" value="'.&mt('Delete Selected').'" />'.'<br />'.
       '<br />');        '<br />');
     $r->print(&Apache::loncommon::start_data_table().      $r->print(&Apache::loncommon::start_data_table().
       '<tr>'.        '<tr>'.
Line 2868  ENDOVER Line 3501  ENDOVER
  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 (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};
       if (&isdateparm($resourcedata->{$thiskey.'.type'})) {
    $display_value = 
       &Apache::lonlocal::locallocaltime($display_value);
       }
     $r->print(&mt('Parameter: "[_1]" with value: "[_2]"',      $r->print(&mt('Parameter: "[_1]" with value: "[_2]"',
   &standard_parameter_names($data{'parameter_name'}),    &standard_parameter_names($data{'parameter_name'}),
   $resourcedata->{$thiskey}));    $resourcedata->{$thiskey}));
Line 2899  ENDOVER Line 3537  ENDOVER
  $r->print(&mt('Resource: [_1] <br />&nbsp;&nbsp;&nbsp;with ID: [_2] <br />&nbsp;&nbsp;&nbsp;in folder [_3]',   $r->print(&mt('Resource: [_1] <br />&nbsp;&nbsp;&nbsp;with ID: [_2] <br />&nbsp;&nbsp;&nbsp;in folder [_3]',
       $url,$resid,$map));        $url,$resid,$map));
     }      }
     $r->print(&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 Checked Parameters').'" />'.        '<input type="submit" value="'.&mt('Delete Selected').'" />'.
       '</p></form>'.        '</p></form>'.
       &Apache::loncommon::end_page());        &Apache::loncommon::end_page());
 }  }
   
   sub date_shift_one {
       my ($r) = @_;
       my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
       my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
   
       &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=dateshift1&timebase='.$env{'form.timebase'},
       text=>"Shifting Dates"});
       my $start_page=&Apache::loncommon::start_page('Shift Dates');
       my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Shift');
       $r->print(<<ENDOVER);
   $start_page
   $breadcrumbs
   ENDOVER
       $r->print('<form name="shiftform" method="post">'.
                 '<table><tr><td>'.&mt('Currently set date:').'</td><td>'.
                 &Apache::lonlocal::locallocaltime($env{'form.timebase'}).'</td></tr>'.
                 '<tr><td>'.&mt('Shifted date:').'</td><td>'.
                       &Apache::lonhtmlcommon::date_setter('shiftform',
                                                           'timeshifted',
                                                           $env{'form.timebase'},,
                                                           '').
                 '</td></tr></table>'.
                 '<input type="hidden" name="action" value="dateshift2" />'.
                 '<input type="hidden" name="timebase" value="'.$env{'form.timebase'}.'" />'.
                 '<input type="submit" value="'.&mt('Shift all dates accordingly').'" /></form>');
       $r->print(&Apache::loncommon::end_page());
   }
   
   sub date_shift_two {
       my ($r) = @_;
       my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
       my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
       &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=dateshift1&timebase='.$env{'form.timebase'},
       text=>"Shifting Dates"});
       my $start_page=&Apache::loncommon::start_page('Shift Dates');
       my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Shift');
       $r->print(<<ENDOVER);
   $start_page
   $breadcrumbs
   ENDOVER
       my $timeshifted=&Apache::lonhtmlcommon::get_date_from_form('timeshifted');
       $r->print(&mt('Shifting all dates such that [_1] becomes [_2]',
                 &Apache::lonlocal::locallocaltime($env{'form.timebase'}),
                 &Apache::lonlocal::locallocaltime($timeshifted)));
       my $delta=$timeshifted-$env{'form.timebase'};
       &dateshift($delta);
       $r->print(&Apache::loncommon::end_page());
   }
   
 sub parse_key {  sub parse_key {
     my ($key) = @_;      my ($key) = @_;
     my %data;      my %data;
Line 2935  sub parse_key { Line 3622  sub parse_key {
  $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'});
  &Apache::lonnet::logthis($1." siad ". $data{'realm_exists'} );  
     } elsif ($middle) {      } elsif ($middle) {
  $data{'realm'} = $middle;   $data{'realm'} = $middle;
  $data{'realm_type'} = 'symb';   $data{'realm_type'} = 'symb';
Line 2950  sub parse_key { Line 3636  sub parse_key {
     return %data;      return %data;
 }  }
   
 ##################################################  
 ##################################################  
   
 =pod  
   
 =item check_cloners  
   
 Checks if new users included in list of allowed cloners  
 are valid users.  Replaces supplied list with   
 cleaned list containing only users with valid usernames  
 and domains.  
   
 Inputs: $clonelist, $oldcloner   
 where $clonelist is ref to array of requested cloners,  
 and $oldcloner is ref to array of currently allowed  
 cloners.  
   
 Returns: string - comma separated list of requested  
 cloners (username:domain) who do not exist in system.  
   
 =item change_clone  
   
 Modifies the list of courses a user can clone (stored  
 in the user's environment.db file), called when a  
 change is made to the list of users allowed to clone  
 a course.  
   
 Inputs: $action,$cloner  
 where $action is add or drop, and $cloner is identity of   
 user for whom cloning ability is to be changed in course.   
   
 =cut  
                                                                                               
 ##################################################  
 ##################################################  
   
 sub extract_cloners {  sub extract_cloners {
     my ($clonelist,$allowclone) = @_;      my ($clonelist,$allowclone) = @_;
     if ($clonelist =~ /,/) {      if ($clonelist =~ /,/) {
         @{$allowclone} = split/,/,$clonelist;          @{$allowclone} = split(/,/,$clonelist);
     } else {      } else {
         $$allowclone[0] = $clonelist;          $$allowclone[0] = $clonelist;
     }      }
 }  }
   
   
 sub check_cloners {  sub check_cloners {
     my ($clonelist,$oldcloner) = @_;      my ($clonelist,$oldcloner) = @_;
     my ($clean_clonelist,$disallowed);      my ($clean_clonelist,%disallowed);
     my @allowclone = ();      my @allowclone = ();
     &extract_cloners($$clonelist,\@allowclone);      &extract_cloners($$clonelist,\@allowclone);
     foreach my $currclone (@allowclone) {      foreach my $currclone (@allowclone) {
         if (!grep/^$currclone$/,@$oldcloner) {          if (!grep(/^\Q$currclone\E$/,@$oldcloner)) {
             my ($uname,$udom) = split/:/,$currclone;              if ($currclone eq '*') {
             if ($uname && $udom) {                  $clean_clonelist .= $currclone.',';
                 if (&Apache::lonnet::homeserver($uname,$udom) eq 'no_host') {              } else {
                     $disallowed .= $currclone.',';                     my ($uname,$udom) = split(/:/,$currclone);
                   if ($uname eq '*') {
                       if ($udom =~ /^$match_domain$/) {
                           if (!&Apache::lonnet::domain($udom)) {
                               $disallowed{'domain'} .= $currclone.',';
                           } else {
                               $clean_clonelist .= $currclone.',';
                           }
                       } else {
                           $disallowed{'format'} .= $currclone.',';
                       }
                   } elsif ($currclone !~/^($match_username)\:($match_domain)$/) {
                       $disallowed{'format'} .= $currclone.','; 
                 } else {                  } else {
                     $clean_clonelist .= $currclone.',';                      if (&Apache::lonnet::homeserver($uname,$udom) eq 'no_host') {
                           $disallowed{'newuser'} .= $currclone.',';
                       } else {
                           $clean_clonelist .= $currclone.',';
                       }
                 }                  }
             }              }
         } else {          } else {
             $clean_clonelist .= $currclone.',';              $clean_clonelist .= $currclone.',';
         }          }
     }      }
     if ($disallowed) {      foreach my $key (keys(%disallowed)) {
         $disallowed =~ s/,$//;          $disallowed{$key} =~ s/,$//;
     }      }
     if ($clean_clonelist) {      if ($clean_clonelist) {
         $clean_clonelist =~ s/,$//;          $clean_clonelist =~ s/,$//;
     }      }
     $$clonelist = $clean_clonelist;      $$clonelist = $clean_clonelist;
     return $disallowed;      return %disallowed;
 }    }
   
 sub change_clone {  sub change_clone {
     my ($clonelist,$oldcloner) = @_;      my ($clonelist,$oldcloner) = @_;
Line 3036  sub change_clone { Line 3703  sub change_clone {
         my @allowclone;          my @allowclone;
         &extract_cloners($clonelist,\@allowclone);          &extract_cloners($clonelist,\@allowclone);
         foreach my $currclone (@allowclone) {          foreach my $currclone (@allowclone) {
             if (!grep/^$currclone$/,@$oldcloner) {              if (!grep(/^$currclone$/,@$oldcloner)) {
                 ($uname,$udom) = split/:/,$currclone;                  if ($currclone ne '*') {
                 if ($uname && $udom) {                      ($uname,$udom) = split(/:/,$currclone);
                     unless (&Apache::lonnet::homeserver($uname,$udom) eq 'no_host') {                      if ($uname && $udom && $uname ne '*') {
                         my %currclonecrs = &Apache::lonnet::dump('environment',$udom,$uname,'cloneable');                          if (&Apache::lonnet::homeserver($uname,$udom) ne 'no_host') {
                         if ($currclonecrs{'cloneable'} !~ /\Q$clone_crs\E/) {                              my %currclonecrs = &Apache::lonnet::dump('environment',$udom,$uname,'cloneable');
                             if ($currclonecrs{'cloneable'} eq '') {                              if ($currclonecrs{'cloneable'} !~ /\Q$clone_crs\E/) {
                                 $currclonecrs{'cloneable'} = $clone_crs;                                  if ($currclonecrs{'cloneable'} eq '') {
                             } else {                                      $currclonecrs{'cloneable'} = $clone_crs;
                                 $currclonecrs{'cloneable'} .= ','.$clone_crs;                                  } else {
                                       $currclonecrs{'cloneable'} .= ','.$clone_crs;
                                   }
                                   &Apache::lonnet::put('environment',\%currclonecrs,$udom,$uname);
                             }                              }
                             &Apache::lonnet::put('environment',\%currclonecrs,$udom,$uname);  
                         }                          }
                     }                      }
                 }                  }
             }              }
         }          }
         foreach my $oldclone (@$oldcloner) {          foreach my $oldclone (@$oldcloner) {
             if (!grep/^$oldclone$/,@allowclone) {              if (!grep(/^\Q$oldclone\E$/,@allowclone)) {
                 ($uname,$udom) = split/:/,$oldclone;                  if ($oldclone ne '*') {
                 if ($uname && $udom) {                      ($uname,$udom) = split(/:/,$oldclone);
                     unless (&Apache::lonnet::homeserver($uname,$udom) eq 'no_host') {                      if ($uname && $udom && $uname ne '*' ) {
                         my %currclonecrs = &Apache::lonnet::dump('environment',$udom,$uname,'cloneable');                          if (&Apache::lonnet::homeserver($uname,$udom) ne 'no_host') {
                         my %newclonecrs = ();                              my %currclonecrs = &Apache::lonnet::dump('environment',$udom,$uname,'cloneable');
                         if ($currclonecrs{'cloneable'} =~ /\Q$clone_crs\E/) {                              my %newclonecrs = ();
                             if ($currclonecrs{'cloneable'} =~ /,/) {                              if ($currclonecrs{'cloneable'} =~ /\Q$clone_crs\E/) {
                                 my @currclonecrs = split/,/,$currclonecrs{'cloneable'};                                  if ($currclonecrs{'cloneable'} =~ /,/) {
                                 foreach (@currclonecrs) {                                      my @currclonecrs = split/,/,$currclonecrs{'cloneable'};
                                     unless ($_ eq $clone_crs) {                                      foreach my $crs (@currclonecrs) {
                                         $newclonecrs{'cloneable'} .= $_.',';                                          if ($crs ne $clone_crs) {
                                               $newclonecrs{'cloneable'} .= $crs.',';
                                           }
                                     }                                      }
                                       $newclonecrs{'cloneable'} =~ s/,$//;
                                   } else {
                                       $newclonecrs{'cloneable'} = '';
                                 }                                  }
                                 $newclonecrs{'cloneable'} =~ s/,$//;                                  &Apache::lonnet::put('environment',\%newclonecrs,$udom,$uname);
                             } else {  
                                 $newclonecrs{'cloneable'} = '';  
                             }                              }
                             &Apache::lonnet::put('environment',\%newclonecrs,$udom,$uname);  
                         }                          }
                     }                      }
                 }                  }
Line 3082  sub change_clone { Line 3753  sub change_clone {
 }  }
   
   
 ##################################################  
 ##################################################  
   
 =pod  
   
 =item * header  
   
 Output html header for page  
   
 =cut  
   
 ##################################################  
 ##################################################  
 sub header {  sub header {
     return &Apache::loncommon::start_page('Parameter Manager');      return &Apache::loncommon::start_page('Parameter Manager');
 }  }
 ##################################################  
 ##################################################  
   
 sub print_main_menu {  sub print_main_menu {
     my ($r,$parm_permission)=@_;      my ($r,$parm_permission)=@_;
     #      #
       $r->print(&header());
       $r->print(&Apache::lonhtmlcommon::breadcrumbs('Parameter Manager'));
     $r->print(<<ENDMAINFORMHEAD);      $r->print(<<ENDMAINFORMHEAD);
 <form method="post" enctype="multipart/form-data"  <form method="post" enctype="multipart/form-data"
       action="/adm/parmset" name="studentform">        action="/adm/parmset" name="studentform">
Line 3111  ENDMAINFORMHEAD Line 3773  ENDMAINFORMHEAD
     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 $vgr  = &Apache::lonnet::allowed('vgr',$env{'request.course.id'});      my $vgr  = &Apache::lonnet::allowed('vgr',$env{'request.course.id'});
       my $mgr  = &Apache::lonnet::allowed('mgr',$env{'request.course.id'});
   
   
     my @menu =      my @menu =
         ( { divider=>'Settings for Your Course',          ( { categorytitle=>'Settings for this Course',
   },      items => [
           { text => 'Set Course Environment',    { linktext => 'Course Environment',
     action => 'crsenv',      url => '/adm/parmset?action=crsenv',
             permission => $parm_permission,      permission => $parm_permission,
             help => 'Course_Environment',      linktitle =>'Edit environment settings for this course.'  ,
             },      icon => 'preferences-desktop-remote-desktop.png'  ,
           { text => 'Set Portfolio Metadata',      #help => 'Course_Environment',
     action => 'setrestrictmeta',      },
             permission => $parm_permission,    { linktext => 'Portfolio Metadata',
             },      url => '/adm/parmset?action=setrestrictmeta',
   { text => 'Manage Course Slots',      permission => $parm_permission,
     url => '/adm/slotrequest?command=showslots',      linktitle => 'Restrict metadata for this course.' ,
     permission => $vgr,      icon =>'contact-new.png'   ,
             },      },
           { text => 'Set Parameter Setting Default Actions',    { linktext => 'Manage Course Slots',
             action => 'setdefaults',      url => '/adm/slotrequest?command=showslots',
             permission => $parm_permission,      permission => $vgr,
             },                linktitle =>'Manage slots for this course.'  ,
   { divider => 'New and Existing Parameter Settings for Your Resources',      icon => 'format-justify-fill.png'  ,
     },      },
           { text => 'Set/Modify Resource Parameters - Helper Mode',    { linktext => 'Reset Student Access Times',
             url => '/adm/helper/parameter.helper',      url => '/adm/helper/resettimes.helper',
             permission => $parm_permission,      permission => $mgr,
             help => 'Parameter_Helper',      linktitle =>'Reset access times for folders/maps, resources or the course.'  ,
             },      icon => 'start-here.png'  ,
    { text => 'Set/Modify Resource Parameters - Overview Mode',      },
             action => 'newoverview',  
             permission => $parm_permission,    { linktext => 'Set Parameter Setting Default Actions',
             help => 'Parameter_Overview',      url => '/adm/parmset?action=setdefaults',
             },      permission => $parm_permission,
           { text => 'Set/Modify Resource Parameters - Table Mode',      linktitle =>'Set default actions for parameters.'  ,
             action => 'settable',      icon => 'folder-new.png'  ,
             permission => $parm_permission,      }]},          
             help => 'Table_Mode',    { categorytitle => 'New and Existing Parameter Settings for Resources',
             },      items => [
            { divider => 'Existing Parameter Settings for Your Resources',    { linktext => 'Edit Resource Parameters - Helper Mode',
   },      url => '/adm/helper/parameter.helper',
   { text => 'Modify Resource Parameters - Overview Mode',      permission => $parm_permission,
             action => 'setoverview',      linktitle =>'Set/Modify resource parameters in helper mode.'  ,
             permission => $parm_permission,      icon => 'dialog-information.png'  ,
             help => 'Parameter_Overview',      #help => 'Parameter_Helper',
      },                },
   { text => 'Parameter Change Log and Course Blog Posting/User Notification',    { linktext => 'Edit Resource Parameters - Overview Mode',
             action => 'parameterchangelog',      url => '/adm/parmset?action=newoverview',
             permission => $parm_permission,      permission => $parm_permission,
             },      linktitle =>'Set/Modify resource parameters in overview mode.'  ,
       icon => 'edit-find.png'  ,
       #help => 'Parameter_Overview',
       },
     { linktext => 'Edit Resource Parameters - Table Mode',
       url => '/adm/parmset?action=settable',
       permission => $parm_permission,
       linktitle =>'Set/Modify resource parameters in table mode.'  ,
       icon => 'edit-copy.png'  ,
       #help => 'Table_Mode',
       }]},
              { categorytitle => 'Existing Parameter Settings for Resources',
        items => [
     { linktext => 'Modify Resource Parameters - Overview Mode',
       url => '/adm/parmset?action=setoverview',
       permission => $parm_permission,
       linktitle =>'Set/Modify existing resource parameters in overview mode.'  ,
       icon => 'preferences-desktop-wallpaper.png'  ,
       #help => 'Parameter_Overview',
       },          
     { linktext => 'Change Log',
       url => '/adm/parmset?action=parameterchangelog',
       permission => $parm_permission,
       linktitle =>'View parameter and course blog posting/user notification change log.'  ,
       icon => 'emblem-system.png'   ,
       }]}
           );            );
     my $menu_html = '';      $r->print(&Apache::lonhtmlcommon::generate_menu(@menu));
     foreach my $menu_item (@menu) {  
  if ($menu_item->{'divider'}) {  
     $menu_html .= '<h3>'.&mt($menu_item->{'divider'}).'</h3>';  
     next;  
  }  
         next if (! $menu_item->{'permission'});  
         $menu_html.='<p>';  
         $menu_html.='<span class="LC_parm_menu_item">';  
         if (exists($menu_item->{'url'})) {  
             $menu_html.=qq{<a href="$menu_item->{'url'}">};  
         } else {  
             $menu_html.=  
                 qq{<a href="/adm/parmset?action=$menu_item->{'action'}">};  
         }  
         $menu_html.= &mt($menu_item->{'text'}).'</a></span>';  
         if (exists($menu_item->{'help'})) {  
             $menu_html.=  
                 &Apache::loncommon::help_open_topic($menu_item->{'help'});  
         }  
         $menu_html.='</p>'.$/;  
     }  
     $r->print($menu_html);  
     return;      return;
 }  }
 ### Set 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 3198  sub output_row { Line 3867  sub output_row {
     }      }
     if (!($options =~ /deleted/)) {      if (!($options =~ /deleted/)) {
         my @options= ( ['active', 'Show to student'],          my @options= ( ['active', 'Show to student'],
                     ['stuadd', 'Provide text area for students to type catalog information'],                      ['stuadd', 'Provide text area for students to type metadata'],
                     ['choices','Provide choices for students to select from']);                      ['choices','Provide choices for students to select from']);
 #   ['onlyone','Student may select only one choice']);  #   ['onlyone','Student may select only one choice']);
         if ($added_flag) {          if ($added_flag) {
Line 3222  sub output_row { Line 3891  sub output_row {
         my $multiple_checked;          my $multiple_checked;
         my $single_checked;          my $single_checked;
         if ($options =~ m/onlyone/) {          if ($options =~ m/onlyone/) {
             $multiple_checked = "";              $multiple_checked = '';
             $single_checked = " CHECKED ";              $single_checked = ' checked="checked"';
         } else {          } else {
             $multiple_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).'<span class="LC_metadata">   $output .= '<td>'.('&nbsp;' x 10).'<span class="LC_metadata">
             <input type="radio" name="'.$field_name.'_onlyone" value="multiple" '.$multiple_checked .'/>              <input type="radio" name="'.$field_name.'_onlyone" value="multiple"'.$multiple_checked .' />
             Student may select multiple choices from list</span></td>';              '.&mt('Student may select multiple choices from list').'</span></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).'<span class="LC_metadata">   $output .= '<td>'.('&nbsp;' x 10).'<span class="LC_metadata">
             <input type="radio" name="'.$field_name.'_onlyone"  value="single" '.$single_checked.'/>              <input type="radio" name="'.$field_name.'_onlyone"  value="single"'.$single_checked.' />
             Student may select only one choice from list</span></td>';              '.&mt('Student may select only one choice from list').'</span></td>';
  $output .= &Apache::loncommon::end_data_table_row();   $output .= &Apache::loncommon::end_data_table_row();
     }      }
     return ($output);      return ($output);
 }  }
   
   
   
 sub order_meta_fields {  sub order_meta_fields {
     my ($r)=@_;      my ($r)=@_;
     my $idx = 1;      my $idx = 1;
     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'};
     $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',
       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"},
Line 3286  sub order_meta_fields { Line 3960  sub order_meta_fields {
  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();      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) {
Line 3323  sub order_meta_fields { Line 3997  sub order_meta_fields {
     $r->print('</table>');      $r->print('</table>');
     return 'ok';      return 'ok';
 }  }
   
   
   sub continue {
       my $output;
       $output .= '<form action="" method="post">';
       $output .= '<input type="hidden" name="action" value="setrestrictmeta" />';
       $output .= '<input type="submit" value="Continue" />';
       return ($output);
   }
   
   
 sub addmetafield {  sub addmetafield {
     my ($r)=@_;      my ($r)=@_;
       &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=addmetadata',
       text=>"Add Metadata Field"});
     $r->print(&Apache::loncommon::start_page('Add Metadata Field'));      $r->print(&Apache::loncommon::start_page('Add Metadata Field'));
     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Add Metadata Field'));      $r->print(&Apache::lonhtmlcommon::breadcrumbs('Add Metadata Field'));
     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'};
     if (exists($env{'form.undelete'})) {      if (exists($env{'form.undelete'})) {
         my @meta_fields = &Apache::loncommon::get_env_multiple('form.undelete');          my @meta_fields = &Apache::loncommon::get_env_multiple('form.undeletefield');
         foreach my $meta_field(@meta_fields) {          foreach my $meta_field(@meta_fields) {
             my $options = $env{'course.'.$env{'request.course.id'}.'.metadata.'.$meta_field.'.options'};              my $options = $env{'course.'.$env{'request.course.id'}.'.metadata.'.$meta_field.'.options'};
             $options =~ s/deleted//;              $options =~ s/deleted//;
Line 3340  sub addmetafield { Line 4027  sub addmetafield {
                                                                                   
             $r->print('Undeleted Metadata Field <strong>'.$env{'course.'.$env{'request.course.id'}.'.metadata.'.$meta_field.'.added'}."</strong> with result ".$put_result.'<br />');              $r->print('Undeleted Metadata Field <strong>'.$env{'course.'.$env{'request.course.id'}.'.metadata.'.$meta_field.'.added'}."</strong> with result ".$put_result.'<br />');
         }          }
         $r->print('<form action="" method="post">');          $r->print(&continue());
         $r->print('<input type="hidden" name="action" value="setrestrictmeta" />');  
         $r->print('<input type="submit" value="Continue" />');  
     } elsif (exists($env{'form.fieldname'})) {      } elsif (exists($env{'form.fieldname'})) {
         my $meta_field = $env{'form.fieldname'};          my $meta_field = $env{'form.fieldname'};
         my $display_field = $env{'form.fieldname'};          my $display_field = $env{'form.fieldname'};
Line 3352  sub addmetafield { Line 4037  sub addmetafield {
                             {'metadata.'.$meta_field.'.values'=>"",                              {'metadata.'.$meta_field.'.values'=>"",
                              'metadata.'.$meta_field.'.added'=>"$display_field",                               'metadata.'.$meta_field.'.added'=>"$display_field",
                              'metadata.'.$meta_field.'.options'=>""},$dom,$crs);                               'metadata.'.$meta_field.'.options'=>""},$dom,$crs);
         $r->print('Added new Metadata Field '.$env{'form.fieldname'}." with result ".$put_result);          $r->print('Added new Metadata Field <strong>'.$env{'form.fieldname'}."</strong> with result ".$put_result.'<br />');
           $r->print(&continue());
     } else {      } else {
         my $fields = &get_deleted_meta_fieldnames();          my $fields = &get_deleted_meta_fieldnames($env{'request.course.id'});
         if ($fields) {          if ($fields) {
             $r->print('You may undelete previously deleted fields.<br />Check those you wish to undelete and click Undelete.<br />');              $r->print('You may undelete previously deleted fields.<br />Check those you wish to undelete and click Undelete.<br />');
             $r->print('<form method="post" action="">');              $r->print('<form method="post" action="">');
             foreach my $key(keys(%$fields)) {              foreach my $key(keys(%$fields)) {
                 $r->print('<input type="checkbox" name="undelete" value="'.$key.'" />'.$$fields{$key}.'<br /');                  $r->print('<input type="checkbox" name="undeletefield" value="'.$key.'" />'.$$fields{$key}.'<br /');
             }              }
             $r->print('<input type="submit" name="undelete" value="Undelete" />');              $r->print('<input type="submit" name="undelete" value="Undelete" />');
             $r->print('</form>');              $r->print('</form>');
Line 3367  sub addmetafield { Line 4053  sub addmetafield {
         $r->print('<hr /><strong>Or</strong> you may enter a new metadata field name.<form method="post" action="/adm/parmset?action=addmetadata"');          $r->print('<hr /><strong>Or</strong> you may enter a new metadata field name.<form method="post" action="/adm/parmset?action=addmetadata"');
         $r->print('<input type="text" name="fieldname" /><br />');          $r->print('<input type="text" name="fieldname" /><br />');
         $r->print('<input type="submit" value="Add Metadata Field" />');          $r->print('<input type="submit" value="Add Metadata Field" />');
         $r->print('</form>');  
     }      }
       $r->print('</form>');
 }  }
   
   
   
 sub setrestrictmeta {  sub setrestrictmeta {
     my ($r)=@_;      my ($r)=@_;
     my $next_meta;      my $next_meta;
     my $output;      my $output;
     my $item_num;      my $item_num;
     my $put_result;      my $put_result;
       &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setrestrictmeta',
       text=>"Restrict Metadata"});
     $r->print(&Apache::loncommon::start_page('Restrict Metadata'));      $r->print(&Apache::loncommon::start_page('Restrict Metadata'));
     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Restrict Metadata'));      $r->print(&Apache::lonhtmlcommon::breadcrumbs('Restrict Metadata'));
     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};      my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
Line 3419  sub setrestrictmeta { Line 4110  sub setrestrictmeta {
     # Get the default metadata fields      # Get the default metadata fields
     my %metadata_fields = &Apache::lonmeta::fieldnames('portfolio');      my %metadata_fields = &Apache::lonmeta::fieldnames('portfolio');
     # Now get possible added metadata fields      # Now get possible added metadata fields
     my $added_metadata_fields = &get_added_meta_fieldnames(\%metadata_fields);      my $added_metadata_fields = &get_added_meta_fieldnames($env{'request.course.id'});
     my $row_alt = 1;      my $row_alt = 1;
     $output .= &Apache::loncommon::start_data_table();      $output .= &Apache::loncommon::start_data_table();
     foreach my $field (sort(keys(%metadata_fields))) {      foreach my $field (sort(keys(%metadata_fields))) {
Line 3453  ENDenv Line 4144  ENDenv
     $r->print(&Apache::loncommon::end_page());      $r->print(&Apache::loncommon::end_page());
     return 'ok';      return 'ok';
 }  }
 ##################################################  
   
   
 sub get_added_meta_fieldnames {  sub get_added_meta_fieldnames {
       my ($cid) = @_;
     my %fields;      my %fields;
     foreach my $key(%env) {      foreach my $key(%env) {
         if ($key =~ m/\.metadata\.(.+)\.added$/) {          if ($key =~ m/\Q$cid\E\.metadata\.(.+)\.added$/) {
             my $field_name = $1;              my $field_name = $1;
             my ($display_field_name) = $env{$key};              my ($display_field_name) = $env{$key};
             $fields{$field_name} = $display_field_name;              $fields{$field_name} = $display_field_name;
Line 3465  sub get_added_meta_fieldnames { Line 4159  sub get_added_meta_fieldnames {
     }      }
     return \%fields;      return \%fields;
 }  }
   
   
   
 sub get_deleted_meta_fieldnames {  sub get_deleted_meta_fieldnames {
       my ($cid) = @_;
     my %fields;      my %fields;
     my ($default_fields) = @_;  
     foreach my $key(%env) {      foreach my $key(%env) {
         if ($key =~ m/\.metadata\.(.+)\.added$/) {          if ($key =~ m/\Q$cid\E\.metadata\.(.+)\.added$/) {
             my $field_name = $1;              my $field_name = $1;
             if ($env{'course.'.$env{'request.course.id'}.'.metadata.'.$field_name.'.options'} =~ m/deleted/) {              if ($env{'course.'.$env{'request.course.id'}.'.metadata.'.$field_name.'.options'} =~ m/deleted/) {
                 my ($display_field_name) = $env{$key};                  my ($display_field_name) = $env{$key};
Line 3482  sub get_deleted_meta_fieldnames { Line 4179  sub get_deleted_meta_fieldnames {
 sub defaultsetter {  sub defaultsetter {
     my ($r) = @_;      my ($r) = @_;
   
       &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setdefaults',
       text=>"Set Defaults"});
     my $start_page =       my $start_page = 
  &Apache::loncommon::start_page('Parameter Setting Default Actions');   &Apache::loncommon::start_page('Parameter Setting Default Actions');
     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Defaults');      my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Defaults');
Line 3633  ENDYESNO Line 4332  ENDYESNO
         $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().
       "\n<input type='submit' name='storerules' value='".        "\n".'<input type="submit" name="storerules" value="'.
       &mt('Store Rules')."' /></form>\n".        &mt('Save Rules').'" /></form>'."\n".
       &Apache::loncommon::end_page());        &Apache::loncommon::end_page());
     return;      return;
 }  }
Line 3678  sub components { Line 4377  sub components {
 }  }
   
 my %standard_parms;  my %standard_parms;
   
   
 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>) {
Line 3707  sub standard_parameter_names { Line 4408  sub standard_parameter_names {
     }      }
 }  }
   
 #  
 # Parameter Change Log  
 #  
   
   
 sub parm_change_log {  sub parm_change_log {
     my ($r)=@_;      my ($r)=@_;
       &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=settable',
    text=>"Parameter Change Log"});
     $r->print(&Apache::loncommon::start_page('Parameter Change Log'));      $r->print(&Apache::loncommon::start_page('Parameter Change Log'));
     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Parameter Change Log'));      $r->print(&Apache::lonhtmlcommon::breadcrumbs('Parameter Change Log'));
   
Line 3753  sub parm_change_log { Line 4453  sub parm_change_log {
  }   }
  if ($last) { ($folder) = &Apache::lonnet::decode_symb($last); }   if ($last) { ($folder) = &Apache::lonnet::decode_symb($last); }
     }      }
     foreach my $id (sort { $parmlog{$b}{'exe_time'}<=>$parmlog{$a}{'exe_time'} } (keys(%parmlog))) {      foreach my $id (sort 
       {
    if ($parmlog{$b}{'exe_time'} ne $parmlog{$a}{'exe_time'}) {
       return $parmlog{$b}{'exe_time'} <=>$parmlog{$a}{'exe_time'}
    }
    my $aid = (split('00000',$a))[-1];
    my $bid = (split('00000',$b))[-1];
    return $bid<=>$aid;
       } (keys(%parmlog))) {
         my @changes=keys(%{$parmlog{$id}{'logentry'}});          my @changes=keys(%{$parmlog{$id}{'logentry'}});
  my $count = 0;   my $count = 0;
  my $time =   my $time =
Line 3867  sub check_for_course_info { Line 4575  sub check_for_course_info {
     return 0;      return 0;
 }  }
   
 ##################################################  
 ##################################################  
   
 =pod  
   
 =item * handler  
   
 Main handler.  Calls &assessparms and &crsenv subroutines.  
   
 =cut  
 ##################################################  
 ##################################################  
 #    use Data::Dumper;  
   
   
 sub handler {  sub handler {
     my $r=shift;      my $r=shift;
   
     if ($r->header_only) {      &reset_caches();
  &Apache::loncommon::content_type($r,'text/html');  
  $r->send_http_header;      &Apache::loncommon::content_type($r,'text/html');
  return OK;      $r->send_http_header;
     }      return OK if $r->header_only;
   
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
     ['action','state',      ['action','state',
                                              'pres_marker',                                               'pres_marker',
                                              'pres_value',                                               'pres_value',
                                              'pres_type',                                               'pres_type',
                                              'udom','uname','symb','serial']);                                               'udom','uname','symb','serial','timebase']);
   
   
     &Apache::lonhtmlcommon::clear_breadcrumbs();      &Apache::lonhtmlcommon::clear_breadcrumbs();
Line 3913  sub handler { Line 4608  sub handler {
     my $exists = &check_for_course_info();      my $exists = &check_for_course_info();
   
     if ($env{'request.course.id'} &&  $parm_permission && $exists) {      if ($env{'request.course.id'} &&  $parm_permission && $exists) {
   
         # Start Page  
         &Apache::loncommon::content_type($r,'text/html');  
         $r->send_http_header;  
   
   
         # id numbers can change on re-ordering of folders  
   
         &resetsymbcache();  
   
         #          #
         # Main switch on form.action and form.state, as appropriate          # Main switch on form.action and form.state, as appropriate
         #          #
Line 3930  sub handler { Line 4615  sub handler {
         #  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'})) {
             &Apache::lonhtmlcommon::add_breadcrumb({help=>'Problem_Parameters',  
     text=>"Problem Parameters"});  
     &assessparms($r);      &assessparms($r);
   
         } elsif (! exists($env{'form.action'})) {          } elsif (! exists($env{'form.action'})) {
             $r->print(&header());  
             $r->print(&Apache::lonhtmlcommon::breadcrumbs('Parameter Manager'));  
             &print_main_menu($r,$parm_permission);              &print_main_menu($r,$parm_permission);
         } elsif ($env{'form.action'} eq 'crsenv' && $parm_permission) {          } elsif ($env{'form.action'} eq 'crsenv') {
             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=crsenv',  
     text=>"Course Environment"});  
             &crsenv($r);               &crsenv($r); 
         } elsif ($env{'form.action'} eq 'setoverview' && $parm_permission) {          } elsif ($env{'form.action'} eq 'setoverview') {
             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview',  
     text=>"Overview Mode"});  
     &overview($r);      &overview($r);
  } elsif ($env{'form.action'} eq 'addmetadata' && $parm_permission) {   } elsif ($env{'form.action'} eq 'addmetadata') {
             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=addmetadata',  
     text=>"Add Metadata Field"});  
     &addmetafield($r);      &addmetafield($r);
  } elsif ($env{'form.action'} eq 'ordermetadata' && $parm_permission) {   } elsif ($env{'form.action'} eq 'ordermetadata') {
             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=addmetadata',  
     text=>"Add Metadata Field"});  
     &order_meta_fields($r);      &order_meta_fields($r);
         } elsif ($env{'form.action'} eq 'setrestrictmeta' && $parm_permission) {          } elsif ($env{'form.action'} eq 'setrestrictmeta') {
             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setrestrictmeta',  
     text=>"Restrict Metadata"});  
     &setrestrictmeta($r);      &setrestrictmeta($r);
         } elsif ($env{'form.action'} eq 'newoverview' && $parm_permission) {          } elsif ($env{'form.action'} eq 'newoverview') {
             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview',  
     text=>"Overview Mode"});  
     &newoverview($r);      &newoverview($r);
         }  elsif ($env{'form.action'} eq 'setdefaults' && $parm_permission) {          } elsif ($env{'form.action'} eq 'setdefaults') {
             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setdefaults',  
     text=>"Set Defaults"});  
     &defaultsetter($r);      &defaultsetter($r);
  } elsif ($env{'form.action'} eq 'settable' && $parm_permission) {   } elsif ($env{'form.action'} eq 'settable') {
             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=settable',  
     text=>"Table Mode",  
     help => 'Course_Setting_Parameters'});  
     &assessparms($r);      &assessparms($r);
         } elsif ($env{'form.action'} eq 'parameterchangelog' && $parm_permission) {          } elsif ($env{'form.action'} eq 'parameterchangelog') {
             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=settable',  
     text=>"Parameter Change Log"});  
     &parm_change_log($r);      &parm_change_log($r);
         } elsif ($env{'form.action'} eq 'cleanparameters' && $parm_permission) {          } elsif ($env{'form.action'} eq 'cleanparameters') {
             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=cleanparameters',  
     text=>"Clean Parameters"});  
     &clean_parameters($r);      &clean_parameters($r);
  }                 } elsif ($env{'form.action'} eq 'dateshift1') {
               &date_shift_one($r);
           } elsif ($env{'form.action'} eq 'dateshift2') {
               &date_shift_two($r);
    } elsif ($env{'form.action'} eq 'categorizecourse') {
               &assign_course_categories($r);
           } 
     } 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) {
Line 3991  sub handler { Line 4656  sub handler {
  }   }
  return HTTP_NOT_ACCEPTABLE;   return HTTP_NOT_ACCEPTABLE;
     }      }
       &reset_caches();
   
     return OK;      return OK;
 }  }
   
 1;  1;
 __END__  __END__
   
 =pod  
   
 =back  
   
 =cut  
   
   
   

Removed from v.1.355  
changed lines
  Added in v.1.428


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