Annotation of loncom/interface/lonparmset.pm, revision 1.413.2.1

1.1       www         1: # The LearningOnline Network with CAPA
                      2: # Handler to set parameters for assessments
                      3: #
1.413.2.1! raeburn     4: # $Id: lonparmset.pm,v 1.413 2008/10/23 14:26:17 bisitz Exp $
1.40      albertel    5: #
                      6: # Copyright Michigan State University Board of Trustees
                      7: #
                      8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                      9: #
                     10: # LON-CAPA is free software; you can redistribute it and/or modify
                     11: # it under the terms of the GNU General Public License as published by
                     12: # the Free Software Foundation; either version 2 of the License, or
                     13: # (at your option) any later version.
                     14: #
                     15: # LON-CAPA is distributed in the hope that it will be useful,
                     16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     18: # GNU General Public License for more details.
                     19: #
                     20: # You should have received a copy of the GNU General Public License
                     21: # along with LON-CAPA; if not, write to the Free Software
                     22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     23: #
                     24: # /home/httpd/html/adm/gpl.txt
                     25: #
                     26: # http://www.lon-capa.org/
                     27: #
1.59      matthew    28: ###################################################################
                     29: ###################################################################
                     30: 
                     31: =pod
                     32: 
                     33: =head1 NAME
                     34: 
                     35: lonparmset - Handler to set parameters for assessments and course
                     36: 
                     37: =head1 SYNOPSIS
                     38: 
                     39: lonparmset provides an interface to setting course parameters. 
                     40: 
                     41: =head1 DESCRIPTION
                     42: 
                     43: This module sets coursewide and assessment parameters.
                     44: 
                     45: =head1 INTERNAL SUBROUTINES
                     46: 
                     47: =over 4
                     48: 
                     49: =cut
                     50: 
                     51: ###################################################################
                     52: ###################################################################
1.1       www        53: 
                     54: package Apache::lonparmset;
                     55: 
                     56: use strict;
                     57: use Apache::lonnet;
                     58: use Apache::Constants qw(:common :http REDIRECT);
1.88      matthew    59: use Apache::lonhtmlcommon();
1.36      albertel   60: use Apache::loncommon;
1.1       www        61: use GDBM_File;
1.57      albertel   62: use Apache::lonhomework;
                     63: use Apache::lonxml;
1.130     www        64: use Apache::lonlocal;
1.197     www        65: use Apache::lonnavmaps;
1.307     raeburn    66: use Apache::longroup;
1.303     www        67: use Apache::lonrss;
1.350     albertel   68: use LONCAPA qw(:DEFAULT :match);
1.1       www        69: 
1.198     www        70: 
1.59      matthew    71: ##################################################
                     72: ##################################################
                     73: 
                     74: =pod
                     75: 
                     76: =item parmval
                     77: 
                     78: Figure out a cascading parameter.
                     79: 
1.71      albertel   80: Inputs:  $what - a parameter spec (incluse part info and name I.E. 0.weight)
1.162     albertel   81:          $id   - a bighash Id number
1.71      albertel   82:          $def  - the resource's default value   'stupid emacs
                     83: 
1.269     raeburn    84: Returns:  A list, the first item is the index into the remaining list of items of parm valuse that is the active one, the list consists of parm values at the 14 possible levels
1.71      albertel   85: 
1.306     albertel   86: 14- General Course
                     87: 13- Map or Folder level in course
1.269     raeburn    88: 12- resource default
                     89: 11- map default
1.306     albertel   90: 10- resource level in course
1.269     raeburn    91: 9 - General for section
                     92: 8 - Map or Folder level for section
                     93: 7 - resource level in section
                     94: 6 - General for group
                     95: 5 - Map or Folder level for group
                     96: 4 - resource level in group
1.71      albertel   97: 3 - General for specific student
1.82      www        98: 2 - Map or Folder level for specific student
1.71      albertel   99: 1 - resource level for specific student
1.2       www       100: 
1.59      matthew   101: =cut
                    102: 
                    103: ##################################################
1.2       www       104: sub parmval {
1.275     raeburn   105:     my ($what,$id,$def,$uname,$udom,$csec,$cgroup,$courseopt)=@_;
                    106:     return &parmval_by_symb($what,&symbcache($id),$def,$uname,$udom,$csec,
                    107:                                                            $cgroup,$courseopt);
1.201     www       108: }
                    109: 
                    110: sub parmval_by_symb {
1.275     raeburn   111:     my ($what,$symb,$def,$uname,$udom,$csec,$cgroup,$courseopt)=@_;
1.200     www       112: 
1.352     albertel  113:     my $useropt;
                    114:     if ($uname ne '' && $udom ne '') {
                    115: 	$useropt = &Apache::lonnet::get_userresdata($uname,$udom);
                    116:     }
1.200     www       117: 
1.8       www       118:     my $result='';
1.44      albertel  119:     my @outpar=();
1.2       www       120: # ----------------------------------------------------- Cascading lookup scheme
1.201     www       121:     my $map=(&Apache::lonnet::decode_symb($symb))[0];    
1.305     albertel  122:     $map = &Apache::lonnet::deversion($map);
1.10      www       123: 
1.201     www       124:     my $symbparm=$symb.'.'.$what;
                    125:     my $mapparm=$map.'___(all).'.$what;
1.10      www       126: 
1.269     raeburn   127:     my $grplevel=$env{'request.course.id'}.'.['.$cgroup.'].'.$what;
                    128:     my $grplevelr=$env{'request.course.id'}.'.['.$cgroup.'].'.$symbparm;
                    129:     my $grplevelm=$env{'request.course.id'}.'.['.$cgroup.'].'.$mapparm;
                    130: 
1.190     albertel  131:     my $seclevel=$env{'request.course.id'}.'.['.$csec.'].'.$what;
                    132:     my $seclevelr=$env{'request.course.id'}.'.['.$csec.'].'.$symbparm;
                    133:     my $seclevelm=$env{'request.course.id'}.'.['.$csec.'].'.$mapparm;
                    134: 
                    135:     my $courselevel=$env{'request.course.id'}.'.'.$what;
                    136:     my $courselevelr=$env{'request.course.id'}.'.'.$symbparm;
                    137:     my $courselevelm=$env{'request.course.id'}.'.'.$mapparm;
1.2       www       138: 
1.11      www       139: 
1.182     albertel  140: # --------------------------------------------------------- first, check course
1.11      www       141: 
1.200     www       142:     if (defined($$courseopt{$courselevel})) {
1.269     raeburn   143: 	$outpar[14]=$$courseopt{$courselevel};
                    144: 	$result=14;
1.43      albertel  145:     }
1.11      www       146: 
1.200     www       147:     if (defined($$courseopt{$courselevelm})) {
1.269     raeburn   148: 	$outpar[13]=$$courseopt{$courselevelm};
                    149: 	$result=13;
1.43      albertel  150:     }
1.11      www       151: 
1.182     albertel  152: # ------------------------------------------------------- second, check default
                    153: 
1.269     raeburn   154:     if (defined($def)) { $outpar[12]=$def; $result=12; }
1.182     albertel  155: 
                    156: # ------------------------------------------------------ third, check map parms
                    157: 
1.376     albertel  158:     my $thisparm=&parmhash($symbparm);
1.269     raeburn   159:     if (defined($thisparm)) { $outpar[11]=$thisparm; $result=11; }
1.182     albertel  160: 
1.200     www       161:     if (defined($$courseopt{$courselevelr})) {
1.269     raeburn   162: 	$outpar[10]=$$courseopt{$courselevelr};
                    163: 	$result=10;
1.43      albertel  164:     }
1.11      www       165: 
1.182     albertel  166: # ------------------------------------------------------ fourth, back to course
1.352     albertel  167:     if ($csec ne '') {
1.200     www       168:         if (defined($$courseopt{$seclevel})) {
1.269     raeburn   169: 	    $outpar[9]=$$courseopt{$seclevel};
                    170: 	    $result=9;
1.43      albertel  171: 	}
1.200     www       172:         if (defined($$courseopt{$seclevelm})) {
1.269     raeburn   173: 	    $outpar[8]=$$courseopt{$seclevelm};
                    174: 	    $result=8;
1.43      albertel  175: 	}
                    176: 
1.200     www       177:         if (defined($$courseopt{$seclevelr})) {
1.269     raeburn   178: 	    $outpar[7]=$$courseopt{$seclevelr};
                    179: 	    $result=7;
1.43      albertel  180: 	}
                    181:     }
1.275     raeburn   182: # ------------------------------------------------------ fifth, check course group
1.352     albertel  183:     if ($cgroup ne '') {
1.269     raeburn   184:         if (defined($$courseopt{$grplevel})) {
                    185:             $outpar[6]=$$courseopt{$grplevel};
                    186:             $result=6;
                    187:         }
                    188:         if (defined($$courseopt{$grplevelm})) {
                    189:             $outpar[5]=$$courseopt{$grplevelm};
                    190:             $result=5;
                    191:         }
                    192:         if (defined($$courseopt{$grplevelr})) {
                    193:             $outpar[4]=$$courseopt{$grplevelr};
                    194:             $result=4;
                    195:         }
                    196:     }
1.11      www       197: 
1.182     albertel  198: # ---------------------------------------------------------- fifth, check user
1.11      www       199: 
1.352     albertel  200:     if ($uname ne '') {
1.200     www       201: 	if (defined($$useropt{$courselevel})) {
                    202: 	    $outpar[3]=$$useropt{$courselevel};
1.43      albertel  203: 	    $result=3;
                    204: 	}
1.10      www       205: 
1.200     www       206: 	if (defined($$useropt{$courselevelm})) {
                    207: 	    $outpar[2]=$$useropt{$courselevelm};
1.43      albertel  208: 	    $result=2;
                    209: 	}
1.2       www       210: 
1.200     www       211: 	if (defined($$useropt{$courselevelr})) {
                    212: 	    $outpar[1]=$$useropt{$courselevelr};
1.43      albertel  213: 	    $result=1;
                    214: 	}
                    215:     }
1.44      albertel  216:     return ($result,@outpar);
1.2       www       217: }
                    218: 
1.198     www       219: 
                    220: 
1.376     albertel  221: # --- Caches local to lonparmset
                    222: 
                    223:     
                    224: sub reset_caches {
                    225:     &resetparmhash();
                    226:     &resetsymbcache();
                    227:     &resetrulescache();
1.203     www       228: }
                    229: 
1.376     albertel  230: {
                    231:     my $parmhashid;
                    232:     my %parmhash;
                    233:     sub resetparmhash {
                    234: 	undef($parmhashid);
                    235: 	undef(%parmhash);
                    236:     }
                    237:     
                    238:     sub cacheparmhash {
                    239: 	if ($parmhashid eq  $env{'request.course.fn'}) { return; }
                    240: 	my %parmhashfile;
                    241: 	if (tie(%parmhashfile,'GDBM_File',
                    242: 		$env{'request.course.fn'}.'_parms.db',&GDBM_READER(),0640)) {
                    243: 	    %parmhash=%parmhashfile;
                    244: 	    untie(%parmhashfile);
                    245: 	    $parmhashid=$env{'request.course.fn'};
                    246: 	}
1.201     www       247:     }
1.376     albertel  248:  
                    249:     sub parmhash {
                    250: 	my ($id) = @_;
                    251: 	&cacheparmhash();
                    252: 	return $parmhash{$id};
                    253:     }
                    254:  }
                    255: 
                    256: {   
                    257:     my $symbsid;
                    258:     my %symbs;
                    259:     sub resetsymbcache {
                    260: 	undef($symbsid);
                    261: 	undef(%symbs);
                    262:     }
                    263:     
                    264:     sub symbcache {
                    265: 	my $id=shift;
                    266: 	if ($symbsid ne $env{'request.course.id'}) {
                    267: 	    undef(%symbs);
                    268: 	}
                    269: 	if (!$symbs{$id}) {
                    270: 	    my $navmap = Apache::lonnavmaps::navmap->new();
                    271: 	    if ($id=~/\./) {
                    272: 		my $resource=$navmap->getById($id);
                    273: 		$symbs{$id}=$resource->symb();
                    274: 	    } else {
                    275: 		my $resource=$navmap->getByMapPc($id);
                    276: 		$symbs{$id}=&Apache::lonnet::declutter($resource->src());
                    277: 	    }
                    278: 	    $symbsid=$env{'request.course.id'};
1.201     www       279: 	}
1.376     albertel  280: 	return $symbs{$id};
1.201     www       281:     }
1.376     albertel  282:  }
1.201     www       283: 
1.376     albertel  284: {   
                    285:     my $rulesid;
                    286:     my %rules;
                    287:     sub resetrulescache {
                    288: 	undef($rulesid);
                    289: 	undef(%rules);
                    290:     }
                    291:     
                    292:     sub rulescache {
                    293: 	my $id=shift;
                    294: 	if ($rulesid ne $env{'request.course.id'}
                    295: 	    && !defined($rules{$id})) {
                    296: 	    my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                    297: 	    my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
                    298: 	    %rules=&Apache::lonnet::dump('parmdefactions',$dom,$crs);
                    299: 	    $rulesid=$env{'request.course.id'};
                    300: 	}
                    301: 	return $rules{$id};
1.221     www       302:     }
                    303: }
                    304: 
1.229     www       305: sub preset_defaults {
                    306:     my $type=shift;
                    307:     if (&rulescache($type.'_action') eq 'default') {
                    308: # yes, there is something
                    309: 	return (&rulescache($type.'_hours'),
                    310: 		&rulescache($type.'_min'),
                    311: 		&rulescache($type.'_sec'),
                    312: 		&rulescache($type.'_value'));
                    313:     } else {
                    314: # nothing there or something else
                    315: 	return ('','','','','');
                    316:     }
                    317: }
                    318: 
1.186     www       319: ##################################################
1.277     www       320: 
                    321: sub date_sanity_info {
                    322:    my $checkdate=shift;
                    323:    unless ($checkdate) { return ''; }
                    324:    my $result='';
                    325:    my $crsprefix='course.'.$env{'request.course.id'}.'.';
                    326:    if ($env{$crsprefix.'default_enrollment_end_date'}) {
                    327:       if ($checkdate>$env{$crsprefix.'default_enrollment_end_date'}) {
1.413     bisitz    328:          $result.='<div class="LC_warning">'
                    329:                  .&mt('After course enrollment end!')
                    330:                  .'</div>';
1.277     www       331:       }
                    332:    }
                    333:    if ($env{$crsprefix.'default_enrollment_start_date'}) {
                    334:       if ($checkdate<$env{$crsprefix.'default_enrollment_start_date'}) {
1.413     bisitz    335:          $result.='<div class="LC_warning">'
                    336:                  .&mt('Before course enrollment start!')
                    337:                  .'</div>';
1.277     www       338:       }
                    339:    }
1.413     bisitz    340: # Preparation for additional warnings about dates in the past/future.
                    341: # An improved, more context sensitive version is recommended,
                    342: # e.g. warn for due and answer dates which are defined before the corresponding open date, etc.
                    343: #   if ($checkdate<time) {
                    344: #      $result.='<div class="LC_info">'
                    345: #              .'('.&mt('in the past').')'
                    346: #              .'</div>';
                    347: #      }
                    348: #   if ($checkdate>time) {
                    349: #      $result.='<div class="LC_info">'
                    350: #              .'('.&mt('in the future').')'
                    351: #              .'</div>';
                    352: #      }
1.277     www       353:    return $result;
                    354: }
                    355: ##################################################
1.186     www       356: ##################################################
                    357: #
1.197     www       358: # Store a parameter by ID
1.186     www       359: #
                    360: # Takes
                    361: # - resource id
                    362: # - name of parameter
                    363: # - level
                    364: # - new value
                    365: # - new type
1.187     www       366: # - username
                    367: # - userdomain
                    368: 
1.186     www       369: sub storeparm {
1.269     raeburn   370:     my ($sresid,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$cgroup)=@_;
1.275     raeburn   371:     &storeparm_by_symb(&symbcache($sresid),$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,'',$cgroup);
1.197     www       372: }
                    373: 
                    374: #
                    375: # Store a parameter by symb
                    376: #
                    377: # Takes
                    378: # - symb
                    379: # - name of parameter
                    380: # - level
                    381: # - new value
                    382: # - new type
                    383: # - username
                    384: # - userdomain
1.226     www       385: my %recstack;
1.197     www       386: sub storeparm_by_symb {
1.275     raeburn   387:     my ($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$recflag,$cgroup)=@_;
1.226     www       388:     unless ($recflag) {
                    389: # first time call
                    390: 	%recstack=();
                    391: 	$recflag=1;
                    392:     }
                    393: # store parameter
                    394:     &storeparm_by_symb_inner
1.269     raeburn   395: 	($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$cgroup);
1.266     www       396: # don't do anything if parameter was reset
                    397:     unless ($nval) { return; }
1.226     www       398:     my ($prefix,$parm)=($spnam=~/^(.*[\_\.])([^\_\.]+)$/);
                    399: # remember that this was set
                    400:     $recstack{$parm}=1;
                    401: # what does this trigger?
                    402:     foreach my $triggered (split(/\:/,&rulescache($parm.'_triggers'))) {
                    403: # don't backfire
                    404:        unless ((!$triggered) || ($recstack{$triggered})) {
                    405: 	   my $action=&rulescache($triggered.'_action');
                    406: 	   my ($whichaction,$whichparm)=($action=~/^(.*\_)([^\_]+)$/);
                    407: # set triggered parameter on same level
                    408: 	   my $newspnam=$prefix.$triggered;
1.227     www       409: 	   my $newvalue='';
1.228     www       410: 	   my $active=1;
                    411: 	   if ($action=~/^when\_setting/) {
                    412: # are there restrictions?
                    413: 	       if (&rulescache($triggered.'_triggervalue')=~/\w/) {
                    414: 		   $active=0;
                    415: 		   foreach my $possiblevalue (split(/\s*\,\s*/,&rulescache($triggered.'_triggervalue'))) {
                    416: 		       if (lc($possiblevalue) eq lc($nval)) { $active=1; }
                    417: 		   }
                    418: 	       }
                    419: 	       $newvalue=&rulescache($triggered.'_value');
1.227     www       420: 	   } else {
                    421: 	       my $totalsecs=((&rulescache($triggered.'_days')*24+&rulescache($triggered.'_hours'))*60+&rulescache($triggered.'_min'))*60+&rulescache($triggered.'_sec');
1.228     www       422: 	       if ($action=~/^later\_than/) {
                    423: 		   $newvalue=$nval+$totalsecs;
                    424: 	       } else {
                    425: 		   $newvalue=$nval-$totalsecs;
                    426: 	       }
                    427: 	   }
                    428: 	   if ($active) {
                    429: 	       &storeparm_by_symb($symb,$newspnam,$snum,$newvalue,&rulescache($triggered.'_type'),
1.275     raeburn   430: 				   $uname,$udom,$csec,$recflag,$cgroup);
1.227     www       431: 	   }
1.226     www       432:        }
                    433:     }
                    434:     return '';
                    435: }
                    436: 
1.293     www       437: sub log_parmset {
                    438:     return &Apache::lonnet::instructor_log('parameterlog',@_);
1.284     www       439: }
                    440: 
1.226     www       441: sub storeparm_by_symb_inner {
1.197     www       442: # ---------------------------------------------------------- Get symb, map, etc
1.269     raeburn   443:     my ($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$cgroup)=@_;
1.197     www       444: # ---------------------------------------------------------- Construct prefixes
1.186     www       445:     $spnam=~s/\_([^\_]+)$/\.$1/;
1.197     www       446:     my $map=(&Apache::lonnet::decode_symb($symb))[0];    
1.305     albertel  447:     $map = &Apache::lonnet::deversion($map);
                    448: 
1.197     www       449:     my $symbparm=$symb.'.'.$spnam;
                    450:     my $mapparm=$map.'___(all).'.$spnam;
                    451: 
1.269     raeburn   452:     my $grplevel=$env{'request.course.id'}.'.['.$cgroup.'].'.$spnam;
                    453:     my $grplevelr=$env{'request.course.id'}.'.['.$cgroup.'].'.$symbparm;
                    454:     my $grplevelm=$env{'request.course.id'}.'.['.$cgroup.'].'.$mapparm;
                    455: 
1.190     albertel  456:     my $seclevel=$env{'request.course.id'}.'.['.$csec.'].'.$spnam;
                    457:     my $seclevelr=$env{'request.course.id'}.'.['.$csec.'].'.$symbparm;
                    458:     my $seclevelm=$env{'request.course.id'}.'.['.$csec.'].'.$mapparm;
1.186     www       459:     
1.190     albertel  460:     my $courselevel=$env{'request.course.id'}.'.'.$spnam;
                    461:     my $courselevelr=$env{'request.course.id'}.'.'.$symbparm;
                    462:     my $courselevelm=$env{'request.course.id'}.'.'.$mapparm;
1.186     www       463:     
                    464:     my $storeunder='';
1.269     raeburn   465:     if (($snum==14) || ($snum==3)) { $storeunder=$courselevel; }
                    466:     if (($snum==13) || ($snum==2)) { $storeunder=$courselevelm; }
                    467:     if (($snum==10) || ($snum==1)) { $storeunder=$courselevelr; }
                    468:     if ($snum==9) { $storeunder=$seclevel; }
                    469:     if ($snum==8) { $storeunder=$seclevelm; }
                    470:     if ($snum==7) { $storeunder=$seclevelr; }
                    471:     if ($snum==6) { $storeunder=$grplevel; }
                    472:     if ($snum==5) { $storeunder=$grplevelm; }
                    473:     if ($snum==4) { $storeunder=$grplevelr; }
                    474: 
1.186     www       475:     
                    476:     my $delete;
                    477:     if ($nval eq '') { $delete=1;}
                    478:     my %storecontent = ($storeunder         => $nval,
                    479: 			$storeunder.'.type' => $ntype);
                    480:     my $reply='';
                    481:     if ($snum>3) {
                    482: # ---------------------------------------------------------------- Store Course
                    483: #
1.200     www       484: 	my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                    485: 	my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
1.186     www       486: # Expire sheets
                    487: 	&Apache::lonnet::expirespread('','','studentcalc');
1.269     raeburn   488: 	if (($snum==10) || ($snum==7) || ($snum==4)) {
1.197     www       489: 	    &Apache::lonnet::expirespread('','','assesscalc',$symb);
1.269     raeburn   490: 	} elsif (($snum==11) || ($snum==8) || ($snum==5)) {
1.197     www       491: 	    &Apache::lonnet::expirespread('','','assesscalc',$map);
1.186     www       492: 	} else {
                    493: 	    &Apache::lonnet::expirespread('','','assesscalc');
                    494: 	}
                    495: # Store parameter
                    496: 	if ($delete) {
                    497: 	    $reply=&Apache::lonnet::del
1.200     www       498: 		('resourcedata',[keys(%storecontent)],$cdom,$cnum);
1.290     www       499:             &log_parmset(\%storecontent,1);
1.186     www       500: 	} else {
                    501: 	    $reply=&Apache::lonnet::cput
1.200     www       502: 		('resourcedata',\%storecontent,$cdom,$cnum);
1.290     www       503: 	    &log_parmset(\%storecontent);
1.186     www       504: 	}
1.200     www       505: 	&Apache::lonnet::devalidatecourseresdata($cnum,$cdom);
1.186     www       506:     } else {
                    507: # ------------------------------------------------------------------ Store User
                    508: #
                    509: # Expire sheets
                    510: 	&Apache::lonnet::expirespread($uname,$udom,'studentcalc');
                    511: 	if ($snum==1) {
                    512: 	    &Apache::lonnet::expirespread
1.197     www       513: 		($uname,$udom,'assesscalc',$symb);
1.186     www       514: 	} elsif ($snum==2) {
                    515: 	    &Apache::lonnet::expirespread
1.197     www       516: 		($uname,$udom,'assesscalc',$map);
1.186     www       517: 	} else {
                    518: 	    &Apache::lonnet::expirespread($uname,$udom,'assesscalc');
                    519: 	}
                    520: # Store parameter
                    521: 	if ($delete) {
                    522: 	    $reply=&Apache::lonnet::del
                    523: 		('resourcedata',[keys(%storecontent)],$udom,$uname);
1.290     www       524: 	    &log_parmset(\%storecontent,1,$uname,$udom);
1.186     www       525: 	} else {
                    526: 	    $reply=&Apache::lonnet::cput
                    527: 		('resourcedata',\%storecontent,$udom,$uname);
1.290     www       528: 	    &log_parmset(\%storecontent,0,$uname,$udom);
1.186     www       529: 	}
1.191     albertel  530: 	&Apache::lonnet::devalidateuserresdata($uname,$udom);
1.186     www       531:     }
                    532:     
                    533:     if ($reply=~/^error\:(.*)/) {
1.314     albertel  534: 	return "<span class=\"LC_error\">Write Error: $1</span>";
1.186     www       535:     }
                    536:     return '';
                    537: }
                    538: 
1.59      matthew   539: ##################################################
                    540: ##################################################
                    541: 
                    542: =pod
                    543: 
                    544: =item valout
                    545: 
                    546: Format a value for output.
                    547: 
1.320     www       548: Inputs:  $value, $type, $editable
1.59      matthew   549: 
                    550: Returns: $value, formatted for output.  If $type indicates it is a date,
                    551: localtime($value) is returned.
1.320     www       552: $editable will return an icon to click on
1.9       www       553: 
1.59      matthew   554: =cut
                    555: 
                    556: ##################################################
                    557: ##################################################
1.9       www       558: sub valout {
1.320     www       559:     my ($value,$type,$editable)=@_;
1.59      matthew   560:     my $result = '';
                    561:     # Values of zero are valid.
                    562:     if (! $value && $value ne '0') {
1.320     www       563: 	if ($editable) {
1.324     www       564: 	    $result = '<span class="LC_clickhere">*</span>';
1.320     www       565: 	} else {
                    566: 	    $result='&nbsp;';
                    567: 	}
1.59      matthew   568:     } else {
1.66      www       569:         if ($type eq 'date_interval') {
                    570:             my ($sec,$min,$hour,$mday,$mon,$year)=gmtime($value);
1.413     bisitz    571:             my @timer;
1.66      www       572:             $year=$year-70;
                    573:             $mday--;
                    574:             if ($year) {
1.413     bisitz    575: #               $result.=&mt('[quant,_1,yr]',$year).' ';
                    576:                 push(@timer,&mt('[quant,_1,yr]',$year));
1.66      www       577:             }
                    578:             if ($mon) {
1.413     bisitz    579: #               $result.=&mt('[quant,_1,mth]',$mon).' ';
                    580:                 push(@timer,&mt('[quant,_1,mth]',$mon));
1.66      www       581:             }
                    582:             if ($mday) {
1.413     bisitz    583: #               $result.=&mt('[quant,_1,day]',$mday).' ';
                    584:                 push(@timer,&mt('[quant,_1,day]',$mday));
1.66      www       585:             }
                    586:             if ($hour) {
1.413     bisitz    587: #               $result.=&mt('[quant,_1,hr]',$hour).' ';
                    588:                 push(@timer,&mt('[quant,_1,hr]',$hour));
1.66      www       589:             }
                    590:             if ($min) {
1.413     bisitz    591: #               $result.=&mt('[quant,_1,min]',$min).' ';
                    592:                 push(@timer,&mt('[quant,_1,min]',$min));
1.66      www       593:             }
                    594:             if ($sec) {
1.413     bisitz    595: #               $result.=&mt('[quant,_1,sec]',$sec).' ';
                    596:                 push(@timer,&mt('[quant,_1,sec]',$sec));
1.66      www       597:             }
1.413     bisitz    598: #           $result=~s/\s+$//;
                    599:             if (!@timer) { # Special case: all entries 0 -> display "0 secs" intead of empty field to keep this field editable
                    600:                 push(@timer,&mt('[quant,_1,sec]',0));
                    601:             }
                    602:             $result.=join(", ",@timer);
1.213     www       603:         } elsif (&isdateparm($type)) {
1.361     albertel  604:             $result = &Apache::lonlocal::locallocaltime($value).
                    605: 		&date_sanity_info($value);
1.59      matthew   606:         } else {
                    607:             $result = $value;
1.378     albertel  608: 	    $result = &HTML::Entities::encode($result,'"<>&');
1.59      matthew   609:         }
                    610:     }
                    611:     return $result;
1.9       www       612: }
                    613: 
1.59      matthew   614: ##################################################
                    615: ##################################################
                    616: 
                    617: =pod
1.5       www       618: 
1.59      matthew   619: =item plink
                    620: 
                    621: Produces a link anchor.
                    622: 
                    623: Inputs: $type,$dis,$value,$marker,$return,$call
                    624: 
                    625: Returns: scalar with html code for a link which will envoke the 
                    626: javascript function 'pjump'.
                    627: 
                    628: =cut
                    629: 
                    630: ##################################################
                    631: ##################################################
1.5       www       632: sub plink {
                    633:     my ($type,$dis,$value,$marker,$return,$call)=@_;
1.23      www       634:     my $winvalue=$value;
                    635:     unless ($winvalue) {
1.213     www       636: 	if (&isdateparm($type)) {
1.190     albertel  637:             $winvalue=$env{'form.recent_'.$type};
1.23      www       638:         } else {
1.190     albertel  639:             $winvalue=$env{'form.recent_'.(split(/\_/,$type))[0]};
1.23      www       640:         }
                    641:     }
1.229     www       642:     my ($parmname)=((split(/\&/,$marker))[1]=~/\_([^\_]+)$/);
                    643:     my ($hour,$min,$sec,$val)=&preset_defaults($parmname);
                    644:     unless (defined($winvalue)) { $winvalue=$val; }
1.378     albertel  645:     my $valout = &valout($value,$type,1);
                    646:     foreach my $item (\$type, \$dis, \$winvalue, \$marker, \$return, \$call,
                    647: 		      \$hour, \$min, \$sec) {
                    648: 	$$item = &HTML::Entities::encode($$item,'"<>&');
                    649: 	$$item =~ s/\'/\\\'/g;
                    650:     }
1.270     www       651:     return '<table width="100%"><tr valign="top" align="right"><td><a name="'.$marker.'" /></td></tr><tr><td align="center">'.
1.43      albertel  652: 	'<a href="javascript:pjump('."'".$type."','".$dis."','".$winvalue."','"
1.229     www       653: 	    .$marker."','".$return."','".$call."','".$hour."','".$min."','".$sec."'".');">'.
1.378     albertel  654: 	    $valout.'</a></td></tr></table>';
1.5       www       655: }
                    656: 
1.280     albertel  657: sub page_js {
                    658: 
1.81      www       659:     my $selscript=&Apache::loncommon::studentbrowser_javascript();
1.88      matthew   660:     my $pjump_def = &Apache::lonhtmlcommon::pjump_javascript_definition();
1.280     albertel  661: 
                    662:     return(<<ENDJS);
                    663: <script type="text/javascript">
1.44      albertel  664: 
                    665:     function pclose() {
                    666:         parmwin=window.open("/adm/rat/empty.html","LONCAPAparms",
                    667:                  "height=350,width=350,scrollbars=no,menubar=no");
                    668:         parmwin.close();
                    669:     }
                    670: 
1.88      matthew   671:     $pjump_def
1.44      albertel  672: 
                    673:     function psub() {
                    674:         pclose();
                    675:         if (document.parmform.pres_marker.value!='') {
                    676:             document.parmform.action+='#'+document.parmform.pres_marker.value;
                    677:             var typedef=new Array();
                    678:             typedef=document.parmform.pres_type.value.split('_');
                    679:            if (document.parmform.pres_type.value!='') {
                    680:             if (typedef[0]=='date') {
                    681:                 eval('document.parmform.recent_'+
                    682:                      document.parmform.pres_type.value+
                    683: 		     '.value=document.parmform.pres_value.value;');
                    684:             } else {
                    685:                 eval('document.parmform.recent_'+typedef[0]+
                    686: 		     '.value=document.parmform.pres_value.value;');
                    687:             }
                    688: 	   }
                    689:             document.parmform.submit();
                    690:         } else {
                    691:             document.parmform.pres_value.value='';
                    692:             document.parmform.pres_marker.value='';
                    693:         }
                    694:     }
                    695: 
1.57      albertel  696:     function openWindow(url, wdwName, w, h, toolbar,scrollbar) {
                    697:         var options = "width=" + w + ",height=" + h + ",";
                    698:         options += "resizable=yes,scrollbars="+scrollbar+",status=no,";
                    699:         options += "menubar=no,toolbar="+toolbar+",location=no,directories=no";
                    700:         var newWin = window.open(url, wdwName, options);
                    701:         newWin.focus();
                    702:     }
1.44      albertel  703: </script>
1.81      www       704: $selscript
1.280     albertel  705: ENDJS
                    706: 
                    707: }
                    708: sub startpage {
                    709:     my ($r) = @_;
1.281     albertel  710: 
1.282     albertel  711:     my %loaditems = ('onunload' => "pclose()",
1.283     albertel  712: 		     'onload'   => "group_or_section('cgroup')",);
1.280     albertel  713: 
1.281     albertel  714:     my $start_page = 
                    715: 	&Apache::loncommon::start_page('Set/Modify Course Parameters',
                    716: 				       &page_js(),
1.282     albertel  717: 				       {'add_entries' => \%loaditems,});
1.280     albertel  718:     my $breadcrumbs = 
1.321     www       719: 	&Apache::lonhtmlcommon::breadcrumbs('Table Mode Parameter Setting','Table_Mode');
1.280     albertel  720:     $r->print(<<ENDHEAD);
1.281     albertel  721: $start_page
1.193     albertel  722: $breadcrumbs
                    723: <form method="post" action="/adm/parmset?action=settable" name="parmform">
1.280     albertel  724: <input type="hidden" value='' name="pres_value" />
                    725: <input type="hidden" value='' name="pres_type" />
                    726: <input type="hidden" value='' name="pres_marker" />
                    727: <input type="hidden" value='1' name="prevvisit" />
1.44      albertel  728: ENDHEAD
                    729: }
                    730: 
1.209     www       731: 
1.44      albertel  732: sub print_row {
1.201     www       733:     my ($r,$which,$part,$name,$symbp,$rid,$default,$defaulttype,$display,$defbgone,
1.275     raeburn   734: 	$defbgtwo,$defbgthree,$parmlev,$uname,$udom,$csec,$cgroup,$usersgroups)=@_;
                    735:     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                    736:     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                    737:     my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom);
1.66      www       738: # get the values for the parameter in cascading order
                    739: # empty levels will remain empty
1.44      albertel  740:     my ($result,@outpar)=&parmval($$part{$which}.'.'.$$name{$which},
1.275     raeburn   741: 	  $rid,$$default{$which},$uname,$udom,$csec,$cgroup,$courseopt);
1.66      www       742: # get the type for the parameters
                    743: # problem: these may not be set for all levels
                    744:     my ($typeresult,@typeoutpar)=&parmval($$part{$which}.'.'.
1.275     raeburn   745:                                           $$name{$which}.'.type',$rid,
                    746: 		 $$defaulttype{$which},$uname,$udom,$csec,$cgroup,$courseopt);
1.66      www       747: # cascade down manually
1.182     albertel  748:     my $cascadetype=$$defaulttype{$which};
1.269     raeburn   749:     for (my $i=14;$i>0;$i--) {
1.66      www       750: 	 if ($typeoutpar[$i]) { 
                    751:             $cascadetype=$typeoutpar[$i];
                    752: 	} else {
                    753:             $typeoutpar[$i]=$cascadetype;
                    754:         }
                    755:     }
1.57      albertel  756:     my $parm=$$display{$which};
                    757: 
1.203     www       758:     if ($parmlev eq 'full') {
1.57      albertel  759:         $r->print('<td bgcolor='.$defbgtwo.' align="center">'
                    760:                   .$$part{$which}.'</td>');
                    761:     } else {    
                    762:         $parm=~s|\[.*\]\s||g;
                    763:     }
1.231     www       764:     my $automatic=&rulescache(($which=~/\_([^\_]+)$/)[0].'_triggers');
                    765:     if ($automatic) {
1.314     albertel  766: 	$parm.='<span class="LC_warning"><br />'.&mt('Automatically sets').' '.join(', ',split(/\:/,$automatic)).'</span>';
1.231     www       767:     }
1.159     albertel  768:     $r->print('<td bgcolor='.$defbgone.'>'.$parm.'</td>');
1.57      albertel  769:    
1.44      albertel  770:     my $thismarker=$which;
                    771:     $thismarker=~s/^parameter\_//;
                    772:     my $mprefix=$rid.'&'.$thismarker.'&';
1.275     raeburn   773:     my $effective_parm = &valout($outpar[$result],$typeoutpar[$result]);
                    774:     my ($othergrp,$grp_parm,$controlgrp);
1.44      albertel  775: 
1.57      albertel  776:     if ($parmlev eq 'general') {
                    777: 
                    778:         if ($uname) {
1.66      www       779:             &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
1.269     raeburn   780:         } elsif ($cgroup) {
                    781:             &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
1.57      albertel  782:         } elsif ($csec) {
1.269     raeburn   783:             &print_td($r,9,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); 
1.57      albertel  784:         } else {
1.269     raeburn   785:             &print_td($r,14,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); 
1.57      albertel  786:         }
                    787:     } elsif ($parmlev eq 'map') {
                    788: 
                    789:         if ($uname) {
1.66      www       790:             &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
1.269     raeburn   791:         } elsif ($cgroup) {
                    792:             &print_td($r,5,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
1.57      albertel  793:         } elsif ($csec) {
1.269     raeburn   794:             &print_td($r,8,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
1.57      albertel  795:         } else {
1.269     raeburn   796:             &print_td($r,13,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
1.57      albertel  797:         }
                    798:     } else {
1.275     raeburn   799:         if ($uname) {
                    800:             if (@{$usersgroups} > 1) {
                    801:                 my ($coursereply,$grp_parm,$controlgrp);
                    802:                 ($coursereply,$othergrp,$grp_parm,$controlgrp) =
                    803:                     &print_usergroups($r,$$part{$which}.'.'.$$name{$which},
                    804:                        $rid,$cgroup,$defbgone,$usersgroups,$result,$courseopt);
                    805:                 if ($coursereply && $result > 3) {
                    806:                     if (defined($controlgrp)) {
                    807:                         if ($cgroup ne $controlgrp) {
                    808:                             $effective_parm = $grp_parm;
                    809:                             $result = 0;
                    810:                         }
                    811:                     }
                    812:                 }
                    813:             }
                    814:         }
1.57      albertel  815: 
1.269     raeburn   816:         &print_td($r,14,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
1.57      albertel  817: 
1.269     raeburn   818: 	&print_td($r,13,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
                    819: 	&print_td($r,12,'#FFDDDD',$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
                    820: 	&print_td($r,11,'#FFDDDD',$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
1.203     www       821: 	&print_td($r,10,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
                    822: 	
                    823: 	if ($csec) {
1.269     raeburn   824: 	    &print_td($r,9,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
                    825: 	    &print_td($r,8,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
                    826: 	    &print_td($r,7,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
1.203     www       827: 	}
1.269     raeburn   828: 
                    829:         if ($cgroup) {
                    830:             &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
                    831:             &print_td($r,5,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
                    832:             &print_td($r,4,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
                    833:         }
1.275     raeburn   834:      
1.203     www       835: 	if ($uname) {
1.275     raeburn   836:             if ($othergrp) {
                    837:                 $r->print($othergrp);
                    838:             }
1.203     www       839: 	    &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
                    840: 	    &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
                    841: 	    &print_td($r,1,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
                    842: 	}
1.57      albertel  843: 
                    844:     } # end of $parmlev if/else
1.275     raeburn   845:     $r->print('<td bgcolor="#CCCCFF" align="center">'.$effective_parm.'</td>');
1.136     albertel  846: 
1.203     www       847:     if ($parmlev eq 'full') {
1.136     albertel  848:         my $sessionval=&Apache::lonnet::EXT('resource.'.$$part{$which}.
1.201     www       849:                                         '.'.$$name{$which},$$symbp{$rid});
1.136     albertel  850:         my $sessionvaltype=$typeoutpar[$result];
                    851:         if (!defined($sessionvaltype)) { $sessionvaltype=$$defaulttype{$which}; }
1.275     raeburn   852:         $r->print('<td bgcolor="#999999" align="center"><font color="#FFFFFF">'.
1.66      www       853:                   &valout($sessionval,$sessionvaltype).'&nbsp;'.
1.57      albertel  854:                   '</font></td>');
1.136     albertel  855:     }
1.44      albertel  856:     $r->print('</tr>');
1.57      albertel  857:     $r->print("\n");
1.44      albertel  858: }
1.59      matthew   859: 
1.44      albertel  860: sub print_td {
1.66      www       861:     my ($r,$which,$defbg,$result,$outpar,$mprefix,$value,$typeoutpar,$display)=@_;
1.57      albertel  862:     $r->print('<td bgcolor='.(($result==$which)?'"#AAFFAA"':$defbg).
1.114     www       863:               ' align="center">');
1.269     raeburn   864:     if ($which<11 || $which > 12) {
1.114     www       865: 	$r->print(&plink($$typeoutpar[$which],
                    866: 			 $$display{$value},$$outpar[$which],
                    867: 			 $mprefix."$which",'parmform.pres','psub'));
                    868:     } else {
                    869: 	$r->print(&valout($$outpar[$which],$$typeoutpar[$which]));
                    870:     }
                    871:     $r->print('</td>'."\n");
1.57      albertel  872: }
                    873: 
1.275     raeburn   874: sub print_usergroups {
                    875:     my ($r,$what,$rid,$cgroup,$defbg,$usersgroups,$result,$courseopt) = @_;
                    876:     my $courseid = $env{'request.course.id'};
                    877:     my $output;
                    878:     my $symb = &symbcache($rid);
                    879:     my $symbparm=$symb.'.'.$what;
                    880:     my $map=(&Apache::lonnet::decode_symb($symb))[0];
                    881:     my $mapparm=$map.'___(all).'.$what;
                    882:     my ($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype) =
                    883:           &parm_control_group($courseid,$usersgroups,$symbparm,$mapparm,$what,
                    884:                                                                    $courseopt);
                    885:     my $bgcolor = $defbg;
                    886:     my $grp_parm;
                    887:     if (($coursereply) && ($cgroup ne $resultgroup)) { 
                    888:         if ($result > 3) {
                    889:             $bgcolor = '"#AAFFAA"';
                    890:             $grp_parm = &valout($coursereply,$resulttype);
                    891:         }
                    892:         $grp_parm = &valout($coursereply,$resulttype);
                    893:         $output = '<td bgcolor='.$bgcolor.' align="center">';
                    894:         if ($resultgroup && $resultlevel) {
                    895:             $output .= '<small><b>'.$resultgroup.'</b> ('.$resultlevel.'): </small>'.$grp_parm;
                    896:         } else {
                    897:             $output .= '&nbsp;';
                    898:         }
                    899:         $output .= '</td>';
                    900:     } else {
                    901:         $output .= '<td bgcolor='.$bgcolor.'>&nbsp;</td>';
                    902:     }
                    903:     return ($coursereply,$output,$grp_parm,$resultgroup);
                    904: }
                    905: 
                    906: sub parm_control_group {
                    907:     my ($courseid,$usersgroups,$symbparm,$mapparm,$what,$courseopt) = @_;
                    908:     my ($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype);
                    909:     my $grpfound = 0;
                    910:     my @levels = ($symbparm,$mapparm,$what);
                    911:     my @levelnames = ('resource','map/folder','general');
                    912:     foreach my $group (@{$usersgroups}) {
                    913:         if ($grpfound) { last; }
                    914:         for (my $i=0; $i<@levels; $i++) {
                    915:             my $item = $courseid.'.['.$group.'].'.$levels[$i];
                    916:             if (defined($$courseopt{$item})) {
                    917:                 $coursereply = $$courseopt{$item};
                    918:                 $resultitem = $item;
                    919:                 $resultgroup = $group;
                    920:                 $resultlevel = $levelnames[$i];
                    921:                 $resulttype = $$courseopt{$item.'.type'};
                    922:                 $grpfound = 1;
                    923:                 last;
                    924:             }
                    925:         }
                    926:     }
                    927:     return($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype);
                    928: }
1.201     www       929: 
1.63      bowersj2  930: =pod
                    931: 
                    932: =item B<extractResourceInformation>: Given the course data hash, extractResourceInformation extracts lots of information about the course's resources into a variety of hashes.
                    933: 
                    934: Input: See list below:
                    935: 
                    936: =over 4
                    937: 
                    938: =item B<ids>: An array that will contain all of the ids in the course.
                    939: 
                    940: =item B<typep>: hash, id->type, where "type" contains the extension of the file, thus, I<problem exam quiz assess survey form>.
                    941: 
1.171     www       942: =item B<keyp>: hash, id->key list, will contain a comma separated list of the meta-data keys available for the given id
1.63      bowersj2  943: 
                    944: =item B<allparms>: hash, name of parameter->display value (what is the display value?)
                    945: 
                    946: =item B<allparts>: hash, part identification->text representation of part, where the text representation is "[Part $part]"
                    947: 
                    948: =item B<allkeys>: hash, full key to part->display value (what's display value?)
                    949: 
                    950: =item B<allmaps>: hash, ???
                    951: 
                    952: =item B<fcat>: ???
                    953: 
                    954: =item B<defp>: hash, ???
                    955: 
                    956: =item B<mapp>: ??
                    957: 
                    958: =item B<symbp>: hash, id->full sym?
                    959: 
                    960: =back
                    961: 
                    962: =cut
                    963: 
                    964: sub extractResourceInformation {
                    965:     my $ids = shift;
                    966:     my $typep = shift;
                    967:     my $keyp = shift;
                    968:     my $allparms = shift;
                    969:     my $allparts = shift;
                    970:     my $allmaps = shift;
                    971:     my $mapp = shift;
                    972:     my $symbp = shift;
1.82      www       973:     my $maptitles=shift;
1.196     www       974:     my $uris=shift;
1.210     www       975:     my $keyorder=shift;
1.211     www       976:     my $defkeytype=shift;
1.196     www       977: 
1.210     www       978:     my $keyordercnt=100;
1.63      bowersj2  979: 
1.196     www       980:     my $navmap = Apache::lonnavmaps::navmap->new();
                    981:     my @allres=$navmap->retrieveResources(undef,undef,1,undef,1);
                    982:     foreach my $resource (@allres) {
                    983: 	my $id=$resource->id();
                    984:         my ($mapid,$resid)=split(/\./,$id);
                    985: 	if ($mapid eq '0') { next; }
                    986: 	$$ids[$#$ids+1]=$id;
                    987: 	my $srcf=$resource->src();
                    988: 	$srcf=~/\.(\w+)$/;
                    989: 	$$typep{$id}=$1;
                    990: 	$$keyp{$id}='';
                    991:         $$uris{$id}=$srcf;
1.363     albertel  992: 	foreach my $key (split(/\,/,&Apache::lonnet::metadata($srcf,'allpossiblekeys'))) {
                    993: 	    next if ($key!~/^parameter_/);
                    994: 
1.209     www       995: # Hidden parameters
1.363     albertel  996: 	    next if (&Apache::lonnet::metadata($srcf,$key.'.hidden') eq 'parm');
1.209     www       997: #
                    998: # allparms is a hash of parameter names
                    999: #
1.363     albertel 1000: 	    my $name=&Apache::lonnet::metadata($srcf,$key.'.name');
1.375     albertel 1001: 	    if (!exists($$allparms{$name}) || $$allparms{$name} =~ m/^\s*$/ ) {
1.363     albertel 1002: 		my $display= &Apache::lonnet::metadata($srcf,$key.'.display');
1.196     www      1003: 		my $parmdis = $display;
1.412     bisitz   1004: 		$parmdis =~ s/\s*\[Part.*$//g;
1.363     albertel 1005: 		$$allparms{$name}=$parmdis;
                   1006: 		if (ref($defkeytype)) {
                   1007: 		    $$defkeytype{$name}=
                   1008: 			&Apache::lonnet::metadata($srcf,$key.'.type');
                   1009: 		}
                   1010: 	    }
                   1011: 
1.209     www      1012: #
                   1013: # allparts is a hash of all parts
                   1014: #
1.363     albertel 1015: 	    my $part= &Apache::lonnet::metadata($srcf,$key.'.part');
1.410     bisitz   1016: 	    $$allparts{$part} = &mt('Part: [_1]',$part);
1.209     www      1017: #
                   1018: # Remember all keys going with this resource
                   1019: #
1.363     albertel 1020: 	    if ($$keyp{$id}) {
                   1021: 		$$keyp{$id}.=','.$key;
                   1022: 	    } else {
                   1023: 		$$keyp{$id}=$key;
                   1024: 	    }
1.210     www      1025: #
                   1026: # Put in order
                   1027: # 
1.363     albertel 1028: 	    unless ($$keyorder{$key}) {
                   1029: 		$$keyorder{$key}=$keyordercnt;
                   1030: 		$keyordercnt++;
                   1031: 	    }
                   1032: 	}
1.210     www      1033: 
1.363     albertel 1034: 	
                   1035: 	if (!exists($$mapp{$mapid})) {
                   1036: 	    $$mapp{$id}=
                   1037: 		&Apache::lonnet::declutter($resource->enclosing_map_src());
                   1038: 	    $$mapp{$mapid}=$$mapp{$id};
                   1039: 	    $$allmaps{$mapid}=$$mapp{$id};
                   1040: 	    if ($mapid eq '1') {
1.401     bisitz   1041: 		$$maptitles{$mapid}=&mt('Main Course Documents');
1.363     albertel 1042: 	    } else {
                   1043: 		$$maptitles{$mapid}=
                   1044: 		    &Apache::lonnet::gettitle($$mapp{$id});    
1.63      bowersj2 1045: 	    }
1.363     albertel 1046: 	    $$maptitles{$$mapp{$id}}=$$maptitles{$mapid};
                   1047: 	    $$symbp{$mapid}=$$mapp{$id}.'___(all)';
1.196     www      1048: 	} else {
1.363     albertel 1049: 	    $$mapp{$id} = $$mapp{$mapid};
1.196     www      1050: 	}
                   1051: 	$$symbp{$id}=&Apache::lonnet::encode_symb($$mapp{$id},$resid,$srcf);
1.63      bowersj2 1052:     }
                   1053: }
                   1054: 
1.208     www      1055: 
                   1056: ##################################################
                   1057: ##################################################
                   1058: 
1.213     www      1059: sub isdateparm {
                   1060:     my $type=shift;
                   1061:     return (($type=~/^date/) && (!($type eq 'date_interval')));
                   1062: }
                   1063: 
1.208     www      1064: sub parmmenu {
1.211     www      1065:     my ($r,$allparms,$pscat,$keyorder)=@_;
1.208     www      1066:     my $tempkey;
                   1067:     $r->print(<<ENDSCRIPT);
                   1068: <script type="text/javascript">
                   1069:     function checkall(value, checkName) {
                   1070: 	for (i=0; i<document.forms.parmform.elements.length; i++) {
                   1071:             ele = document.forms.parmform.elements[i];
                   1072:             if (ele.name == checkName) {
                   1073:                 document.forms.parmform.elements[i].checked=value;
                   1074:             }
                   1075:         }
                   1076:     }
1.210     www      1077: 
                   1078:     function checkthis(thisvalue, checkName) {
                   1079: 	for (i=0; i<document.forms.parmform.elements.length; i++) {
                   1080:             ele = document.forms.parmform.elements[i];
                   1081:             if (ele.name == checkName) {
                   1082: 		if (ele.value == thisvalue) {
                   1083: 		    document.forms.parmform.elements[i].checked=true;
                   1084: 		}
                   1085:             }
                   1086:         }
                   1087:     }
                   1088: 
                   1089:     function checkdates() {
                   1090: 	checkthis('duedate','pscat');
                   1091:  	checkthis('opendate','pscat');
                   1092: 	checkthis('answerdate','pscat');
1.218     www      1093:     }
                   1094: 
                   1095:     function checkdisset() {
                   1096: 	checkthis('discussend','pscat');
                   1097:  	checkthis('discusshide','pscat');
                   1098:     }
                   1099: 
                   1100:     function checkcontdates() {
                   1101: 	checkthis('contentopen','pscat');
                   1102:  	checkthis('contentclose','pscat');
                   1103:     }
                   1104:  
1.210     www      1105: 
                   1106:     function checkvisi() {
                   1107: 	checkthis('hiddenresource','pscat');
                   1108:  	checkthis('encrypturl','pscat');
                   1109: 	checkthis('problemstatus','pscat');
                   1110: 	checkthis('contentopen','pscat');
                   1111: 	checkthis('opendate','pscat');
                   1112:     }
                   1113: 
                   1114:     function checkparts() {
                   1115: 	checkthis('hiddenparts','pscat');
                   1116: 	checkthis('display','pscat');
                   1117: 	checkthis('ordered','pscat');
                   1118:     }
                   1119: 
                   1120:     function checkstandard() {
                   1121:         checkall(false,'pscat');
                   1122: 	checkdates();
                   1123: 	checkthis('weight','pscat');
                   1124: 	checkthis('maxtries','pscat');
                   1125:     }
                   1126: 
1.208     www      1127: </script>
                   1128: ENDSCRIPT
1.209     www      1129:     $r->print();
1.317     albertel 1130:     $r->print("\n<table id=\"LC_parm_overview_parm_menu\"><tr>");
1.208     www      1131:     my $cnt=0;
1.211     www      1132:     foreach $tempkey (&keysindisplayorder($allparms,$keyorder)) {
1.317     albertel 1133: 	$r->print("\n<td><label><input type='checkbox' name='pscat' ");
1.208     www      1134: 	$r->print('value="'.$tempkey.'"');
                   1135: 	if ($$pscat[0] eq "all" || grep $_ eq $tempkey, @{$pscat}) {
                   1136: 	    $r->print(' checked');
                   1137: 	}
1.411     bisitz   1138: 	$r->print('>'.($$allparms{$tempkey}=~/\S/ ? &mt($$allparms{$tempkey})
                   1139: 		                                  : &mt($tempkey))
1.375     albertel 1140: 		  .'</label></td>');
1.209     www      1141:  	$cnt++;
                   1142:         if ($cnt==3) {
                   1143: 	    $r->print("</tr>\n<tr>");
                   1144: 	    $cnt=0;
                   1145: 	}
1.208     www      1146:     }
1.410     bisitz   1147:     $r->print('</tr>'
                   1148:              .'<tr id=\"LC_parm_overview_parm_menu_selectors\">'
                   1149:              .'<td valign="top">'
                   1150:              .'<fieldset><legend><b>'.&mt('Parameter Selection').'</b></legend>'
                   1151:              .'<span class="LC_nobreak">'
                   1152:              .'&bull; <a href="javascript:checkall(true, \'pscat\')">'.&mt('Select All').'</a>'
                   1153:              .'</span>'
                   1154:              .'<br />'
                   1155:              .'<span class="LC_nobreak">'
                   1156:              .'&bull; <a href="javascript:checkstandard()">'.&mt('Select Common Only').'</a>'
                   1157:              .'</span>'
                   1158:              .'<br />'
                   1159:              .'<span class="LC_nobreak">'
                   1160:              .'&bull; <a href="javascript:checkall(false, \'pscat\')">'.&mt('Unselect All').'</a>'
                   1161:              .'</span>'
                   1162:              .'</fieldset>'
                   1163:              .'</td>'
                   1164:              .'<td colspan="2" valign="top">'
                   1165:              .'<fieldset><legend><b>'.&mt('Add Selection for...').'</b></legend>'
                   1166:              .'<span class="LC_nobreak">'
                   1167:              .'&bull; <a href="javascript:checkdates()">'.&mt('Problem Dates').'</a>'
                   1168:              .'</span>'
                   1169:              .'<span class="LC_nobreak">'
                   1170:              .' &bull; <a href="javascript:checkcontdates()">'.&mt('Content Dates').'</a>'
                   1171:              .'</span>'
                   1172: #            .'<br />'
                   1173:              .'<span class="LC_nobreak">'
                   1174:              .' &bull; <a href="javascript:checkdisset()">'.&mt('Discussion Settings').'</a>'
                   1175:              .'</span>'
                   1176:              .'<span class="LC_nobreak">'
                   1177:              .' &bull; <a href="javascript:checkvisi()">'.&mt('Visibilities').'</a>'
                   1178:              .'</span>'
                   1179: #            .'<br />'
                   1180:              .'<span class="LC_nobreak">'
                   1181:              .' &bull; <a href="javascript:checkparts()">'.&mt('Part Parameters').'</a>'
                   1182:              .'</span>'
                   1183:              .'</fieldset>'
                   1184:              .'</td>'
                   1185:              .'</tr></table>'
                   1186:     );
1.208     www      1187: }
                   1188: 
1.209     www      1189: sub partmenu {
                   1190:     my ($r,$allparts,$psprt)=@_;
1.211     www      1191:     $r->print('<select multiple name="psprt" size="8">');
1.208     www      1192:     $r->print('<option value="all"');
1.401     bisitz   1193:     $r->print(' selected="selected"') unless (@{$psprt});
1.208     www      1194:     $r->print('>'.&mt('All Parts').'</option>');
                   1195:     my %temphash=();
                   1196:     foreach (@{$psprt}) { $temphash{$_}=1; }
1.234     albertel 1197:     foreach my $tempkey (sort {
                   1198: 	if ($a==$b) { return ($a cmp $b) } else { return ($a <=> $b); }
                   1199:     } keys(%{$allparts})) {
1.208     www      1200: 	unless ($tempkey =~ /\./) {
                   1201: 	    $r->print('<option value="'.$tempkey.'"');
                   1202: 	    if ($$psprt[0] eq "all" ||  $temphash{$tempkey}) {
1.401     bisitz   1203: 		$r->print(' selected="selected"');
1.208     www      1204: 	    }
                   1205: 	    $r->print('>'.$$allparts{$tempkey}.'</option>');
                   1206: 	}
                   1207:     }
1.209     www      1208:     $r->print('</select>');
                   1209: }
                   1210: 
                   1211: sub usermenu {
1.275     raeburn  1212:     my ($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,$usersgroups)=@_;
1.209     www      1213:     my $chooseopt=&Apache::loncommon::select_dom_form($udom,'udom').' '.
                   1214:         &Apache::loncommon::selectstudent_link('parmform','uname','udom');
                   1215:     my $selscript=&Apache::loncommon::studentbrowser_javascript();
1.412     bisitz   1216: 
1.209     www      1217:     my $sections='';
1.300     albertel 1218:     my %sectionhash = &Apache::loncommon::get_sections();
                   1219: 
1.269     raeburn  1220:     my $groups;
1.307     raeburn  1221:     my %grouphash = &Apache::longroup::coursegroups();
1.299     albertel 1222: 
1.412     bisitz   1223:     my $g_s_header='';
                   1224:     my $g_s_footer='';
                   1225: 
1.300     albertel 1226:     if (%sectionhash) {
1.412     bisitz   1227:         $sections=&mt('Section:').' <select name="csec"';
1.299     albertel 1228:         if (%grouphash && $parmlev ne 'full') {
1.269     raeburn  1229:             $sections .= qq| onchange="group_or_section('csec')" |;
                   1230:         }
                   1231:         $sections .= '>';
1.275     raeburn  1232: 	foreach my $section ('',sort keys %sectionhash) {
                   1233: 	    $sections.='<option value="'.$section.'" '.
                   1234: 		($section eq $csec?'selected="selected"':'').'>'.$section.
                   1235:                                                               '</option>';
1.209     www      1236:         }
                   1237:         $sections.='</select>';
1.269     raeburn  1238:     }
1.412     bisitz   1239: 
1.300     albertel 1240:     if (%sectionhash && %grouphash && $parmlev ne 'full') {
1.412     bisitz   1241:         $sections .= '&nbsp;'.&mt('or').'&nbsp;';
1.269     raeburn  1242:         $sections .= qq|
                   1243: <script type="text/javascript">
                   1244: function group_or_section(caller) {
                   1245:    if (caller == "cgroup") {
                   1246:        if (document.parmform.cgroup.selectedIndex != 0) {
                   1247:            document.parmform.csec.selectedIndex = 0;
                   1248:        }
                   1249:    } else {
                   1250:        if (document.parmform.csec.selectedIndex != 0) {
                   1251:            document.parmform.cgroup.selectedIndex = 0;
                   1252:        }
                   1253:    }
                   1254: }
                   1255: </script>
                   1256: |;
                   1257:     } else {
                   1258:         $sections .= qq|
                   1259: <script type="text/javascript">
                   1260: function group_or_section(caller) {
                   1261:     return;
                   1262: }
                   1263: </script>
                   1264: |;
                   1265:     } 
1.299     albertel 1266: 
                   1267:     if (%grouphash) {
1.412     bisitz   1268:         $groups=&mt('Group:').' <select name="cgroup"';
1.300     albertel 1269:         if (%sectionhash && $env{'form.action'} eq 'settable') {
1.269     raeburn  1270:             $groups .= qq| onchange="group_or_section('cgroup')" |;
                   1271:         }
                   1272:         $groups .= '>';
1.275     raeburn  1273:         foreach my $grp ('',sort keys %grouphash) {
                   1274:             $groups.='<option value="'.$grp.'" ';
                   1275:             if ($grp eq $cgroup) {
                   1276:                 unless ((defined($uname)) && ($grp eq '')) {
                   1277:                     $groups .=  'selected="selected" ';
                   1278:                 }
                   1279:             } elsif (!defined($cgroup)) {
                   1280:                 if (@{$usersgroups} == 1) {
                   1281:                     if ($grp eq $$usersgroups[0]) {
                   1282:                         $groups .=  'selected="selected" ';
                   1283:                     }
                   1284:                 }
                   1285:             }
                   1286:             $groups .= '>'.$grp.'</option>';
1.269     raeburn  1287:         }
                   1288:         $groups.='</select>';
                   1289:     }
1.412     bisitz   1290: 
                   1291:     if (%sectionhash || %grouphash) {
                   1292:         $g_s_header='<fieldset><legend>'.&mt('Group/Section').'</legend><div>';
                   1293:         $g_s_footer='</div></fieldset>';
                   1294:     }
                   1295: 
                   1296:     $r->print('<b>'
                   1297:              .$g_s_header
                   1298:              .$sections
                   1299:              .$groups
                   1300:              .$g_s_footer
                   1301:              .'<fieldset><legend>'.&mt('User').'</legend><div>'
                   1302:              .&mt('For User [_1] or Student/Employee ID [_2] at Domain [_3]'
                   1303:                  ,'<input type="text" value="'.$uname.'" size="12" name="uname" />'
                   1304:                  ,'<input type="text" value="'.$id.'" size="12" name="id" /> '
                   1305:                  ,$chooseopt)
                   1306:              .'</div></fieldset>'
                   1307:              .'</b>'
                   1308:     );
1.209     www      1309: }
                   1310: 
                   1311: sub displaymenu {
1.211     www      1312:     my ($r,$allparms,$allparts,$pscat,$psprt,$keyorder)=@_;
1.209     www      1313:     $r->print('<table border="1"><tr><th>'.&mt('Select Parameters to View').'</th><th>'.
                   1314: 	     &mt('Select Parts to View').'</th></tr><tr><td>');  
1.211     www      1315:     &parmmenu($r,$allparms,$pscat,$keyorder);
1.412     bisitz   1316:     $r->print('</td><td valign="top" align="center">');
1.209     www      1317:     &partmenu($r,$allparts,$psprt);
                   1318:     $r->print('</td></tr></table>');
                   1319: }
                   1320: 
                   1321: sub mapmenu {
                   1322:     my ($r,$allmaps,$pschp,$maptitles)=@_;
1.231     www      1323:     $r->print('<b>'.&mt('Select Enclosing Map or Folder').'</b> ');
1.209     www      1324:     $r->print('<select name="pschp">');
                   1325:     $r->print('<option value="all">'.&mt('All Maps or Folders').'</option>');
                   1326:     foreach (sort {$$allmaps{$a} cmp $$allmaps{$b}} keys %{$allmaps}) {
1.208     www      1327: 	$r->print('<option value="'.$_.'"');
1.401     bisitz   1328: 	if (($pschp eq $_)) { $r->print(' selected="selected"'); }
1.209     www      1329: 	$r->print('>'.$$maptitles{$_}.($$allmaps{$_}!~/^uploaded/?' ['.$$allmaps{$_}.']':'').'</option>');
                   1330:     }
                   1331:     $r->print("</select>");
                   1332: }
                   1333: 
                   1334: sub levelmenu {
                   1335:     my ($r,$alllevs,$parmlev)=@_;
1.231     www      1336:     $r->print('<b>'.&mt('Select Parameter Level').
                   1337: 	      &Apache::loncommon::help_open_topic('Course_Parameter_Levels').'</b> ');
1.209     www      1338:     $r->print('<select name="parmlev">');
                   1339:     foreach (reverse sort keys %{$alllevs}) {
                   1340: 	$r->print('<option value="'.$$alllevs{$_}.'"');
                   1341: 	if ($parmlev eq $$alllevs{$_}) {
1.401     bisitz   1342: 	    $r->print(' selected="selected"'); 
1.209     www      1343: 	}
1.401     bisitz   1344: 	$r->print('>'.&mt($_).'</option>');
1.208     www      1345:     }
1.209     www      1346:     $r->print("</select>");
1.208     www      1347: }
                   1348: 
1.211     www      1349: 
                   1350: sub sectionmenu {
                   1351:     my ($r,$selectedsections)=@_;
1.300     albertel 1352:     my %sectionhash = &Apache::loncommon::get_sections();
                   1353:     return if (!%sectionhash);
                   1354: 
                   1355:     $r->print('<select name="Section" multiple="true" size="8" >');
                   1356:     foreach my $s ('all',sort keys %sectionhash) {
                   1357: 	$r->print('    <option value="'.$s.'"');
                   1358: 	foreach (@{$selectedsections}) {
                   1359: 	    if ($s eq $_) {
1.401     bisitz   1360: 		$r->print(' selected="selected"');
1.300     albertel 1361: 		last;
1.212     www      1362: 	    }
                   1363: 	}
1.300     albertel 1364: 	$r->print('>'.$s."</option>\n");
                   1365:     }
                   1366:     $r->print("</select>\n");
1.269     raeburn  1367: }
                   1368: 
                   1369: sub groupmenu {
                   1370:     my ($r,$selectedgroups)=@_;
1.307     raeburn  1371:     my %grouphash = &Apache::longroup::coursegroups();
1.299     albertel 1372:     return if (!%grouphash);
                   1373: 
                   1374:     $r->print('<select name="Group" multiple="true" size="8" >');
                   1375:     foreach my $group (sort(keys(%grouphash))) {
                   1376: 	$r->print('    <option value="'.$group.'"');
                   1377: 	foreach (@{$selectedgroups}) {
                   1378: 	    if ($group eq $_) {
1.401     bisitz   1379: 		$r->print(' selected="selected"');
1.299     albertel 1380: 		last;
                   1381: 	    }
                   1382: 	}
                   1383: 	$r->print('>'.$group."</option>\n");
1.211     www      1384:     }
1.299     albertel 1385:     $r->print("</select>\n");
1.211     www      1386: }
                   1387: 
1.269     raeburn  1388: 
1.210     www      1389: sub keysplit {
                   1390:     my $keyp=shift;
                   1391:     return (split(/\,/,$keyp));
                   1392: }
                   1393: 
                   1394: sub keysinorder {
                   1395:     my ($name,$keyorder)=@_;
                   1396:     return sort {
                   1397: 	$$keyorder{$a} <=> $$keyorder{$b};
                   1398:     } (keys %{$name});
                   1399: }
                   1400: 
1.236     albertel 1401: sub keysinorder_bytype {
                   1402:     my ($name,$keyorder)=@_;
                   1403:     return sort {
                   1404: 	my $ta=(split('_',$a))[-1];
                   1405: 	my $tb=(split('_',$b))[-1];
                   1406: 	if ($$keyorder{'parameter_0_'.$ta} == $$keyorder{'parameter_0_'.$tb}) {
                   1407: 	    return ($a cmp $b);
                   1408: 	}
                   1409: 	$$keyorder{'parameter_0_'.$ta} <=> $$keyorder{'parameter_0_'.$tb};
                   1410:     } (keys %{$name});
                   1411: }
                   1412: 
1.211     www      1413: sub keysindisplayorder {
                   1414:     my ($name,$keyorder)=@_;
                   1415:     return sort {
                   1416: 	$$keyorder{'parameter_0_'.$a} <=> $$keyorder{'parameter_0_'.$b};
                   1417:     } (keys %{$name});
                   1418: }
                   1419: 
1.214     www      1420: sub sortmenu {
                   1421:     my ($r,$sortorder)=@_;
1.236     albertel 1422:     $r->print('<br /><label><input type="radio" name="sortorder" value="realmstudent"');
1.214     www      1423:     if ($sortorder eq 'realmstudent') {
                   1424:        $r->print(' checked="on"');
                   1425:     }
                   1426:     $r->print(' />'.&mt('Sort by realm first, then student (group/section)'));
1.236     albertel 1427:     $r->print('</label><br /><label><input type="radio" name="sortorder" value="studentrealm"');
1.214     www      1428:     if ($sortorder eq 'studentrealm') {
                   1429:        $r->print(' checked="on"');
                   1430:     }
1.236     albertel 1431:     $r->print(' />'.&mt('Sort by student (group/section) first, then realm').
                   1432: 	      '</label>');
1.214     www      1433: }
                   1434: 
1.211     www      1435: sub standardkeyorder {
                   1436:     return ('parameter_0_opendate' => 1,
                   1437: 	    'parameter_0_duedate' => 2,
                   1438: 	    'parameter_0_answerdate' => 3,
                   1439: 	    'parameter_0_interval' => 4,
                   1440: 	    'parameter_0_weight' => 5,
                   1441: 	    'parameter_0_maxtries' => 6,
                   1442: 	    'parameter_0_hinttries' => 7,
                   1443: 	    'parameter_0_contentopen' => 8,
                   1444: 	    'parameter_0_contentclose' => 9,
                   1445: 	    'parameter_0_type' => 10,
                   1446: 	    'parameter_0_problemstatus' => 11,
                   1447: 	    'parameter_0_hiddenresource' => 12,
                   1448: 	    'parameter_0_hiddenparts' => 13,
                   1449: 	    'parameter_0_display' => 14,
                   1450: 	    'parameter_0_ordered' => 15,
                   1451: 	    'parameter_0_tol' => 16,
                   1452: 	    'parameter_0_sig' => 17,
1.218     www      1453: 	    'parameter_0_turnoffunit' => 18,
                   1454:             'parameter_0_discussend' => 19,
                   1455:             'parameter_0_discusshide' => 20);
1.211     www      1456: }
                   1457: 
1.59      matthew  1458: ##################################################
                   1459: ##################################################
                   1460: 
                   1461: =pod
                   1462: 
                   1463: =item assessparms
                   1464: 
                   1465: Show assessment data and parameters.  This is a large routine that should
                   1466: be simplified and shortened... someday.
                   1467: 
                   1468: Inputs: $r
                   1469: 
                   1470: Returns: nothing
                   1471: 
1.63      bowersj2 1472: Variables used (guessed by Jeremy):
                   1473: 
                   1474: =over 4
                   1475: 
                   1476: =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.
                   1477: 
                   1478: =item B<psprt>: ParameterS PaRTs? a list of the parts of a problem that we are displaying? Used to display only selected parts?
                   1479: 
                   1480: =item B<allmaps>:
                   1481: 
                   1482: =back
                   1483: 
1.59      matthew  1484: =cut
                   1485: 
                   1486: ##################################################
                   1487: ##################################################
1.30      www      1488: sub assessparms {
1.1       www      1489: 
1.43      albertel 1490:     my $r=shift;
1.201     www      1491: 
                   1492:     my @ids=();
                   1493:     my %symbp=();
                   1494:     my %mapp=();
                   1495:     my %typep=();
                   1496:     my %keyp=();
                   1497:     my %uris=();
                   1498:     my %maptitles=();
                   1499: 
1.2       www      1500: # -------------------------------------------------------- Variable declaration
1.209     www      1501: 
1.129     www      1502:     my %allmaps=();
                   1503:     my %alllevs=();
1.57      albertel 1504: 
1.187     www      1505:     my $uname;
                   1506:     my $udom;
                   1507:     my $uhome;
                   1508:     my $csec;
1.269     raeburn  1509:     my $cgroup;
1.275     raeburn  1510:     my @usersgroups = ();
1.187     www      1511:  
1.190     albertel 1512:     my $coursename=$env{'course.'.$env{'request.course.id'}.'.description'};
1.187     www      1513: 
1.57      albertel 1514:     $alllevs{'Resource Level'}='full';
1.215     www      1515:     $alllevs{'Map/Folder Level'}='map';
1.57      albertel 1516:     $alllevs{'Course Level'}='general';
                   1517: 
                   1518:     my %allparms;
                   1519:     my %allparts;
1.210     www      1520: #
                   1521: # Order in which these parameters will be displayed
                   1522: #
1.211     www      1523:     my %keyorder=&standardkeyorder();
                   1524: 
1.43      albertel 1525:     @ids=();
                   1526:     %symbp=();
                   1527:     %typep=();
                   1528: 
                   1529:     my $message='';
                   1530: 
1.190     albertel 1531:     $csec=$env{'form.csec'};
1.269     raeburn  1532:     $cgroup=$env{'form.cgroup'};
1.188     www      1533: 
1.190     albertel 1534:     if      ($udom=$env{'form.udom'}) {
                   1535:     } elsif ($udom=$env{'request.role.domain'}) {
                   1536:     } elsif ($udom=$env{'user.domain'}) {
1.172     albertel 1537:     } else {
                   1538: 	$udom=$r->dir_config('lonDefDomain');
                   1539:     }
1.43      albertel 1540: 
1.134     albertel 1541:     my @pscat=&Apache::loncommon::get_env_multiple('form.pscat');
1.190     albertel 1542:     my $pschp=$env{'form.pschp'};
1.134     albertel 1543:     my @psprt=&Apache::loncommon::get_env_multiple('form.psprt');
1.76      www      1544:     if (!@psprt) { $psprt[0]='0'; }
1.57      albertel 1545: 
1.43      albertel 1546:     my $pssymb='';
1.57      albertel 1547:     my $parmlev='';
                   1548:  
1.190     albertel 1549:     unless ($env{'form.parmlev'}) {
1.57      albertel 1550:         $parmlev = 'map';
                   1551:     } else {
1.190     albertel 1552:         $parmlev = $env{'form.parmlev'};
1.57      albertel 1553:     }
1.26      www      1554: 
1.29      www      1555: # ----------------------------------------------- Was this started from grades?
                   1556: 
1.190     albertel 1557:     if (($env{'form.command'} eq 'set') && ($env{'form.url'})
                   1558: 	&& (!$env{'form.dis'})) {
                   1559: 	my $url=$env{'form.url'};
1.194     albertel 1560: 	$url=~s-^http://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--;
1.43      albertel 1561: 	$pssymb=&Apache::lonnet::symbread($url);
1.92      albertel 1562: 	if (!@pscat) { @pscat=('all'); }
1.43      albertel 1563: 	$pschp='';
1.57      albertel 1564:         $parmlev = 'full';
1.190     albertel 1565:     } elsif ($env{'form.symb'}) {
                   1566: 	$pssymb=$env{'form.symb'};
1.92      albertel 1567: 	if (!@pscat) { @pscat=('all'); }
1.43      albertel 1568: 	$pschp='';
1.57      albertel 1569:         $parmlev = 'full';
1.43      albertel 1570:     } else {
1.190     albertel 1571: 	$env{'form.url'}='';
1.43      albertel 1572:     }
                   1573: 
1.190     albertel 1574:     my $id=$env{'form.id'};
1.43      albertel 1575:     if (($id) && ($udom)) {
                   1576: 	$uname=(&Apache::lonnet::idget($udom,$id))[1];
                   1577: 	if ($uname) {
                   1578: 	    $id='';
                   1579: 	} else {
                   1580: 	    $message=
1.314     albertel 1581: 		'<span class="LC_error">'.&mt("Unknown ID")." '$id' ".
                   1582: 		&mt('at domain')." '$udom'</span>";
1.43      albertel 1583: 	}
                   1584:     } else {
1.190     albertel 1585: 	$uname=$env{'form.uname'};
1.43      albertel 1586:     }
                   1587:     unless ($udom) { $uname=''; }
                   1588:     $uhome='';
                   1589:     if ($uname) {
                   1590: 	$uhome=&Apache::lonnet::homeserver($uname,$udom);
                   1591:         if ($uhome eq 'no_host') {
                   1592: 	    $message=
1.314     albertel 1593: 		'<span class="LC_error">'.&mt("Unknown user")." '$uname' ".
                   1594: 		&mt("at domain")." '$udom'</span>";
1.43      albertel 1595: 	    $uname='';
1.12      www      1596:         } else {
1.103     albertel 1597: 	    $csec=&Apache::lonnet::getsection($udom,$uname,
1.190     albertel 1598: 					      $env{'request.course.id'});
1.269     raeburn  1599:             
1.43      albertel 1600: 	    if ($csec eq '-1') {
1.314     albertel 1601: 		$message='<span class="LC_error">'.
1.133     www      1602: 		    &mt("User")." '$uname' ".&mt("at domain")." '$udom' ".
1.314     albertel 1603: 		    &mt("not in this course")."</span>";
1.43      albertel 1604: 		$uname='';
1.190     albertel 1605: 		$csec=$env{'form.csec'};
1.269     raeburn  1606:                 $cgroup=$env{'form.cgroup'};
1.43      albertel 1607: 	    } else {
                   1608: 		my %name=&Apache::lonnet::userenvironment($udom,$uname,
                   1609: 		      ('firstname','middlename','lastname','generation','id'));
1.133     www      1610: 		$message="\n<p>\n".&mt("Full Name").": ".
1.43      albertel 1611: 		    $name{'firstname'}.' '.$name{'middlename'}.' '
                   1612: 			.$name{'lastname'}.' '.$name{'generation'}.
1.336     albertel 1613: 			    "<br />\n".&mt('ID').": ".$name{'id'}.'<p>';
1.43      albertel 1614: 	    }
1.297     raeburn  1615:             @usersgroups = &Apache::lonnet::get_users_groups(
1.275     raeburn  1616:                                        $udom,$uname,$env{'request.course.id'});
1.297     raeburn  1617:             if (@usersgroups > 0) {
1.306     albertel 1618:                 unless (grep(/^\Q$cgroup\E$/,@usersgroups)) {
1.275     raeburn  1619:                     $cgroup = $usersgroups[0];
1.297     raeburn  1620:                 }
1.269     raeburn  1621:             }
1.12      www      1622:         }
1.43      albertel 1623:     }
1.2       www      1624: 
1.43      albertel 1625:     unless ($csec) { $csec=''; }
1.269     raeburn  1626:     unless ($cgroup) { $cgroup=''; }
1.12      www      1627: 
1.14      www      1628: # --------------------------------------------------------- Get all assessments
1.210     www      1629:     &extractResourceInformation(\@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allmaps, 
                   1630: 				\%mapp, \%symbp,\%maptitles,\%uris,
                   1631: 				\%keyorder);
1.63      bowersj2 1632: 
1.57      albertel 1633:     $mapp{'0.0'} = '';
                   1634:     $symbp{'0.0'} = '';
1.99      albertel 1635: 
1.14      www      1636: # ---------------------------------------------------------- Anything to store?
1.190     albertel 1637:     if ($env{'form.pres_marker'}) {
1.205     www      1638:         my @markers=split(/\&\&\&/,$env{'form.pres_marker'});
                   1639:         my @values=split(/\&\&\&/,$env{'form.pres_value'});
                   1640:         my @types=split(/\&\&\&/,$env{'form.pres_type'});
                   1641: 	for (my $i=0;$i<=$#markers;$i++) {
                   1642: 	    $message.=&storeparm(split(/\&/,$markers[$i]),
                   1643: 				 $values[$i],
                   1644: 				 $types[$i],
1.269     raeburn  1645: 				 $uname,$udom,$csec,$cgroup);
1.205     www      1646: 	}
1.68      www      1647: # ---------------------------------------------------------------- Done storing
1.130     www      1648: 	$message.='<h3>'.&mt('Changes can take up to 10 minutes before being active for all students.').&Apache::loncommon::help_open_topic('Caching').'</h3>';
1.68      www      1649:     }
1.57      albertel 1650: #----------------------------------------------- if all selected, fill in array
1.209     www      1651:     if ($pscat[0] eq "all") {@pscat = (keys %allparms);}
                   1652:     if (!@pscat) { @pscat=('duedate','opendate','answerdate','weight','maxtries') }; 
1.57      albertel 1653:     if ($psprt[0] eq "all" || !@psprt) {@psprt = (keys %allparts);}
1.2       www      1654: # ------------------------------------------------------------------ Start page
1.63      bowersj2 1655: 
1.209     www      1656:     &startpage($r);
1.57      albertel 1657: 
1.44      albertel 1658:     foreach ('tolerance','date_default','date_start','date_end',
                   1659: 	     'date_interval','int','float','string') {
                   1660: 	$r->print('<input type="hidden" value="'.
1.378     albertel 1661: 		  &HTML::Entities::encode($env{'form.recent_'.$_},'"&<>').
                   1662: 		  '" name="recent_'.$_.'" />');
1.44      albertel 1663:     }
1.57      albertel 1664:                         
1.44      albertel 1665:     if (!$pssymb) {
1.209     www      1666:         $r->print('<table border="1"><tr><td>');
                   1667:         &levelmenu($r,\%alllevs,$parmlev);
1.128     albertel 1668: 	if ($parmlev ne 'general') {
1.209     www      1669:             $r->print('<td>');
                   1670: 	    &mapmenu($r,\%allmaps,$pschp,\%maptitles);
                   1671: 	    $r->print('</td>');
1.128     albertel 1672: 	}
1.209     www      1673:         $r->print('</td></tr></table>');
1.211     www      1674: 	&displaymenu($r,\%allparms,\%allparts,\@pscat,\@psprt,\%keyorder);
1.44      albertel 1675:     } else {
1.125     www      1676:         my ($map,$id,$resource)=&Apache::lonnet::decode_symb($pssymb);
1.312     albertel 1677: 	my $title = &Apache::lonnet::gettitle($pssymb);
                   1678:         $r->print(&mt('Specific Resource: [_1] ([_2])',$title,$resource).
                   1679:                   '<input type="hidden" value="'.$pssymb.'" name="symb" />'.
1.238     www      1680: 		  '<br /><label><b>'.&mt('Show all parts').': <input type="checkbox" name="psprt" value="all"'.
                   1681: 		  ($env{'form.psprt'}?' checked="checked"':'').' /></b></label><br />');
1.57      albertel 1682:     }
1.275     raeburn  1683:     &usermenu($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,\@usersgroups);    
1.57      albertel 1684: 
1.210     www      1685:     $r->print('<p>'.$message.'</p>');
                   1686: 
1.209     www      1687:     $r->print('<br /><input type="submit" name="dis" value="'.&mt("Update Parameter Display").'" />');
1.57      albertel 1688: 
                   1689:     my @temp_pscat;
                   1690:     map {
                   1691:         my $cat = $_;
                   1692:         push(@temp_pscat, map { $_.'.'.$cat } @psprt);
                   1693:     } @pscat;
                   1694: 
                   1695:     @pscat = @temp_pscat;
                   1696: 
1.209     www      1697:     if (($env{'form.prevvisit'}) || ($pschp) || ($pssymb)) {
1.10      www      1698: # ----------------------------------------------------------------- Start Table
1.57      albertel 1699:         my @catmarker=map { tr|.|_|; 'parameter_'.$_; } @pscat;
1.190     albertel 1700:         my $csuname=$env{'user.name'};
                   1701:         my $csudom=$env{'user.domain'};
1.57      albertel 1702: 
1.203     www      1703:         if ($parmlev eq 'full') {
1.57      albertel 1704:            my $coursespan=$csec?8:5;
1.275     raeburn  1705:            my $userspan=3;
1.269     raeburn  1706:            if ($cgroup ne '') {
                   1707:               $coursespan += 3;
                   1708:            } 
                   1709:       
1.57      albertel 1710:            $r->print('<p><table border=2>');
                   1711:            $r->print('<tr><td colspan=5></td>');
1.130     www      1712:            $r->print('<th colspan='.($coursespan).'>'.&mt('Any User').'</th>');
1.57      albertel 1713:            if ($uname) {
1.275     raeburn  1714:                if (@usersgroups > 1) {
                   1715:                    $userspan ++;
                   1716:                }
                   1717:                $r->print('<th colspan="'.$userspan.'" rowspan="2">');
1.130     www      1718:                $r->print(&mt("User")." $uname ".&mt('at Domain')." $udom</th>");
1.57      albertel 1719:            }
1.133     www      1720: 	   my %lt=&Apache::lonlocal::texthash(
                   1721: 				  'pie'    => "Parameter in Effect",
                   1722: 				  'csv'    => "Current Session Value",
                   1723:                                   'at'     => 'at',
                   1724:                                   'rl'     => "Resource Level",
                   1725: 				  'ic'     => 'in Course',
                   1726: 				  'aut'    => "Assessment URL and Title",
1.143     albertel 1727: 				  'type'   => 'Type',
1.133     www      1728: 				  'emof'   => "Enclosing Map or Folder",
1.143     albertel 1729: 				  'part'   => 'Part',
1.133     www      1730:                                   'pn'     => 'Parameter Name',
                   1731: 				  'def'    => 'default',
                   1732: 				  'femof'  => 'from Enclosing Map or Folder',
                   1733: 				  'gen'    => 'general',
                   1734: 				  'foremf' => 'for Enclosing Map or Folder',
                   1735: 				  'fr'     => 'for Resource'
                   1736: 					      );
1.57      albertel 1737:            $r->print(<<ENDTABLETWO);
1.133     www      1738: <th rowspan=3>$lt{'pie'}</th>
1.336     albertel 1739: <th rowspan=3>$lt{'csv'}<br />($csuname $lt{'at'} $csudom)</th>
1.182     albertel 1740: </tr><tr><td colspan=5></td><th colspan=2>$lt{'ic'}</th><th colspan=2>$lt{'rl'}</th>
                   1741: <th colspan=1>$lt{'ic'}</th>
                   1742: 
1.10      www      1743: ENDTABLETWO
1.57      albertel 1744:            if ($csec) {
1.133     www      1745:                 $r->print("<th colspan=3>".
1.269     raeburn  1746: 			  &mt("in Section")." $csec</th>");
                   1747:            }
                   1748:            if ($cgroup) {
                   1749:                 $r->print("<th colspan=3>".
                   1750:                           &mt("in Group")." $cgroup</th>");
1.57      albertel 1751:            }
                   1752:            $r->print(<<ENDTABLEHEADFOUR);
1.133     www      1753: </tr><tr><th>$lt{'aut'}</th><th>$lt{'type'}</th>
                   1754: <th>$lt{'emof'}</th><th>$lt{'part'}</th><th>$lt{'pn'}</th>
1.192     albertel 1755: <th>$lt{'gen'}</th><th>$lt{'foremf'}</th>
                   1756: <th>$lt{'def'}</th><th>$lt{'femof'}</th><th>$lt{'fr'}</th>
1.10      www      1757: ENDTABLEHEADFOUR
1.57      albertel 1758: 
                   1759:            if ($csec) {
1.130     www      1760:                $r->print('<th>'.&mt('general').'</th><th>'.&mt('for Enclosing Map or Folder').'</th><th>'.&mt('for Resource').'</th>');
1.57      albertel 1761:            }
                   1762: 
1.269     raeburn  1763:            if ($cgroup) {
                   1764:                $r->print('<th>'.&mt('general').'</th><th>'.&mt('for Enclosing Map or Folder').'</th><th>'.&mt('for Resource').'</th>');
                   1765:            }
                   1766: 
1.57      albertel 1767:            if ($uname) {
1.275     raeburn  1768:                if (@usersgroups > 1) {
                   1769:                    $r->print('<th>'.&mt('Control by other group?').'</th>');
                   1770:                }
1.130     www      1771:                $r->print('<th>'.&mt('general').'</th><th>'.&mt('for Enclosing Map or Folder').'</th><th>'.&mt('for Resource').'</th>');
1.57      albertel 1772:            }
                   1773: 
                   1774:            $r->print('</tr>');
                   1775: 
                   1776:            my $defbgone='';
                   1777:            my $defbgtwo='';
1.269     raeburn  1778:            my $defbgthree = '';
1.57      albertel 1779: 
                   1780:            foreach (@ids) {
                   1781: 
                   1782:                 my $rid=$_;
                   1783:                 my ($inmapid)=($rid=~/\.(\d+)$/);
                   1784: 
1.152     albertel 1785:                 if ((!$pssymb && 
                   1786: 		     (($pschp eq 'all') || ($allmaps{$pschp} eq $mapp{$rid})))
                   1787: 		    ||
                   1788: 		    ($pssymb && $pssymb eq $symbp{$rid})) {
1.4       www      1789: # ------------------------------------------------------ Entry for one resource
1.184     albertel 1790:                     if ($defbgone eq '"#E0E099"') {
                   1791:                         $defbgone='"#E0E0DD"';
1.57      albertel 1792:                     } else {
1.184     albertel 1793:                         $defbgone='"#E0E099"';
1.57      albertel 1794:                     }
1.184     albertel 1795:                     if ($defbgtwo eq '"#FFFF99"') {
                   1796:                         $defbgtwo='"#FFFFDD"';
1.57      albertel 1797:                     } else {
1.184     albertel 1798:                         $defbgtwo='"#FFFF99"';
1.57      albertel 1799:                     }
1.269     raeburn  1800:                     if ($defbgthree eq '"#FFBB99"') {
                   1801:                         $defbgthree='"#FFBBDD"';
                   1802:                     } else {
                   1803:                         $defbgthree='"#FFBB99"';
                   1804:                     }
                   1805: 
1.57      albertel 1806:                     my $thistitle='';
                   1807:                     my %name=   ();
                   1808:                     undef %name;
                   1809:                     my %part=   ();
                   1810:                     my %display=();
                   1811:                     my %type=   ();
                   1812:                     my %default=();
1.196     www      1813:                     my $uri=&Apache::lonnet::declutter($uris{$rid});
1.57      albertel 1814: 
1.210     www      1815:                     foreach (&keysplit($keyp{$rid})) {
1.57      albertel 1816:                         my $tempkeyp = $_;
                   1817:                         if (grep $_ eq $tempkeyp, @catmarker) {
                   1818:                           $part{$_}=&Apache::lonnet::metadata($uri,$_.'.part');
                   1819:                           $name{$_}=&Apache::lonnet::metadata($uri,$_.'.name');
                   1820:                           $display{$_}=&Apache::lonnet::metadata($uri,$_.'.display');
                   1821:                           unless ($display{$_}) { $display{$_}=''; }
                   1822:                           $display{$_}.=' ('.$name{$_}.')';
                   1823:                           $default{$_}=&Apache::lonnet::metadata($uri,$_);
                   1824:                           $type{$_}=&Apache::lonnet::metadata($uri,$_.'.type');
                   1825:                           $thistitle=&Apache::lonnet::metadata($uri,$_.'.title');
                   1826:                         }
                   1827:                     }
                   1828:                     my $totalparms=scalar keys %name;
                   1829:                     if ($totalparms>0) {
                   1830:                         my $firstrow=1;
1.274     albertel 1831: 			my $title=&Apache::lonnet::gettitle($symbp{$rid});
1.57      albertel 1832:                         $r->print('<tr><td bgcolor='.$defbgone.
                   1833:                              ' rowspan='.$totalparms.
                   1834:                              '><tt><font size=-1>'.
                   1835:                              join(' / ',split(/\//,$uri)).
                   1836:                              '</font></tt><p><b>'.
1.154     albertel 1837:                              "<a href=\"javascript:openWindow('".
1.274     albertel 1838: 				  &Apache::lonnet::clutter($uri).'?symb='.
1.308     www      1839: 				  &escape($symbp{$rid}).
1.336     albertel 1840:                              "', 'metadatafile', '450', '500', 'no', 'yes');\"".
                   1841:                              " target=\"_self\">$title");
1.57      albertel 1842: 
                   1843:                         if ($thistitle) {
                   1844:                             $r->print(' ('.$thistitle.')');
                   1845:                         }
                   1846:                         $r->print('</a></b></td>');
                   1847:                         $r->print('<td bgcolor='.$defbgtwo.
                   1848:                                       ' rowspan='.$totalparms.'>'.$typep{$rid}.
                   1849:                                       '</td>');
                   1850: 
                   1851:                         $r->print('<td bgcolor='.$defbgone.
                   1852:                                       ' rowspan='.$totalparms.
1.238     www      1853:                                       '>'.$maptitles{$mapp{$rid}}.'</td>');
1.57      albertel 1854: 
1.236     albertel 1855:                         foreach (&keysinorder_bytype(\%name,\%keyorder)) {
1.57      albertel 1856:                             unless ($firstrow) {
                   1857:                                 $r->print('<tr>');
                   1858:                             } else {
                   1859:                                 undef $firstrow;
                   1860:                             }
1.201     www      1861:                             &print_row($r,$_,\%part,\%name,\%symbp,$rid,\%default,
1.57      albertel 1862:                                        \%type,\%display,$defbgone,$defbgtwo,
1.269     raeburn  1863:                                        $defbgthree,$parmlev,$uname,$udom,$csec,
1.275     raeburn  1864:                                                             $cgroup,\@usersgroups);
1.57      albertel 1865:                         }
                   1866:                     }
                   1867:                 }
                   1868:             } # end foreach ids
1.43      albertel 1869: # -------------------------------------------------- End entry for one resource
1.57      albertel 1870:             $r->print('</table>');
1.203     www      1871:         } # end of  full
1.57      albertel 1872: #--------------------------------------------------- Entry for parm level map
                   1873:         if ($parmlev eq 'map') {
                   1874:             my $defbgone = '"E0E099"';
                   1875:             my $defbgtwo = '"FFFF99"';
1.269     raeburn  1876:             my $defbgthree = '"FFBB99"';
1.57      albertel 1877: 
                   1878:             my %maplist;
                   1879: 
                   1880:             if ($pschp eq 'all') {
                   1881:                 %maplist = %allmaps; 
                   1882:             } else {
                   1883:                 %maplist = ($pschp => $mapp{$pschp});
                   1884:             }
                   1885: 
                   1886: #-------------------------------------------- for each map, gather information
                   1887:             my $mapid;
1.60      albertel 1888: 	    foreach $mapid (sort {$maplist{$a} cmp $maplist{$b}} keys %maplist) {
                   1889:                 my $maptitle = $maplist{$mapid};
1.57      albertel 1890: 
                   1891: #-----------------------  loop through ids and get all parameter types for map
                   1892: #-----------------------------------------          and associated information
                   1893:                 my %name = ();
                   1894:                 my %part = ();
                   1895:                 my %display = ();
                   1896:                 my %type = ();
                   1897:                 my %default = ();
                   1898:                 my $map = 0;
                   1899: 
                   1900: #		$r->print("Catmarker: @catmarker<br />\n");
                   1901:                
                   1902:                 foreach (@ids) {
                   1903:                   ($map)=(/([\d]*?)\./);
                   1904:                   my $rid = $_;
                   1905:         
                   1906: #                  $r->print("$mapid:$map:   $rid <br /> \n");
                   1907: 
                   1908:                   if ($map eq $mapid) {
1.196     www      1909:                     my $uri=&Apache::lonnet::declutter($uris{$rid});
1.57      albertel 1910: #                    $r->print("Keys: $keyp{$rid} <br />\n");
                   1911: 
                   1912: #--------------------------------------------------------------------
                   1913: # @catmarker contains list of all possible parameters including part #s
                   1914: # $fullkeyp contains the full part/id # for the extraction of proper parameters
                   1915: # $tempkeyp contains part 0 only (no ids - ie, subparts)
                   1916: # When storing information, store as part 0
                   1917: # When requesting information, request from full part
                   1918: #-------------------------------------------------------------------
1.210     www      1919:                     foreach (&keysplit($keyp{$rid})) {
1.57      albertel 1920:                       my $tempkeyp = $_;
                   1921:                       my $fullkeyp = $tempkeyp;
1.73      albertel 1922:                       $tempkeyp =~ s/_\w+_/_0_/;
1.57      albertel 1923:                       
                   1924:                       if ((grep $_ eq $fullkeyp, @catmarker) &&(!$name{$tempkeyp})) {
                   1925:                         $part{$tempkeyp}="0";
                   1926:                         $name{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.name');
                   1927:                         $display{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.display');
                   1928:                         unless ($display{$tempkeyp}) { $display{$tempkeyp}=''; }
                   1929:                         $display{$tempkeyp}.=' ('.$name{$tempkeyp}.')';
1.73      albertel 1930:                         $display{$tempkeyp} =~ s/_\w+_/_0_/;
1.57      albertel 1931:                         $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp);
                   1932:                         $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.type');
                   1933:                       }
                   1934:                     } # end loop through keys
                   1935:                   }
                   1936:                 } # end loop through ids
                   1937:                                  
                   1938: #---------------------------------------------------- print header information
1.133     www      1939:                 my $foldermap=&mt($maptitle=~/^uploaded/?'Folder':'Map');
1.82      www      1940:                 my $showtitle=$maptitles{$maptitle}.($maptitle!~/^uploaded/?' ['.$maptitle.']':'');
1.401     bisitz   1941:                 my $tmp="";
1.57      albertel 1942:                 if ($uname) {
1.267     albertel 1943: 		    my $person=&Apache::loncommon::plainname($uname,$udom);
1.401     bisitz   1944:                     $tmp.=&mt("User")." <font color=\"red\"><i>$uname \($person\) </i></font> ".
                   1945:                         &mt('in')." \n";
1.57      albertel 1946:                 } else {
1.401     bisitz   1947:                     $tmp.="<font color=\"red\"><i>".&mt('all').'</i></font> '.&mt('users in')." \n";
1.57      albertel 1948:                 }
1.269     raeburn  1949:                 if ($cgroup) {
1.401     bisitz   1950:                     $tmp.=&mt("Group")." <font color=\"red\"><i>$cgroup".
                   1951:                               "</i></font> ".&mt('of')." \n";
1.269     raeburn  1952:                     $csec = '';
                   1953:                 } elsif ($csec) {
1.401     bisitz   1954:                     $tmp.=&mt("Section")." <font color=\"red\"><i>$csec".
                   1955:                               "</i></font> ".&mt('of')." \n";
1.269     raeburn  1956:                 }
1.401     bisitz   1957:                 $r->print('<div align="center"><h4>'
                   1958:                          .&mt('Set Defaults for All Resources in [_1]Specifically for [_2][_3]'
1.404     bisitz   1959:                              ,$foldermap.'<br /><font color="red"><i>'.$showtitle.'</i></font><br />'
1.401     bisitz   1960:                              ,$tmp
                   1961:                              ,'<font color="red"><i>'.$coursename.'</i></font>'
                   1962:                              )
                   1963:                          ."<br /></h4>\n"
                   1964:                          );
1.57      albertel 1965: #---------------------------------------------------------------- print table
                   1966:                 $r->print('<p><table border="2">');
1.130     www      1967:                 $r->print('<tr><th>'.&mt('Parameter Name').'</th>');
                   1968:                 $r->print('<th>'.&mt('Default Value').'</th>');
                   1969:                 $r->print('<th>'.&mt('Parameter in Effect').'</th></tr>');
1.57      albertel 1970: 
1.210     www      1971: 	        foreach (&keysinorder(\%name,\%keyorder)) {
1.168     matthew  1972:                     $r->print('<tr>');
1.201     www      1973:                     &print_row($r,$_,\%part,\%name,\%symbp,$mapid,\%default,
1.269     raeburn  1974:                            \%type,\%display,$defbgone,$defbgtwo,$defbgthree,
                   1975:                            $parmlev,$uname,$udom,$csec,$cgroup);
1.57      albertel 1976:                 }
1.401     bisitz   1977:                 $r->print("</table></div>");
1.57      albertel 1978:             } # end each map
                   1979:         } # end of $parmlev eq map
                   1980: #--------------------------------- Entry for parm level general (Course level)
                   1981:         if ($parmlev eq 'general') {
                   1982:             my $defbgone = '"E0E099"';
                   1983:             my $defbgtwo = '"FFFF99"';
1.269     raeburn  1984:             my $defbgthree = '"FFBB99"';
1.57      albertel 1985: 
                   1986: #-------------------------------------------- for each map, gather information
                   1987:             my $mapid="0.0";
                   1988: #-----------------------  loop through ids and get all parameter types for map
                   1989: #-----------------------------------------          and associated information
                   1990:             my %name = ();
                   1991:             my %part = ();
                   1992:             my %display = ();
                   1993:             my %type = ();
                   1994:             my %default = ();
                   1995:                
                   1996:             foreach (@ids) {
                   1997:                 my $rid = $_;
                   1998:         
1.196     www      1999:                 my $uri=&Apache::lonnet::declutter($uris{$rid});
1.57      albertel 2000: 
                   2001: #--------------------------------------------------------------------
                   2002: # @catmarker contains list of all possible parameters including part #s
                   2003: # $fullkeyp contains the full part/id # for the extraction of proper parameters
                   2004: # $tempkeyp contains part 0 only (no ids - ie, subparts)
                   2005: # When storing information, store as part 0
                   2006: # When requesting information, request from full part
                   2007: #-------------------------------------------------------------------
1.210     www      2008:                 foreach (&keysplit($keyp{$rid})) {
1.57      albertel 2009:                   my $tempkeyp = $_;
                   2010:                   my $fullkeyp = $tempkeyp;
1.73      albertel 2011:                   $tempkeyp =~ s/_\w+_/_0_/;
1.57      albertel 2012:                   if ((grep $_ eq $fullkeyp, @catmarker) &&(!$name{$tempkeyp})) {
                   2013:                     $part{$tempkeyp}="0";
                   2014:                     $name{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.name');
                   2015:                     $display{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.display');
                   2016:                     unless ($display{$tempkeyp}) { $display{$tempkeyp}=''; }
                   2017:                     $display{$tempkeyp}.=' ('.$name{$tempkeyp}.')';
1.73      albertel 2018:                     $display{$tempkeyp} =~ s/_\w+_/_0_/;
1.57      albertel 2019:                     $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp);
                   2020:                     $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.type');
                   2021:                   }
                   2022:                 } # end loop through keys
                   2023:             } # end loop through ids
                   2024:                                  
                   2025: #---------------------------------------------------- print header information
1.133     www      2026: 	    my $setdef=&mt("Set Defaults for All Resources in Course");
1.57      albertel 2027:             $r->print(<<ENDMAPONE);
1.133     www      2028: <center><h4>$setdef
1.135     albertel 2029: <font color="red"><i>$coursename</i></font><br />
1.57      albertel 2030: ENDMAPONE
                   2031:             if ($uname) {
1.267     albertel 2032: 		my $person=&Apache::loncommon::plainname($uname,$udom);
1.135     albertel 2033:                 $r->print(" ".&mt("User")."<font color=\"red\"> <i>$uname \($person\) </i></font> \n");
1.57      albertel 2034:             } else {
1.135     albertel 2035:                 $r->print("<i><font color=\"red\"> ".&mt("ALL")."</i> ".&mt("USERS")."</font> \n");
1.57      albertel 2036:             }
                   2037:             
1.135     albertel 2038:             if ($csec) {$r->print(&mt("Section")."<font color=\"red\"> <i>$csec</i></font>\n")};
1.306     albertel 2039:             if ($cgroup) {$r->print(&mt("Group")."<font color=\"red\"> <i>$cgroup</i></font>\n")};
1.135     albertel 2040:             $r->print("</h4>\n");
1.57      albertel 2041: #---------------------------------------------------------------- print table
                   2042:             $r->print('<p><table border="2">');
1.130     www      2043:             $r->print('<tr><th>'.&mt('Parameter Name').'</th>');
                   2044:             $r->print('<th>'.&mt('Default Value').'</th>');
                   2045:             $r->print('<th>'.&mt('Parameter in Effect').'</th></tr>');
1.57      albertel 2046: 
1.210     www      2047: 	    foreach (&keysinorder(\%name,\%keyorder)) {
1.168     matthew  2048:                 $r->print('<tr>');
1.201     www      2049:                 &print_row($r,$_,\%part,\%name,\%symbp,$mapid,\%default,
1.269     raeburn  2050:                        \%type,\%display,$defbgone,$defbgtwo,$defbgthree,
                   2051:                                    $parmlev,$uname,$udom,$csec,$cgroup);
1.57      albertel 2052:             }
                   2053:             $r->print("</table></center>");
                   2054:         } # end of $parmlev eq general
1.43      albertel 2055:     }
1.280     albertel 2056:     $r->print('</form>'.&Apache::loncommon::end_page());
1.57      albertel 2057: } # end sub assessparms
1.30      www      2058: 
1.59      matthew  2059: 
                   2060: ##################################################
                   2061: ##################################################
                   2062: 
                   2063: =pod
                   2064: 
                   2065: =item crsenv
                   2066: 
1.105     matthew  2067: Show and set course data and parameters.  This is a large routine that should
1.59      matthew  2068: be simplified and shortened... someday.
                   2069: 
                   2070: Inputs: $r
                   2071: 
                   2072: Returns: nothing
                   2073: 
                   2074: =cut
                   2075: 
                   2076: ##################################################
                   2077: ##################################################
1.30      www      2078: sub crsenv {
                   2079:     my $r=shift;
                   2080:     my $setoutput='';
1.280     albertel 2081: 
1.298     albertel 2082:     my $breadcrumbs = 
                   2083: 	&Apache::lonhtmlcommon::breadcrumbs('Edit Course Environment');
1.190     albertel 2084:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   2085:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.105     matthew  2086: 
1.392     raeburn  2087:     my (%crsinfo,$chome);
                   2088: 
1.105     matthew  2089:     #
                   2090:     # Go through list of changes
1.190     albertel 2091:     foreach (keys %env) {
1.105     matthew  2092:         next if ($_!~/^form\.(.+)\_setparmval$/);
                   2093:         my $name  = $1;
1.190     albertel 2094:         my $value = $env{'form.'.$name.'_value'};
1.105     matthew  2095:         if ($name eq 'newp') {
1.190     albertel 2096:             $name = $env{'form.newp_name'};
1.105     matthew  2097:         }
                   2098:         if ($name eq 'url') {
                   2099:             $value=~s/^\/res\///;
                   2100:             my $bkuptime=time;
                   2101:             my @tmp = &Apache::lonnet::get
                   2102:                 ('environment',['url'],$dom,$crs);
1.130     www      2103:             $setoutput.=&mt('Backing up previous URL').': '.
1.105     matthew  2104:                 &Apache::lonnet::put
                   2105:                 ('environment',
                   2106:                  {'top level map backup '.$bkuptime => $tmp[1] },
                   2107:                  $dom,$crs).
1.336     albertel 2108:                      '<br />';
1.105     matthew  2109:         }
                   2110:         #
                   2111:         # Deal with modified default spreadsheets
                   2112:         if ($name =~ /^spreadsheet_default_(classcalc|
                   2113:                                             studentcalc|
                   2114:                                             assesscalc)$/x) {
                   2115:             my $sheettype = $1; 
                   2116:             if ($sheettype eq 'classcalc') {
                   2117:                 # no need to do anything since viewing the sheet will
                   2118:                 # cause it to be updated. 
                   2119:             } elsif ($sheettype eq 'studentcalc') {
                   2120:                 # expire all the student spreadsheets
                   2121:                 &Apache::lonnet::expirespread('','','studentcalc');
                   2122:             } else {
                   2123:                 # expire all the assessment spreadsheets 
                   2124:                 #    this includes non-default spreadsheets, but better to
                   2125:                 #    be safe than sorry.
                   2126:                 &Apache::lonnet::expirespread('','','assesscalc');
                   2127:                 # expire all the student spreadsheets
                   2128:                 &Apache::lonnet::expirespread('','','studentcalc');
1.30      www      2129:             }
1.105     matthew  2130:         }
                   2131:         #
1.107     matthew  2132:         # Deal with the enrollment dates
                   2133:         if ($name =~ /^default_enrollment_(start|end)_date$/) {
                   2134:             $value=&Apache::lonhtmlcommon::get_date_from_form($name.'_value');
                   2135:         }
1.364     albertel 2136: 	#
                   2137:         # Deal with the emails
                   2138:         if ($name =~ /\.email$/) {
1.371     albertel 2139: 	    foreach my $specifier (split(',',$value)) {
                   2140: 		my ($user,$sections_or_groups)=
                   2141: 		    ($specifier=~/^([^\(]+)\(([^\)]+)\)/);
                   2142: 		if (!$sections_or_groups) {
                   2143: 		    $user = $specifier;
                   2144: 		}
                   2145: 		my ($name,$domain) = split(':',$user);
                   2146: 		if (!defined($user) || !defined($domain)) {
                   2147: 		    $setoutput.= '<br /> <span class="LC_error">'.
                   2148: 			&mt("Invalid email address specified, address must be of the form username:domain what was specified was ([_1])",$user).
                   2149: 			'</span>';
                   2150: 		    undef($value);
                   2151: 		} elsif (&Apache::lonnet::homeserver($user,$domain) eq 'no_host') {
                   2152: 		    $setoutput.= '<br /> <span class="LC_error">'.
                   2153: 			&mt("Invalid email address specified, user [_1] is unknown.",$name).
                   2154: 			'</span>';
                   2155: 		    undef($value);
                   2156: 		}
1.364     albertel 2157: 	    }
                   2158:         }
1.178     raeburn  2159:         # Get existing cloners
                   2160:         my @oldcloner = ();
                   2161:         if ($name eq 'cloners') {
                   2162:             my %clonenames=&Apache::lonnet::dump('environment',$dom,$crs,'cloners');
                   2163:             if ($clonenames{'cloners'} =~ /,/) {
                   2164:                 @oldcloner = split/,/,$clonenames{'cloners'};
                   2165:             } else {
                   2166:                 $oldcloner[0] = $clonenames{'cloners'};
                   2167:             }
                   2168:         }
1.107     matthew  2169:         #
1.105     matthew  2170:         # Let the user know we made the changes
1.153     albertel 2171:         if ($name && defined($value)) {
1.379     raeburn  2172:             my %failed_cloners;
1.178     raeburn  2173:             if ($name eq 'cloners') {
1.239     raeburn  2174:                 $value =~ s/\s//g;
1.178     raeburn  2175:                 $value =~ s/^,//;
                   2176:                 $value =~ s/,$//;
1.239     raeburn  2177:                 # check requested clones are valid users.
1.379     raeburn  2178:                 %failed_cloners = &check_cloners(\$value,\@oldcloner);
1.178     raeburn  2179:             }
1.105     matthew  2180:             my $put_result = &Apache::lonnet::put('environment',
                   2181:                                                   {$name=>$value},$dom,$crs);
                   2182:             if ($put_result eq 'ok') {
1.392     raeburn  2183:                 $setoutput.=&mt('Set').' <b>'.$name.'</b> '.&mt('to').' <b>';
                   2184:                 if ($name =~ /^default_enrollment_(start|end)_date$/) {
                   2185:                     $setoutput .= &Apache::lonlocal::locallocaltime($value);
1.406     raeburn  2186:                 } elsif ($name eq 'categories') {
                   2187:                     $setoutput .= $env{'form.categories_display'};
1.392     raeburn  2188:                 } else {
                   2189:                     $setoutput .= $value;
                   2190:                 }
                   2191:                 $setoutput .= '</b>.<br />';
1.178     raeburn  2192:                 if ($name eq 'cloners') {
                   2193:                     &change_clone($value,\@oldcloner);
                   2194:                 }
1.382     raeburn  2195:                 # Update environment and nohist_courseids.db
1.402     raeburn  2196:                 if (($name eq 'description') || ($name eq 'cloners') || 
1.403     raeburn  2197:                     ($name eq 'hidefromcat') || ($name eq 'categories')) {
1.392     raeburn  2198:                     if ($chome eq '') {
                   2199:                         %crsinfo =
                   2200:                             &Apache::lonnet::courseiddump($dom,'.',1,'.','.',
1.403     raeburn  2201:                                                  $crs,undef,undef,'.');
1.392     raeburn  2202:                         $chome = &Apache::lonnet::homeserver($crs,$dom);
                   2203:                     }
                   2204:                 }
1.179     raeburn  2205:                 if ($name eq 'description' && defined($value)) {
1.393     raeburn  2206:                     &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.description' => $value});
1.382     raeburn  2207:                     if (ref($crsinfo{$env{'request.course.id'}}) eq 'HASH') {
                   2208:                         $crsinfo{$env{'request.course.id'}}{'description'} = $value; 
1.392     raeburn  2209:                         my $putresult =
                   2210:                             &Apache::lonnet::courseidput($dom,\%crsinfo,
                   2211:                                                          $chome,'notime');
                   2212:                     }
                   2213:                 }
1.403     raeburn  2214:                 if (($name eq 'cloners') || ($name eq 'hidefromcat') || ($name eq 'categories')) {
1.402     raeburn  2215:                     if (ref($crsinfo{$env{'request.course.id'}}) eq 'HASH') {
1.403     raeburn  2216:                         &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.'.$name => $value});
                   2217:                         $crsinfo{$env{'request.course.id'}}{$name} = $value;
1.402     raeburn  2218:                         my $putresult =
                   2219:                             &Apache::lonnet::courseidput($dom,\%crsinfo,
                   2220:                                                          $chome,'notime');
                   2221:                     }
                   2222:                 }
1.105     matthew  2223:             } else {
1.130     www      2224:                 $setoutput.=&mt('Unable to set').' <b>'.$name.'</b> '.&mt('to').
                   2225: 		    ' <b>'.$value.'</b> '.&mt('due to').' '.$put_result.'.<br />';
1.30      www      2226:             }
1.379     raeburn  2227:             if (($name eq 'cloners') && (keys(%failed_cloners) > 0)) {
                   2228:                 $setoutput.= &mt('Unable to include').': ';
                   2229:                 my @fails;
                   2230:                 my $num = 0;
                   2231:                 if (defined($failed_cloners{'format'})) {
                   2232:                     $fails[$num] .= '<b>'.$failed_cloners{'format'}.
                   2233:                                   '</b>, '.&mt('reason').' - '.
                   2234:                                   &mt('Invalid format');
                   2235:                     $num ++;
                   2236:                 }
                   2237:                 if (defined($failed_cloners{'domain'})) {
                   2238:                     $fails[$num] .= '<b>'.$failed_cloners{'domain'}.
                   2239:                                   '</b>, '.&mt('reason').' - '.
                   2240:                                   &mt('Domain does not exist');
                   2241:                     $num ++;
                   2242:                 }
                   2243:                 if (defined($failed_cloners{'newuser'})) {
                   2244:                     $fails[$num] .= '<b>'.$failed_cloners{'newuser'}.                                   '</b>, '.&mt('reason').' - '.
                   2245:                         &mt('LON-CAPA user(s) do(es) not exist.').
                   2246:                         '.<br />'.&mt('Please ').
                   2247:                         ' <a href="/adm/createuser">'.
                   2248:                         &mt('add the user(s)').'</a>, '.
                   2249:                         &mt('and then return to the ').
                   2250:                         '<a href="/adm/parmset?action=crsenv">'.
                   2251:                         &mt('Course Parameters page').'</a> '.
                   2252:                         &mt('to add the new user(s) to the list of possible cloners');
                   2253:                 }
                   2254:                 $setoutput .= join(';&nbsp;&nbsp;',@fails).'.<br />';
1.239     raeburn  2255:             }
1.30      www      2256:         }
1.38      harris41 2257:     }
1.315     albertel 2258: 
                   2259:     my $start_table     =&Apache::loncommon::start_data_table();
                   2260:     my $start_header_row=&Apache::loncommon::start_data_table_header_row();
                   2261:     my $end_header_row  =&Apache::loncommon::end_data_table_header_row();
1.108     www      2262: # ------------------------- Re-init course environment entries for this session
                   2263: 
1.302     albertel 2264:     &Apache::lonnet::coursedescription($env{'request.course.id'},
1.296     albertel 2265: 				       {'freshen_cache' => 1});
1.105     matthew  2266: 
1.30      www      2267: # -------------------------------------------------------- Get parameters again
1.45      matthew  2268: 
                   2269:     my %values=&Apache::lonnet::dump('environment',$dom,$crs);
1.140     sakharuk 2270:     my $SelectStyleFile=&mt('Select Style File');
1.141     sakharuk 2271:     my $SelectSpreadsheetFile=&mt('Select Spreadsheet File');
1.30      www      2272:     my $output='';
1.403     raeburn  2273:     my $can_categorize;
1.45      matthew  2274:     if (! exists($values{'con_lost'})) {
1.30      www      2275:         my %descriptions=
1.395     bisitz   2276: 	    ('url'            => '<b>'.&mt('Top Level Map').'</b><br />'.
1.46      matthew  2277:                                  '<a href="javascript:openbrowser'.
1.47      matthew  2278:                                  "('envform','url','sequence')\">".
1.314     albertel 2279:                                  &mt('Select Map').'</a><br /><span class="LC_warning"> '.
1.395     bisitz   2280:                                  &mt('Modification may make assessment data inaccessible!').
1.314     albertel 2281:                                  '</span>',
1.140     sakharuk 2282:              'description'    => '<b>'.&mt('Course Description').'</b>',
1.158     sakharuk 2283:              'courseid'       => '<b>'.&mt('Course ID or number').
1.140     sakharuk 2284:                                  '</b><br />'.
1.395     bisitz   2285:                                  '('.&mt('internal, optional').')',
                   2286:              'cloners'        => '<b>'.&mt('Users allowed to clone course').'</b><br />'
                   2287:                                 .'("<tt>'.&mt('user:domain,user:domain,*:domain').'</tt>")<br />'
                   2288:                                 .&mt('Users with active Course Coordinator role in this course are permitted to clone and need not be included.').'<br />'
                   2289:                                 .&mt('Use [_1] to allow course to be cloned by anyone in the specified domain.','"<tt>*:domain</tt>"').'<br />'
                   2290:                                 .&mt('Use [_1] to allow unrestricted cloning in all domains.','"<tt>*</tt>"'),
1.150     www      2291:              'grading'        => '<b>'.&mt('Grading').'</b><br />'.
1.395     bisitz   2292:                                  &mt('[_1], [_2], or [_3]','"<tt>standard</tt>"','"<tt>external</tt>"','"<tt>spreadsheet</tt>"').&Apache::loncommon::help_open_topic('GradingOptions'),
                   2293: 	     'task_grading'   => '<b>'.&mt('Bridge Task Grading').'</b><br />'
                   2294:                                 .&mt('Instructors and TAs in sections, when grading bridge tasks, should be allowed to grade other sections.').'<br />'
                   2295:                                 .'('.&mt('[_1]: they are allowed (this is the default). [_2]: no, they can only grade their own section.','"<tt>any</tt>"','"<tt>section</tt>"').')',
                   2296:              'default_xml_style' => '<b>'.&mt('Default XML Style File').'</b><br />'.
1.52      www      2297:                     '<a href="javascript:openbrowser'.
                   2298:                     "('envform','default_xml_style'".
1.336     albertel 2299:                     ",'sty')\">$SelectStyleFile</a><br />",
1.395     bisitz   2300:              'question.email' => '<b>'.&mt('Feedback Addresses for Resource Content Question').'</b><br />'
                   2301:                                 .'("<tt>'.&mt('user:domain,user:domain(section;section;...;*;...),...').'</tt>")',
                   2302:              'question.email.text' => '<b>'.&mt('Custom Text for Resource Content Question Option in Feedback').'</b>',
                   2303:              'comment.email'  => '<b>'.&mt('Feedback Addresses for Course Content Comments').'</b><br />'
                   2304:                                 .'("<tt>'.&mt('user:domain,user:domain(section;section;...;*;...),...').'</tt>")',
                   2305:              'comment.email.text' => '<b>'.&mt('Custom Text for Course Content Option in Feedback').'</b>',
                   2306:              'policy.email'   => '<b>'.&mt('Feedback Addresses for Course Policy').'</b><br />'
                   2307:                                  .'("<tt>'.&mt('user:domain,user:domain(section;section;...;*;...),...').'</tt>")',
                   2308:              'policy.email.text' => '<b>'.&mt('Custom Text for Course Policy Option in Feedback').'</b>',
                   2309:              'hideemptyrows'  => '<b>'.&mt('Hide Empty Rows in Spreadsheets').'</b><br />'
                   2310:                                 .'('.&mt('[_1] for default hiding','"<tt>yes</tt>"').')',
                   2311:              'pageseparators'  => '<b>'.&mt('Visibly Separate Items on Pages').'</b><br />'
                   2312:                                  .'('.&mt('[_1] for visible separation.','"<tt>yes</tt>"').' '
                   2313:                                  .&mt('Changes will not show until next login.').')',
                   2314:              'student_classlist_view' => '<b>'.&mt('Allow students to view classlist.').'</b><br />'
                   2315:                                         .'('.&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>"').')',
                   2316:              'student_classlist_portfiles' => '<b>'.&mt('Include link to accessible portfolio files').'</b><br />'
                   2317:                                              .'('.&mt('[_1] for link to each a listing of each student\'s files.','"<tt>yes</tt>"').')',
                   2318:              'student_classlist_opt_in' => '<b>'.&mt("Student's agreement needed for listing in student-viewable roster").'</b><br />'
                   2319:                                            .'('.&mt('[_1] to require students to opt-in to listing in the roster (on the roster page).','"<tt>yes</tt>"').')',
                   2320:              'plc.roles.denied'=> '<b>'.&mt('Disallow live chatroom use for Roles').'</b><br />'
                   2321:                                  .'('.&mt('[_1]: student, [_2]: TA, [_3]: instructor','"<tt>st</tt>"','"<tt>ta</tt>"','"<tt>in</tt>"').')<br />'
                   2322:                                  .'("<tt>'.&mt('role,role,...').'</tt>") '
                   2323: 	                         .Apache::loncommon::help_open_topic("Course_Disable_Discussion"),
1.118     matthew  2324:              'plc.users.denied' => 
1.141     sakharuk 2325:                           '<b>'.&mt('Disallow live chatroom use for Users').'</b><br />'.
1.395     bisitz   2326:                                   '("<tt>'.&mt('user:domain,user:domain,...').'</tt>")',
1.118     matthew  2327: 
1.395     bisitz   2328:              'pch.roles.denied'=> '<b>'.&mt('Disallow Resource Discussion for Roles').'</b><br />'
                   2329:                                  .'('.&mt('[_1]: student, [_2]: TA, [_3]: instructor','"<tt>st</tt>"','"<tt>ta</tt>"','"<tt>in</tt>"')
                   2330:                                  .'("<tt>'.&mt('role,role,...').'</tt>") '
                   2331:                                  .Apache::loncommon::help_open_topic("Course_Disable_Discussion"),
1.53      www      2332:              'pch.users.denied' => 
1.141     sakharuk 2333:                           '<b>'.&mt('Disallow Resource Discussion for Users').'</b><br />'.
1.395     bisitz   2334:                                  '("<tt>'.&mt('user:domain,user:domain,...').'</tt>")',
1.49      matthew  2335:              'spreadsheet_default_classcalc' 
1.141     sakharuk 2336:                  => '<b>'.&mt('Default Course Spreadsheet').'</b> '.
1.50      matthew  2337:                     '<a href="javascript:openbrowser'.
                   2338:                     "('envform','spreadsheet_default_classcalc'".
1.141     sakharuk 2339:                     ",'spreadsheet')\">$SelectSpreadsheetFile</a><br />",
1.49      matthew  2340:              'spreadsheet_default_studentcalc' 
1.395     bisitz   2341:                  => '<b>'.&mt('Default Student Spreadsheet').'</b><br />'.
1.50      matthew  2342:                     '<a href="javascript:openbrowser'.
                   2343:                     "('envform','spreadsheet_default_calc'".
1.141     sakharuk 2344:                     ",'spreadsheet')\">$SelectSpreadsheetFile</a><br />",
1.49      matthew  2345:              'spreadsheet_default_assesscalc' 
1.141     sakharuk 2346:                  => '<b>'.&mt('Default Assessment Spreadsheet').'</b> '.
1.50      matthew  2347:                     '<a href="javascript:openbrowser'.
                   2348:                     "('envform','spreadsheet_default_assesscalc'".
1.141     sakharuk 2349:                     ",'spreadsheet')\">$SelectSpreadsheetFile</a><br />",
1.75      albertel 2350: 	     'allow_limited_html_in_feedback'
1.141     sakharuk 2351: 	         => '<b>'.&mt('Allow limited HTML in discussion posts').'</b><br />'.
1.395     bisitz   2352: 	            '('.&mt('Set value to [_1] to allow.','"<tt>yes</tt>"').')',
1.170     raeburn  2353:              'allow_discussion_post_editing'
1.395     bisitz   2354:                  => '<b>'.&mt('Allow users with specified roles to edit/delete their own discussion posts').'</b><br />'
                   2355:                    .'('.&mt('[_1]: student, [_2]: TA, [_3]: instructor','"<tt>st</tt>"','"<tt>ta</tt>"','"<tt>in</tt>"').')<br />'
                   2356:                    .'('.&mt('Set value to [_1] to allow all roles.','"<tt>yes</tt>"').')'
                   2357:                    .'("<tt>'.&mt('role:section,role:section,...').'</tt>")<br />'
                   2358:                    .'('.&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.').')',
1.89      albertel 2359: 	     'rndseed'
1.395     bisitz   2360: 	         => '<b>'.&mt('Randomization algorithm used').'</b><br />'
                   2361:                    .'<span class="LC_error">'
                   2362:                    .&mt('Modifying this will make problems have different numbers and answers!')
                   2363:                    .'</span>',
1.151     albertel 2364: 	     'receiptalg'
                   2365: 	         => '<b>'.&mt('Receipt algorithm used').'</b> <br />'.
                   2366:                     &mt('This controls how receipt numbers are generated.'),
1.164     sakharuk 2367:              'suppress_tries'
1.272     albertel 2368:                  => '<b>'.&mt('Suppress number of tries in printing').'</b><br />'.
1.395     bisitz   2369:                     ' ('.&mt('[_1] to suppress, anything else to not suppress','"<tt>yes</tt>"').')',
1.113     sakharuk 2370:              'problem_stream_switch'
1.141     sakharuk 2371:                  => '<b>'.&mt('Allow problems to be split over pages').'</b><br />'.
1.395     bisitz   2372:                     ' ('.&mt('[_1] if allowed, anything else if not','"<tt>yes</tt>"').')',
1.161     sakharuk 2373:              'default_paper_size' 
                   2374:                  => '<b>'.&mt('Default paper type').'</b><br />'.
                   2375:                     ' ('.&mt('supported types').': Letter [8 1/2x11 in], Legal [8 1/2x14 in],'. 
                   2376:                     ' Tabloid [11x17 in], Executive [7 1/2x10 in], A2 [420x594 mm],'. 
                   2377:                     ' A3 [297x420 mm], A4 [210x297 mm], A5 [148x210 mm], A6 [105x148 mm])',
1.319     foxr     2378: 	     'print_header_format'
1.395     bisitz   2379: 	         => ' <b>'.&mt('Print header format').'</b><br />'
                   2380:                    .&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>"'),
1.217     albertel 2381:              'default_enrollment_start_date' => '<b>'.&mt('Default beginning date for student access.').'</b>',
                   2382:              'default_enrollment_end_date'   => '<b>'.&mt('Default ending date for student access.').'</b>',
1.395     bisitz   2383:              'nothideprivileged'   => '<b>'.&mt('Privileged users that should not be hidden on staff listings').'</b><br />'
                   2384:                                      .'("<tt>'.&mt('user:domain,user:domain,*:domain').'</tt>")',
1.140     sakharuk 2385:              'languages' => '<b>'.&mt('Languages used').'</b>',
1.115     www      2386:              'disable_receipt_display'
1.141     sakharuk 2387:                  => '<b>'.&mt('Disable display of problem receipts').'</b><br />'.
1.158     sakharuk 2388:                     ' ('.&mt('"[_1]" to disable, anything else if not','<tt>yes</tt>').')',
1.313     albertel 2389: 	     'task_messages'
1.395     bisitz   2390: 	         => '<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>"').')',
1.163     albertel 2391: 	     'disablesigfigs'
                   2392: 	         => '<b>'.&mt('Disable checking of Significant Figures').'</b><br />'.
                   2393:                     ' ('.&mt('"[_1]" to disable, anything else if not','<tt>yes</tt>').')',
1.251     albertel 2394: 	     'disableexampointprint'
                   2395: 	         => '<b>'.&mt('Disable automatically printing point values onto exams.').'</b><br />'.
                   2396:                     ' ('.&mt('"[_1]" to disable, anything else if not','<tt>yes</tt>').')',
1.278     www      2397:              'externalsyllabus'
1.279     www      2398:                  => '<b>'.&mt('URL of Syllabus (not using internal handler)').'</b>',
1.149     albertel 2399: 	     'tthoptions'
1.367     albertel 2400: 	         => '<b>'.&mt('Default set of options to pass to tth/m when converting tex').'</b>',
                   2401: 
                   2402: 	     'texengine'
1.395     bisitz   2403: 	         => '<b>'.&mt('Force all students in the course to use a specific math rendering engine.').'</b><br />'
1.396     bisitz   2404:                    .'('.&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>"').')',
1.397     www      2405:              'timezone'
1.400     raeburn  2406:                  => '<b>'.&mt('Timezone in which the course takes place').'</b>',
1.392     raeburn  2407: 
1.400     raeburn  2408:              'suppress_embed_prompt'
                   2409:                  => '<b>'.&mt('Suppress prompt to upload items referenced in a web page being uploaded to portfolio, when current role is student.').'</b><br />'.
1.402     raeburn  2410:                     ' ('.&mt('[_1] to suppress, anything else to not suppress','"<tt>yes</tt>"').')',
1.403     raeburn  2411:              'hidefromcat'
1.402     raeburn  2412:                  => '<b>'.&mt('Exclude from course catalog').'</b><br />'.
                   2413:                     ' ('.&mt('[_1] to exclude, anything else to include - included if assigned an institutional code, or manually catagorized','"<tt>yes</tt>"').')',
1.403     raeburn  2414:              'categories'
                   2415:                  => '<b>'.&mt('Categorize course').'</b> <a href="javascript:catsbrowser()">'.
                   2416:                     &mt('Display Categories').'</a>',
1.409     raeburn  2417:              'datelocale' 
                   2418:                  => '<b>'.&mt('Locale used for course calendar').'</b>',
1.402     raeburn  2419:              );
                   2420:         my @Display_Order = ('url','description','courseid','cloners');
1.403     raeburn  2421:         (my $can_toggle_cat,$can_categorize) = &can_modify_catsettings($dom);
                   2422:         if ($can_toggle_cat) {
1.402     raeburn  2423:             push(@Display_Order,'hidefromcat');
                   2424:         }
1.403     raeburn  2425:         if ($can_categorize) {
                   2426:             push(@Display_Order,'categories');
                   2427:         }
1.402     raeburn  2428:         push (@Display_Order,('grading',
1.278     www      2429:                              'externalsyllabus',
1.107     matthew  2430:                              'default_xml_style','pageseparators',
1.402     raeburn  2431:                              'question.email','question.email.text','comment.email',
                   2432:                              'comment.email.text','policy.email','policy.email.text',
1.169     matthew  2433:                              'student_classlist_view',
1.372     raeburn  2434:                              'student_classlist_opt_in',
                   2435:                              'student_classlist_portfiles',
1.118     matthew  2436:                              'plc.roles.denied','plc.users.denied',
1.107     matthew  2437:                              'pch.roles.denied','pch.users.denied',
                   2438:                              'allow_limited_html_in_feedback',
1.170     raeburn  2439:                              'allow_discussion_post_editing',
1.108     www      2440:                              'languages',
1.397     www      2441:                              'timezone',
1.409     raeburn  2442:                              'datelocale',
1.150     www      2443: 			     'nothideprivileged',
1.107     matthew  2444:                              'rndseed',
1.151     albertel 2445:                              'receiptalg',
1.107     matthew  2446:                              'problem_stream_switch',
1.164     sakharuk 2447: 			     'suppress_tries',
1.400     raeburn  2448:                              'suppress_embed_prompt',
1.161     sakharuk 2449:                              'default_paper_size',
1.319     foxr     2450: 			     'print_header_format',
1.115     www      2451:                              'disable_receipt_display',
1.107     matthew  2452:                              'spreadsheet_default_classcalc',
                   2453:                              'spreadsheet_default_studentcalc',
                   2454:                              'spreadsheet_default_assesscalc', 
                   2455:                              'hideemptyrows',
                   2456:                              'default_enrollment_start_date',
                   2457:                              'default_enrollment_end_date',
1.163     albertel 2458: 			     'tthoptions',
1.367     albertel 2459: 			     'texengine',
1.251     albertel 2460: 			     'disablesigfigs',
1.313     albertel 2461: 			     'disableexampointprint',
1.402     raeburn  2462: 			     'task_messages','task_grading'));
1.107     matthew  2463: 	foreach my $parameter (sort(keys(%values))) {
1.405     raeburn  2464:             unless (($parameter =~ m/^internal\./)||($parameter =~ m/^metadata\./) ||
                   2465:                     ($parameter =~ m/^selfenroll_/) || ($parameter =~ /_selfenroll$/)
                   2466:                     || ($parameter eq 'type')) {
1.142     raeburn  2467:                 if (! $descriptions{$parameter}) {
                   2468:                     $descriptions{$parameter}=$parameter;
                   2469:                     push(@Display_Order,$parameter);
                   2470:                 }
                   2471:             }
1.43      albertel 2472: 	}
1.315     albertel 2473: 	
1.107     matthew  2474:         foreach my $parameter (@Display_Order) {
                   2475:             my $description = $descriptions{$parameter};
1.51      matthew  2476:             # onchange is javascript to automatically check the 'Set' button.
1.69      www      2477:             my $onchange = 'onFocus="javascript:window.document.forms'.
1.107     matthew  2478:                 "['envform'].elements['".$parameter."_setparmval']".
1.51      matthew  2479:                 '.checked=true;"';
1.315     albertel 2480:             $output .= &Apache::loncommon::start_data_table_row().
                   2481: 		'<td>'.$description.'</td>';
1.107     matthew  2482:             if ($parameter =~ /^default_enrollment_(start|end)_date$/) {
                   2483:                 $output .= '<td>'.
                   2484:                     &Apache::lonhtmlcommon::date_setter('envform',
                   2485:                                                         $parameter.'_value',
                   2486:                                                         $values{$parameter},
                   2487:                                                         $onchange).
                   2488:                                                         '</td>';
1.398     www      2489:             } elsif ($parameter eq 'timezone') {
1.399     raeburn  2490:                 my $includeempty = 1;
                   2491:                 my $timezone = &Apache::lonlocal::gettimezone();
1.398     www      2492:                 $output .= '<td>'.
                   2493:                     &Apache::loncommon::select_timezone($parameter.'_value',
1.399     raeburn  2494:                                                         $timezone,
                   2495:                                                         $onchange,$includeempty).'</td>';
1.409     raeburn  2496:             } elsif ($parameter eq 'datelocale') {
                   2497:                 my $includeempty = 1;
                   2498:                 my $locale_obj = &Apache::lonlocal::getdatelocale();
                   2499:                 my $currdatelocale;
                   2500:                 if (ref($locale_obj)) {
                   2501:                     $currdatelocale = $locale_obj->id();
                   2502:                 }
                   2503:                 $output .= '<td>'.
                   2504:                     &Apache::loncommon::select_datelocale($parameter.'_value',
                   2505:                                                           $currdatelocale,
                   2506:                                                           $onchange,$includeempty).'</td>'; 
1.406     raeburn  2507:             } elsif ($parameter eq 'categories') {
                   2508:                 my $catdisplay;
                   2509:                 if ($values{'categories'} ne '') {
                   2510:                     my @curritems = split(/\&/,$values{'categories'});
                   2511:                     foreach my $item (@curritems) {
                   2512:                         my ($name,$parent,$pos) = split(/:/,$item);
                   2513:                         $catdisplay .= &unescape($name).'&';
                   2514:                     }
                   2515:                     $catdisplay =~ s/\&$//;
                   2516:                 } 
                   2517:                 $output .= '<td>'.
                   2518:                            '<input type="hidden" name="categories_value" value="'.
                   2519:                            $values{'categories'}.'" />'.
                   2520:                            '<input type="textbox" name="categories_display" value="'.
                   2521:                            $catdisplay.'" readonly="readonly" size="40" /></td>';
1.107     matthew  2522:             } else {
                   2523:                 $output .= '<td>'.
                   2524:                     &Apache::lonhtmlcommon::textbox($parameter.'_value',
                   2525:                                                     $values{$parameter},
                   2526:                                                     40,$onchange).'</td>';
                   2527:             }
                   2528:             $output .= '<td>'.
                   2529:                 &Apache::lonhtmlcommon::checkbox($parameter.'_setparmval').
                   2530:                 '</td>';
1.315     albertel 2531:             $output .= &Apache::loncommon::end_data_table_row()."\n";
1.51      matthew  2532: 	}
1.69      www      2533:         my $onchange = 'onFocus="javascript:window.document.forms'.
1.51      matthew  2534:             '[\'envform\'].elements[\'newp_setparmval\']'.
                   2535:             '.checked=true;"';
1.315     albertel 2536: 	$output.=&Apache::loncommon::start_data_table_row().
                   2537: 	    '<td><i>'.&mt('Create New Environment Variable').'</i><br />'.
1.51      matthew  2538: 	    '<input type="text" size=40 name="newp_name" '.
                   2539:                 $onchange.' /></td><td>'.
                   2540:             '<input type="text" size=40 name="newp_value" '.
                   2541:                 $onchange.' /></td><td>'.
1.315     albertel 2542: 	    '<input type="checkbox" name="newp_setparmval" /></td>'.
                   2543: 	    &Apache::loncommon::end_data_table_row()."\n";
1.43      albertel 2544:     }
1.157     sakharuk 2545:     my %lt=&Apache::lonlocal::texthash(
                   2546: 		    'par'   => 'Parameter',
                   2547: 		    'val'   => 'Value',
1.395     bisitz   2548: 		    'set'   => 'Set?',
                   2549: 		    'sav'   => 'Save'
1.157     sakharuk 2550: 				       );
                   2551: 
1.140     sakharuk 2552:     my $Parameter=&mt('Parameter');
                   2553:     my $Value=&mt('Value');
1.141     sakharuk 2554:     my $Set=&mt('Set');
1.403     raeburn  2555:     my ($jscript,$categorize_js);
                   2556:     my $browse_js = &Apache::loncommon::browser_and_searcher_javascript('parmset');
                   2557:     if ($can_categorize) {
                   2558:         $categorize_js = <<ENDSCRIPT;
                   2559: function catsbrowser() {
                   2560:     var catswin = null;
                   2561:     var url = '/adm/parmset?action=categorizecourse';
                   2562:     if (!catswin || catswin.closed) {
                   2563:         catswin=window.open(url,'categorieswin','height=480,width=600,resizable=yes,scrollbars=yes,location=no,menubar=no,toolbar=no');
                   2564:     } else {
                   2565:         catswin.focus();
                   2566:     }
                   2567: } 
                   2568: ENDSCRIPT
                   2569:     }
                   2570:     $jscript = '<script type="text/javascript" language="Javascript">'."\n".
                   2571:                $browse_js."\n".$categorize_js."\n".'</script>';
1.280     albertel 2572:     my $start_page = 
1.323     albertel 2573: 	&Apache::loncommon::start_page('Set Course Environment',
1.403     raeburn  2574: 				       $jscript);
1.280     albertel 2575:     my $end_page = 
                   2576: 	&Apache::loncommon::end_page();
1.315     albertel 2577:     my $end_table=&Apache::loncommon::end_data_table();
1.280     albertel 2578:     $r->print(<<ENDENV);
                   2579: $start_page
1.193     albertel 2580: $breadcrumbs
                   2581: <form method="post" action="/adm/parmset?action=crsenv" name="envform">
1.30      www      2582: $setoutput
1.395     bisitz   2583: <div><input type="submit" name="crsenv" value="$lt{'sav'}" /></div>
1.315     albertel 2584: $start_table
                   2585: $start_header_row
1.395     bisitz   2586: <th>$lt{'par'}</th><th>$lt{'val'}</th><th>$lt{'set'}</th>
1.315     albertel 2587: $end_header_row
1.30      www      2588: $output
1.315     albertel 2589: $end_table
1.395     bisitz   2590: <input type="submit" name="crsenv" value="$lt{'sav'}" />
1.30      www      2591: </form>
1.280     albertel 2592: $end_page
                   2593: ENDENV
1.30      www      2594: }
1.402     raeburn  2595: 
1.403     raeburn  2596: sub can_modify_catsettings {
1.402     raeburn  2597:     my ($dom) = @_;
                   2598:     my %domconf = &Apache::lonnet::get_dom('configuration',['coursecategories'],$dom);
1.403     raeburn  2599:     my ($can_toggle_cat,$can_categorize);
1.402     raeburn  2600:     if (ref($domconf{'coursecategories'}) eq 'HASH') {
                   2601:         if ($domconf{'coursecategories'}{'togglecats'} eq 'crs') {
                   2602:             $can_toggle_cat = 1;
                   2603:         }
1.403     raeburn  2604:         if ($domconf{'coursecategories'}{'categorize'} eq 'crs') {
                   2605:             $can_categorize = 1;
                   2606:         }
                   2607:     }
                   2608:     return ($can_toggle_cat,$can_categorize);
                   2609: }
                   2610: 
                   2611: sub assign_course_categories {
                   2612:     my ($r) = @_;
                   2613:     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   2614:     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                   2615:     my $hascats = 0;
                   2616:     my $cathash;
                   2617:     my %domconf = &Apache::lonnet::get_dom('configuration',['coursecategories'],$cdom);
                   2618:     if (ref($domconf{'coursecategories'}) eq 'HASH') {
                   2619:         $cathash = $domconf{'coursecategories'}{'cats'};
                   2620:         if (ref($cathash) eq 'HASH') {
                   2621:             $hascats = 1;   
                   2622:         }
1.402     raeburn  2623:     }
1.403     raeburn  2624:     my $catwin_js;
                   2625:     if ($hascats) {
                   2626:         my $alert = &mt('Use \"Save\" in the main window to save course categories');
                   2627:         $catwin_js = <<ENDSCRIPT;
                   2628: <script type="text/javascript">
                   2629: 
                   2630: function updateCategories() {
                   2631:     var newcategories = '';
1.406     raeburn  2632:     var unescapedcats = '';
1.403     raeburn  2633:     if (document.chgcats.usecategory.length) {
                   2634:         for (var i=0; i<document.chgcats.usecategory.length; i++) {
                   2635:             if (document.chgcats.usecategory[i].checked == true) {
                   2636:                 newcategories = newcategories + document.chgcats.usecategory[i].value + '&';
1.406     raeburn  2637:                 unescapedcats = unescapedcats + document.chgcats.catname[i].value + ' & ';
1.403     raeburn  2638:             }
                   2639:         }
                   2640:         if (newcategories.length > 0) {
                   2641:             newcategories = newcategories.slice(0,-1);
                   2642:         }
1.406     raeburn  2643:         if (unescapedcats.length > 0) {
1.408     raeburn  2644:             unescapedcats = unescapedcats.slice(0,-3);
1.406     raeburn  2645:         }
1.403     raeburn  2646:     } else {
                   2647:          if (document.chgcats.usecategory.checked == true) {
                   2648:              newcategories = document.chgcats.usecategory.value;
1.406     raeburn  2649:              unescapedcats = document.chgcats.catname.value;
1.403     raeburn  2650:          }
                   2651:     }
                   2652:     opener.document.envform.categories_value.value = newcategories;
1.406     raeburn  2653:     opener.document.envform.categories_display.value = unescapedcats;
1.403     raeburn  2654:     opener.document.envform.categories_setparmval.checked = true;
                   2655:     alert("$alert");
                   2656:     self.close();
                   2657:     return;
                   2658: }
                   2659: 
                   2660: </script>
                   2661: ENDSCRIPT
                   2662:     } else {
                   2663:         my $onload; 
                   2664:     }
                   2665:     my $start_page =
                   2666:         &Apache::loncommon::start_page('Course Categories',$catwin_js,
                   2667:                                        {'only_body'      => 1,});
                   2668:     my $end_page = &Apache::loncommon::end_page();
                   2669:     my $categoriesform = '<h3>'.&mt('Categorize Course').'</h3>';
                   2670:     if ($hascats) {
                   2671:         my %currsettings =
                   2672:             &Apache::lonnet::get('environment',['hidefromcat','categories'],$cdom,$cnum);
                   2673:         $categoriesform .= &mt('Assign one or more categories to this course.').'<br /><br />'.
                   2674:                                '<form name="chgcats" action="/adm/parmset" method="post">'."\n"
                   2675:                                .&Apache::loncommon::assign_categories_table($cathash,
                   2676:                                                        $currsettings{'categories'})."\n"
                   2677:                                .'<br /><input type="button" name="changes" value="'
                   2678:                                .&mt('Copy to main window').'" '
                   2679:                                .'onclick="javascript:updateCategories()" /></form><br />';
                   2680:     } else {
                   2681:         $categoriesform .= &mt('No categories defined for this domain');
                   2682:     }
                   2683:     $r->print($start_page.$categoriesform.$end_page);
                   2684:     return;
1.402     raeburn  2685: }
                   2686: 
1.120     www      2687: ##################################################
1.207     www      2688: # Overview mode
                   2689: ##################################################
1.124     www      2690: my $tableopen;
                   2691: 
                   2692: sub tablestart {
                   2693:     if ($tableopen) {
                   2694: 	return '';
                   2695:     } else {
                   2696: 	$tableopen=1;
1.295     albertel 2697: 	return &Apache::loncommon::start_data_table().'<tr><th>'.&mt('Parameter').'</th><th>'.
1.130     www      2698: 	    &mt('Delete').'</th><th>'.&mt('Set to ...').'</th></tr>';
1.124     www      2699:     }
                   2700: }
                   2701: 
                   2702: sub tableend {
                   2703:     if ($tableopen) {
                   2704: 	$tableopen=0;
1.295     albertel 2705: 	return &Apache::loncommon::end_data_table();
1.124     www      2706:     } else {
                   2707: 	return'';
                   2708:     }
                   2709: }
                   2710: 
1.207     www      2711: sub readdata {
                   2712:     my ($crs,$dom)=@_;
                   2713: # Read coursedata
                   2714:     my $resourcedata=&Apache::lonnet::get_courseresdata($crs,$dom);
                   2715: # Read userdata
                   2716: 
                   2717:     my $classlist=&Apache::loncoursedata::get_classlist();
                   2718:     foreach (keys %$classlist) {
1.350     albertel 2719:         if ($_=~/^($match_username)\:($match_domain)$/) {
1.207     www      2720: 	    my ($tuname,$tudom)=($1,$2);
                   2721: 	    my $useropt=&Apache::lonnet::get_userresdata($tuname,$tudom);
                   2722:             foreach my $userkey (keys %{$useropt}) {
                   2723: 		if ($userkey=~/^$env{'request.course.id'}/) {
                   2724:                     my $newkey=$userkey;
                   2725: 		    $newkey=~s/^($env{'request.course.id'}\.)/$1\[useropt\:$tuname\:$tudom\]\./;
                   2726: 		    $$resourcedata{$newkey}=$$useropt{$userkey};
                   2727: 		}
                   2728: 	    }
                   2729: 	}
                   2730:     }
                   2731:     return $resourcedata;
                   2732: }
                   2733: 
                   2734: 
1.124     www      2735: # Setting
1.208     www      2736: 
                   2737: sub storedata {
                   2738:     my ($r,$crs,$dom)=@_;
1.207     www      2739: # Set userlevel immediately
                   2740: # Do an intermediate store of course level
                   2741:     my $olddata=&readdata($crs,$dom);
1.124     www      2742:     my %newdata=();
                   2743:     undef %newdata;
                   2744:     my @deldata=();
                   2745:     undef @deldata;
1.190     albertel 2746:     foreach (keys %env) {
1.124     www      2747: 	if ($_=~/^form\.([a-z]+)\_(.+)$/) {
                   2748: 	    my $cmd=$1;
                   2749: 	    my $thiskey=$2;
1.207     www      2750: 	    my ($tuname,$tudom)=&extractuser($thiskey);
                   2751: 	    my $tkey=$thiskey;
                   2752:             if ($tuname) {
                   2753: 		$tkey=~s/\.\[useropt\:$tuname\:$tudom\]\./\./;
                   2754: 	    }
1.385     albertel 2755: 	    if ($cmd eq 'set' || $cmd eq 'datepointer' || $cmd eq 'dateinterval') {
1.384     albertel 2756: 		my ($data, $typeof, $text);
                   2757: 		if ($cmd eq 'set') {
                   2758: 		    $data=$env{$_};
                   2759: 		    $typeof=$env{'form.typeof_'.$thiskey};
                   2760: 		    $text = &mt('Saved modified parameter for');
                   2761: 		} elsif ($cmd eq 'datepointer') {
                   2762: 		    $data=&Apache::lonhtmlcommon::get_date_from_form($env{$_});
                   2763: 		    $typeof=$env{'form.typeof_'.$thiskey};
                   2764: 		    $text = &mt('Saved modified date for');
1.385     albertel 2765: 		} elsif ($cmd eq 'dateinterval') {
                   2766: 		    $data=&get_date_interval_from_form($thiskey);
                   2767: 		    $typeof=$env{'form.typeof_'.$thiskey};
                   2768: 		    $text = &mt('Saved modified date for');
1.384     albertel 2769: 		}
                   2770: 		if (defined($data) and $$olddata{$thiskey} ne $data) { 
1.207     www      2771: 		    if ($tuname) {
1.212     www      2772: 			if (&Apache::lonnet::put('resourcedata',{$tkey=>$data,
                   2773: 								 $tkey.'.type' => $typeof},
                   2774: 						 $tudom,$tuname) eq 'ok') {
1.290     www      2775: 			    &log_parmset({$tkey=>$data,$tkey.'.type' => $typeof},0,$tuname,$tudom);
1.384     albertel 2776: 			    $r->print('<br />'.$text.' '.
1.207     www      2777: 				      &Apache::loncommon::plainname($tuname,$tudom));
                   2778: 			} else {
1.314     albertel 2779: 			    $r->print('<div class="LC_error">'.
1.365     albertel 2780: 				      &mt('Error saving parameters').'</div>');
1.207     www      2781: 			}
                   2782: 			&Apache::lonnet::devalidateuserresdata($tuname,$tudom);
                   2783: 		    } else {
                   2784: 			$newdata{$thiskey}=$data;
1.212     www      2785:  			$newdata{$thiskey.'.type'}=$typeof; 
                   2786:                    } 
1.207     www      2787: 		}
1.124     www      2788: 	    } elsif ($cmd eq 'del') {
1.207     www      2789: 		if ($tuname) {
                   2790: 		    if (&Apache::lonnet::del('resourcedata',[$tkey],$tudom,$tuname) eq 'ok') {
1.290     www      2791: 			    &log_parmset({$tkey=>''},1,$tuname,$tudom);
1.207     www      2792: 			$r->print('<br />'.&mt('Deleted parameter for').' '.&Apache::loncommon::plainname($tuname,$tudom));
                   2793: 		    } else {
1.314     albertel 2794: 			$r->print('<div class="LC_error">'.
                   2795: 				  &mt('Error deleting parameters').'</div>');
1.207     www      2796: 		    }
                   2797: 		    &Apache::lonnet::devalidateuserresdata($tuname,$tudom);
                   2798: 		} else {
1.333     albertel 2799: 		    push (@deldata,$thiskey,$thiskey.'.type');
1.207     www      2800: 		}
1.124     www      2801: 	    }
                   2802: 	}
                   2803:     }
1.207     www      2804: # Store all course level
1.144     www      2805:     my $delentries=$#deldata+1;
                   2806:     my @newdatakeys=keys %newdata;
                   2807:     my $putentries=$#newdatakeys+1;
                   2808:     if ($delentries) {
                   2809: 	if (&Apache::lonnet::del('resourcedata',\@deldata,$dom,$crs) eq 'ok') {
1.290     www      2810: 	    my %loghash=map { $_ => '' } @deldata;
                   2811: 	    &log_parmset(\%loghash,1);
1.144     www      2812: 	    $r->print('<h2>'.&mt('Deleted [_1] parameter(s)</h2>',$delentries));
                   2813: 	} else {
1.314     albertel 2814: 	    $r->print('<div class="LC_error">'.
                   2815: 		      &mt('Error deleting parameters').'</div>');
1.144     www      2816: 	}
1.205     www      2817: 	&Apache::lonnet::devalidatecourseresdata($crs,$dom);
1.144     www      2818:     }
                   2819:     if ($putentries) {
                   2820: 	if (&Apache::lonnet::put('resourcedata',\%newdata,$dom,$crs) eq 'ok') {
1.290     www      2821: 			    &log_parmset(\%newdata,0);
1.365     albertel 2822: 	    $r->print('<h3>'.&mt('Saved [_1] parameter(s)',$putentries/2).'</h3>');
1.144     www      2823: 	} else {
1.314     albertel 2824: 	    $r->print('<div class="LC_error">'.
1.365     albertel 2825: 		      &mt('Error saving parameters').'</div>');
1.144     www      2826: 	}
1.205     www      2827: 	&Apache::lonnet::devalidatecourseresdata($crs,$dom);
1.144     www      2828:     }
1.208     www      2829: }
1.207     www      2830: 
1.208     www      2831: sub extractuser {
                   2832:     my $key=shift;
1.350     albertel 2833:     return ($key=~/^$env{'request.course.id'}.\[useropt\:($match_username)\:($match_domain)\]\./);
1.208     www      2834: }
1.206     www      2835: 
1.381     albertel 2836: sub parse_listdata_key {
                   2837:     my ($key,$listdata) = @_;
                   2838:     # split into student/section affected, and
                   2839:     # the realm (folder/resource part and parameter
                   2840:     my ($student,$realm) = 
                   2841: 	($key=~/^\Q$env{'request.course.id'}\E\.\[([^\.]+)\]\.(.+)$/);
                   2842:     # if course wide student would be undefined
                   2843:     if (!defined($student)) {
                   2844: 	($realm)=($key=~/^\Q$env{'request.course.id'}\E\.(.+)$/);
                   2845:     }
                   2846:     # strip off the .type if it's not the Question type parameter
                   2847:     if ($realm=~/\.type$/ && !exists($listdata->{$key.'.type'})) {
                   2848: 	$realm=~s/\.type//;
                   2849:     }
                   2850:     # split into resource+part and parameter name
1.388     albertel 2851:     my ($res,    $parm) = ($realm=~/^(.*)\.(.*)$/);
                   2852:        ($res, my $part) = ($res  =~/^(.*)\.(.*)$/);
1.381     albertel 2853:     return ($student,$res,$part,$parm);
                   2854: }
                   2855: 
1.208     www      2856: sub listdata {
1.214     www      2857:     my ($r,$resourcedata,$listdata,$sortorder)=@_;
1.207     www      2858: # Start list output
1.206     www      2859: 
1.122     www      2860:     my $oldsection='';
                   2861:     my $oldrealm='';
                   2862:     my $oldpart='';
1.123     www      2863:     my $pointer=0;
1.124     www      2864:     $tableopen=0;
1.145     www      2865:     my $foundkeys=0;
1.248     albertel 2866:     my %keyorder=&standardkeyorder();
1.381     albertel 2867: 
1.214     www      2868:     foreach my $thiskey (sort {
1.381     albertel 2869: 	my ($astudent,$ares,$apart,$aparm) = &parse_listdata_key($a,$listdata);
                   2870: 	my ($bstudent,$bres,$bpart,$bparm) = &parse_listdata_key($b,$listdata);
                   2871: 
                   2872: 	# get the numerical order for the param
                   2873: 	$aparm=$keyorder{'parameter_0_'.$aparm};
                   2874: 	$bparm=$keyorder{'parameter_0_'.$bparm};
                   2875: 
                   2876: 	my $result=0;
                   2877: 
1.214     www      2878: 	if ($sortorder eq 'realmstudent') {
1.381     albertel 2879:             if ($ares     ne $bres    ) {
                   2880: 		$result = ($ares     cmp $bres);
                   2881:             } elsif ($astudent ne $bstudent) { 
                   2882: 		$result = ($astudent cmp $bstudent);
                   2883: 	    } elsif ($apart    ne $bpart   ) {
                   2884: 		$result = ($apart    cmp $bpart);
1.237     albertel 2885: 	    }
1.381     albertel 2886: 	} else {
                   2887: 	    if      ($astudent ne $bstudent) { 
                   2888: 		$result = ($astudent cmp $bstudent);
                   2889: 	    } elsif ($ares     ne $bres    ) {
                   2890: 		$result = ($ares     cmp $bres);
                   2891: 	    } elsif ($apart    ne $bpart   ) {
                   2892: 		$result = ($apart    cmp $bpart);
1.247     albertel 2893: 	    }
1.381     albertel 2894: 	}
                   2895: 	    
                   2896: 	if (!$result) {
                   2897:             if (defined($aparm) && defined($bparm)) {
                   2898: 		$result = ($aparm <=> $bparm);
                   2899:             } elsif (defined($aparm)) {
                   2900: 		$result = -1;
                   2901:             } elsif (defined($bparm)) {
                   2902: 		$result = 1;
1.248     albertel 2903: 	    }
1.214     www      2904: 	}
1.381     albertel 2905: 
                   2906: 	$result;
1.214     www      2907:     } keys %{$listdata}) {
1.381     albertel 2908: 
1.211     www      2909: 	if ($$listdata{$thiskey.'.type'}) {
                   2910:             my $thistype=$$listdata{$thiskey.'.type'};
                   2911:             if ($$resourcedata{$thiskey.'.type'}) {
                   2912: 		$thistype=$$resourcedata{$thiskey.'.type'};
                   2913: 	    }
1.207     www      2914: 	    my ($middle,$part,$name)=
                   2915: 		($thiskey=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s]+)\.(\w+)$/);
1.130     www      2916: 	    my $section=&mt('All Students');
1.207     www      2917: 	    if ($middle=~/^\[(.*)\]/) {
1.206     www      2918: 		my $issection=$1;
1.350     albertel 2919: 		if ($issection=~/^useropt\:($match_username)\:($match_domain)/) {
1.206     www      2920: 		    $section=&mt('User').": ".&Apache::loncommon::plainname($1,$2);
                   2921: 		} else {
                   2922: 		    $section=&mt('Group/Section').': '.$issection;
                   2923: 		}
1.207     www      2924: 		$middle=~s/^\[(.*)\]//;
1.122     www      2925: 	    }
1.207     www      2926: 	    $middle=~s/\.+$//;
                   2927: 	    $middle=~s/^\.+//;
1.316     albertel 2928: 	    my $realm='<span class="LC_parm_scope_all">'.&mt('All Resources').'</span>';
1.122     www      2929: 	    if ($middle=~/^(.+)\_\_\_\(all\)$/) {
1.316     albertel 2930: 		$realm='<span class="LC_parm_scope_folder">'.&mt('Folder/Map').': '.&Apache::lonnet::gettitle($1).' <br /><span class="LC_parm_folder">('.$1.')</span></span>';
1.122     www      2931: 	    } elsif ($middle) {
1.174     albertel 2932: 		my ($map,$id,$url)=&Apache::lonnet::decode_symb($middle);
1.316     albertel 2933: 		$realm='<span class="LC_parm_scope_resource">'.&mt('Resource').': '.&Apache::lonnet::gettitle($middle).' <br /><span class="LC_parm_symb">('.$url.' in '.$map.' id: '.$id.')</span></span>';
1.122     www      2934: 	    }
1.214     www      2935: 	    if ($sortorder eq 'realmstudent') {
                   2936: 		if ($realm ne $oldrealm) {
                   2937: 		    $r->print(&tableend()."\n<hr /><h1>$realm</h1>");
                   2938: 		    $oldrealm=$realm;
                   2939: 		    $oldsection='';
                   2940: 		}
                   2941: 		if ($section ne $oldsection) {
                   2942: 		    $r->print(&tableend()."\n<h2>$section</h2>");
                   2943: 		    $oldsection=$section;
                   2944: 		    $oldpart='';
                   2945: 		}
                   2946: 	    } else {
                   2947: 		if ($section ne $oldsection) {
                   2948: 		    $r->print(&tableend()."\n<hr /><h1>$section</h1>");
                   2949: 		    $oldsection=$section;
                   2950: 		    $oldrealm='';
                   2951: 		}
                   2952: 		if ($realm ne $oldrealm) {
                   2953: 		    $r->print(&tableend()."\n<h2>$realm</h2>");
                   2954: 		    $oldrealm=$realm;
                   2955: 		    $oldpart='';
                   2956: 		}
1.122     www      2957: 	    }
                   2958: 	    if ($part ne $oldpart) {
1.124     www      2959: 		$r->print(&tableend().
1.316     albertel 2960: 			  "\n<span class=\"LC_parm_part\">".&mt('Part').": $part</span>");
1.122     www      2961: 		$oldpart=$part;
                   2962: 	    }
1.123     www      2963: #
                   2964: # Ready to print
                   2965: #
1.295     albertel 2966: 	    $r->print(&tablestart().
                   2967: 		      &Apache::loncommon::start_data_table_row().
                   2968: 		      '<td><b>'.&standard_parameter_names($name).
1.293     www      2969: 		      '</b></td><td><input type="checkbox" name="del_'.
1.124     www      2970: 		      $thiskey.'" /></td><td>');
1.145     www      2971: 	    $foundkeys++;
1.213     www      2972: 	    if (&isdateparm($thistype)) {
1.123     www      2973: 		my $jskey='key_'.$pointer;
                   2974: 		$pointer++;
                   2975: 		$r->print(
1.232     albertel 2976: 			  &Apache::lonhtmlcommon::date_setter('parmform',
1.123     www      2977: 							      $jskey,
1.219     www      2978: 						      $$resourcedata{$thiskey},
1.325     www      2979: 							      '',1,'','').
1.277     www      2980: '<input type="hidden" name="datepointer_'.$thiskey.'" value="'.$jskey.'" />'.
1.413     bisitz   2981: (($$resourcedata{$thiskey}!=0)?'<span class="LC_nobreak"><a href="/adm/parmset?&action=dateshift1&timebase='.$$resourcedata{$thiskey}.'">'.
                   2982: &mt('Shift all dates based on this date').'</a></span>':'').
1.277     www      2983: &date_sanity_info($$resourcedata{$thiskey})
1.123     www      2984: 			  );
1.385     albertel 2985: 	    } elsif ($thistype eq 'date_interval') {
                   2986: 		$r->print(&date_interval_selector($thiskey,
                   2987: 						  $$resourcedata{$thiskey}));
1.383     albertel 2988: 	    } elsif ($thistype =~ m/^string/) {
                   2989: 		$r->print(&string_selector($thistype,$thiskey,
                   2990: 					   $$resourcedata{$thiskey}));
1.123     www      2991: 	    } else {
1.383     albertel 2992: 		$r->print(&default_selector($thiskey,$$resourcedata{$thiskey}));
1.123     www      2993: 	    }
1.211     www      2994: 	    $r->print('<input type="hidden" name="typeof_'.$thiskey.'" value="'.
                   2995: 		      $thistype.'">');
1.295     albertel 2996: 	    $r->print('</td>'.&Apache::loncommon::end_data_table_row());
1.122     www      2997: 	}
1.121     www      2998:     }
1.208     www      2999:     return $foundkeys;
                   3000: }
                   3001: 
1.385     albertel 3002: 
                   3003: sub date_interval_selector {
                   3004:     my ($thiskey, $showval) = @_;
                   3005:     my $result;
                   3006:     foreach my $which (['days', 86400, 31],
                   3007: 		       ['hours', 3600, 23],
                   3008: 		       ['minutes', 60, 59],
                   3009: 		       ['seconds',  1, 59]) {
                   3010: 	my ($name, $factor, $max) = @{ $which };
                   3011: 	my $amount = int($showval/$factor);
                   3012: 	$showval  %= $factor;
                   3013: 	my %select = ((map {$_ => $_} (0..$max)),
                   3014: 		      'select_form_order' => [0..$max]);
                   3015: 	$result .= &Apache::loncommon::select_form($amount,$name.'_'.$thiskey,
                   3016: 						   %select);
                   3017: 	$result .= ' '.&mt($name);
                   3018:     }
                   3019:     $result .= '<input type="hidden" name="dateinterval_'.$thiskey.'" />';
                   3020:     return $result;
                   3021: 
                   3022: }
                   3023: 
                   3024: sub get_date_interval_from_form {
                   3025:     my ($key) = @_;
                   3026:     my $seconds = 0;
                   3027:     foreach my $which (['days', 86400],
                   3028: 		       ['hours', 3600],
                   3029: 		       ['minutes', 60],
                   3030: 		       ['seconds',  1]) {
                   3031: 	my ($name, $factor) = @{ $which };
                   3032: 	if (defined($env{'form.'.$name.'_'.$key})) {
                   3033: 	    $seconds += $env{'form.'.$name.'_'.$key} * $factor;
                   3034: 	}
                   3035:     }
                   3036:     return $seconds;
                   3037: }
                   3038: 
                   3039: 
1.383     albertel 3040: sub default_selector {
                   3041:     my ($thiskey, $showval) = @_;
1.385     albertel 3042:     return '<input type="text" name="set_'.$thiskey.'" value="'.$showval.'" />';
1.383     albertel 3043: }
                   3044: 
                   3045: my %strings = 
                   3046:     (
                   3047:      'string_yesno'
                   3048:              => [[ 'yes', 'Yes' ],
                   3049: 		 [ 'no', 'No' ]],
                   3050:      'string_problemstatus'
                   3051:              => [[ 'yes', 'Yes' ],
1.394     www      3052: 		 [ 'answer', 'Yes, and show correct answer if they exceed the maximum number of tries.' ],
1.383     albertel 3053: 		 [ 'no', 'No, don\'t show correct/incorrect feedback.' ],
                   3054: 		 [ 'no_feedback_ever', 'No, show no feedback at all.' ]],
                   3055:      );
                   3056: 
                   3057: 
                   3058: sub string_selector {
                   3059:     my ($thistype, $thiskey, $showval) = @_;
                   3060:     
                   3061:     if (!exists($strings{$thistype})) {
                   3062: 	return &default_selector($thiskey,$showval);
                   3063:     }
                   3064: 
                   3065:     my $result;
                   3066:     foreach my $possibilities (@{ $strings{$thistype} }) {
                   3067: 	my ($name, $description) = @{ $possibilities };
                   3068: 	$result .= '<label><input type="radio" name="set_'.$thiskey.
                   3069: 		  '" value="'.$name.'"';
                   3070: 	if ($showval eq $name) {
                   3071: 	    $result .= ' checked="checked"';
                   3072: 	}
                   3073: 	$result .= ' />'.&mt($description).'</label> ';
                   3074:     }
                   3075:     return $result;
                   3076: }
                   3077: 
1.389     www      3078: #
                   3079: # Shift all start and end dates by $shift
                   3080: #
                   3081: 
                   3082: sub dateshift {
                   3083:     my ($shift)=@_;
                   3084:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   3085:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
                   3086:     my %data=&Apache::lonnet::dump('resourcedata',$dom,$crs);
                   3087: # ugly retro fix for broken version of types
                   3088:     foreach my $key (keys %data) {
                   3089:         if ($key=~/\wtype$/) {
                   3090:             my $newkey=$key;
                   3091:             $newkey=~s/type$/\.type/;
                   3092:             $data{$newkey}=$data{$key};
                   3093:             delete $data{$key};
                   3094:         }
                   3095:     }
1.391     www      3096:     my %storecontent=();
1.389     www      3097: # go through all parameters and look for dates
                   3098:     foreach my $key (keys %data) {
                   3099:        if ($data{$key.'.type'}=~/^date_(start|end)$/) {
                   3100:           my $newdate=$data{$key}+$shift;
1.391     www      3101:           $storecontent{$key}=$newdate;
1.389     www      3102:        }
                   3103:     }
1.391     www      3104:     my $reply=&Apache::lonnet::cput
                   3105:                 ('resourcedata',\%storecontent,$dom,$crs);
                   3106:     if ($reply eq 'ok') {
                   3107:        &log_parmset(\%storecontent);
                   3108:     }
                   3109:     &Apache::lonnet::devalidatecourseresdata($crs,$dom);
                   3110:     return $reply;
1.389     www      3111: }
                   3112: 
1.208     www      3113: sub newoverview {
1.280     albertel 3114:     my ($r) = @_;
                   3115: 
1.208     www      3116:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   3117:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.280     albertel 3118:     my $start_page = &Apache::loncommon::start_page('Set Parameters');
1.298     albertel 3119:     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview');
1.208     www      3120:     $r->print(<<ENDOVER);
1.280     albertel 3121: $start_page
1.208     www      3122: $breadcrumbs
1.232     albertel 3123: <form method="post" action="/adm/parmset?action=newoverview" name="parmform">
1.208     www      3124: ENDOVER
1.211     www      3125:     my @ids=();
                   3126:     my %typep=();
                   3127:     my %keyp=();
                   3128:     my %allparms=();
                   3129:     my %allparts=();
                   3130:     my %allmaps=();
                   3131:     my %mapp=();
                   3132:     my %symbp=();
                   3133:     my %maptitles=();
                   3134:     my %uris=();
                   3135:     my %keyorder=&standardkeyorder();
                   3136:     my %defkeytype=();
                   3137: 
                   3138:     my %alllevs=();
                   3139:     $alllevs{'Resource Level'}='full';
1.215     www      3140:     $alllevs{'Map/Folder Level'}='map';
1.211     www      3141:     $alllevs{'Course Level'}='general';
                   3142: 
                   3143:     my $csec=$env{'form.csec'};
1.269     raeburn  3144:     my $cgroup=$env{'form.cgroup'};
1.211     www      3145: 
                   3146:     my @pscat=&Apache::loncommon::get_env_multiple('form.pscat');
                   3147:     my $pschp=$env{'form.pschp'};
                   3148:     my @psprt=&Apache::loncommon::get_env_multiple('form.psprt');
                   3149:     if (!@psprt) { $psprt[0]='0'; }
                   3150: 
                   3151:     my @selected_sections = 
                   3152: 	&Apache::loncommon::get_env_multiple('form.Section');
                   3153:     @selected_sections = ('all') if (! @selected_sections);
1.374     albertel 3154:     foreach my $sec (@selected_sections) {
                   3155:         if ($sec eq 'all') {
1.211     www      3156:             @selected_sections = ('all');
                   3157:         }
                   3158:     }
1.269     raeburn  3159:     my @selected_groups =
                   3160:         &Apache::loncommon::get_env_multiple('form.Group');
1.211     www      3161: 
                   3162:     my $pssymb='';
                   3163:     my $parmlev='';
                   3164:  
                   3165:     unless ($env{'form.parmlev'}) {
                   3166:         $parmlev = 'map';
                   3167:     } else {
                   3168:         $parmlev = $env{'form.parmlev'};
                   3169:     }
                   3170: 
                   3171:     &extractResourceInformation(\@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allmaps, 
                   3172: 				\%mapp, \%symbp,\%maptitles,\%uris,
                   3173: 				\%keyorder,\%defkeytype);
                   3174: 
1.374     albertel 3175:     if (grep {$_ eq 'all'} (@psprt)) {
                   3176: 	@psprt = keys(%allparts);
                   3177:     }
1.211     www      3178: # Menu to select levels, etc
                   3179: 
1.317     albertel 3180:     $r->print('<table id="LC_parm_overview_scope">
                   3181:                <tr><td class="LC_parm_overview_level_menu">');
1.211     www      3182:     &levelmenu($r,\%alllevs,$parmlev);
                   3183:     if ($parmlev ne 'general') {
1.317     albertel 3184: 	$r->print('<td class="LC_parm_overview_map_menu">');
1.211     www      3185: 	&mapmenu($r,\%allmaps,$pschp,\%maptitles);
                   3186: 	$r->print('</td>');
                   3187:     }
                   3188:     $r->print('</td></tr></table>');
                   3189: 
1.317     albertel 3190:     $r->print('<table id="LC_parm_overview_controls">
                   3191:                <tr><td class="LC_parm_overview_parm_selectors">');  
1.211     www      3192:     &parmmenu($r,\%allparms,\@pscat,\%keyorder);
1.317     albertel 3193:     $r->print('</td><td class="LC_parm_overview_restrictions">
                   3194:                 <table class="LC_parm_overview_restrictions">'.
                   3195:               '<tr><th>'.&mt('Parts').'</th><th>'.&mt('Section(s)').
                   3196:               '</th><th>'.&mt('Group(s)').'</th></tr><tr><td>');
1.211     www      3197:     &partmenu($r,\%allparts,\@psprt);
1.317     albertel 3198:     $r->print('</td><td>');
1.211     www      3199:     &sectionmenu($r,\@selected_sections);
1.317     albertel 3200:     $r->print('</td><td>');
1.269     raeburn  3201:     &groupmenu($r,\@selected_groups);
                   3202:     $r->print('</td></tr></table>');
1.214     www      3203:     $r->print('</td></tr></table>');
                   3204:  
                   3205:     my $sortorder=$env{'form.sortorder'};
                   3206:     unless ($sortorder) { $sortorder='realmstudent'; }
                   3207:     &sortmenu($r,$sortorder);
                   3208: 
                   3209:     $r->print('<p><input type="submit" name="dis" value="'.&mt('Display').'" /></p>');
1.211     www      3210: 
                   3211: # Build the list data hash from the specified parms
                   3212: 
                   3213:     my $listdata;
                   3214:     %{$listdata}=();
                   3215: 
                   3216:     foreach my $cat (@pscat) {
1.269     raeburn  3217:         &secgroup_lister($cat,$pschp,$parmlev,$listdata,\@psprt,\@selected_sections,\%defkeytype,\%allmaps,\@ids,\%symbp);
                   3218:         &secgroup_lister($cat,$pschp,$parmlev,$listdata,\@psprt,\@selected_groups,\%defkeytype,\%allmaps,\@ids,\%symbp);
1.211     www      3219:     }
                   3220: 
1.212     www      3221:     if (($env{'form.store'}) || ($env{'form.dis'})) {
1.211     www      3222: 
1.212     www      3223: 	if ($env{'form.store'}) { &storedata($r,$crs,$dom); }
1.211     www      3224: 
                   3225: # Read modified data
                   3226: 
                   3227: 	my $resourcedata=&readdata($crs,$dom);
                   3228: 
                   3229: # List data
                   3230: 
1.214     www      3231: 	&listdata($r,$resourcedata,$listdata,$sortorder);
1.211     www      3232:     }
                   3233:     $r->print(&tableend().
1.365     albertel 3234: 	     ((($env{'form.store'}) || ($env{'form.dis'}))?'<p><input type="submit" name="store" value="'.&mt('Save').'" /></p>':'').
1.280     albertel 3235: 	      '</form>'.&Apache::loncommon::end_page());
1.208     www      3236: }
                   3237: 
1.269     raeburn  3238: sub secgroup_lister {
                   3239:     my ($cat,$pschp,$parmlev,$listdata,$psprt,$selections,$defkeytype,$allmaps,$ids,$symbp) = @_;
                   3240:     foreach my $item (@{$selections}) {
                   3241:         foreach my $part (@{$psprt}) {
                   3242:             my $rootparmkey=$env{'request.course.id'};
                   3243:             if (($item ne 'all') && ($item ne 'none') && ($item)) {
                   3244:                 $rootparmkey.='.['.$item.']';
                   3245:             }
                   3246:             if ($parmlev eq 'general') {
                   3247: # course-level parameter
                   3248:                 my $newparmkey=$rootparmkey.'.'.$part.'.'.$cat;
                   3249:                 $$listdata{$newparmkey}=1;
                   3250:                 $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
                   3251:             } elsif ($parmlev eq 'map') {
                   3252: # map-level parameter
                   3253:                 foreach my $mapid (keys %{$allmaps}) {
                   3254:                     if (($pschp ne 'all') && ($pschp ne $mapid)) { next; }
                   3255:                     my $newparmkey=$rootparmkey.'.'.$$allmaps{$mapid}.'___(all).'.$part.'.'.$cat;
                   3256:                     $$listdata{$newparmkey}=1;
                   3257:                     $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
                   3258:                 }
                   3259:             } else {
                   3260: # resource-level parameter
                   3261:                 foreach my $rid (@{$ids}) {
                   3262:                     my ($map,$resid,$url)=&Apache::lonnet::decode_symb($$symbp{$rid});
                   3263:                     if (($pschp ne 'all') && ($$allmaps{$pschp} ne $map)) { next; }
                   3264:                     my $newparmkey=$rootparmkey.'.'.$$symbp{$rid}.'.'.$part.'.'.$cat;
                   3265:                     $$listdata{$newparmkey}=1;
                   3266:                     $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
                   3267:                 }
                   3268:             }
                   3269:         }
                   3270:     }
                   3271: }
                   3272: 
1.208     www      3273: sub overview {
1.280     albertel 3274:     my ($r) = @_;
1.208     www      3275:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   3276:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.280     albertel 3277: 
                   3278:     my $start_page=&Apache::loncommon::start_page('Modify Parameters');
1.298     albertel 3279:     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview');
1.208     www      3280:     $r->print(<<ENDOVER);
1.280     albertel 3281: $start_page
1.208     www      3282: $breadcrumbs
1.232     albertel 3283: <form method="post" action="/adm/parmset?action=setoverview" name="parmform">
1.208     www      3284: ENDOVER
                   3285: # Store modified
                   3286: 
                   3287:     &storedata($r,$crs,$dom);
                   3288: 
                   3289: # Read modified data
                   3290: 
                   3291:     my $resourcedata=&readdata($crs,$dom);
                   3292: 
1.214     www      3293: 
                   3294:     my $sortorder=$env{'form.sortorder'};
                   3295:     unless ($sortorder) { $sortorder='realmstudent'; }
                   3296:     &sortmenu($r,$sortorder);
                   3297: 
1.208     www      3298: # List data
                   3299: 
1.214     www      3300:     my $foundkeys=&listdata($r,$resourcedata,$resourcedata,$sortorder);
1.208     www      3301: 
1.145     www      3302:     $r->print(&tableend().'<p>'.
1.280     albertel 3303: 	($foundkeys?'<input type="submit" value="'.&mt('Modify Parameters').'" />':&mt('There are no parameters.')).'</p></form>'.
                   3304: 	      &Apache::loncommon::end_page());
1.120     www      3305: }
1.121     www      3306: 
1.333     albertel 3307: sub clean_parameters {
                   3308:     my ($r) = @_;
                   3309:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   3310:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
                   3311: 
                   3312:     my $start_page=&Apache::loncommon::start_page('Clean Parameters');
                   3313:     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Clean');
                   3314:     $r->print(<<ENDOVER);
                   3315: $start_page
                   3316: $breadcrumbs
                   3317: <form method="post" action="/adm/parmset?action=cleanparameters" name="parmform">
                   3318: ENDOVER
                   3319: # Store modified
                   3320: 
                   3321:     &storedata($r,$crs,$dom);
                   3322: 
                   3323: # Read modified data
                   3324: 
                   3325:     my $resourcedata=&readdata($crs,$dom);
                   3326: 
                   3327: # List data
                   3328: 
                   3329:     $r->print('<h3>'.
                   3330: 	      &mt('These parameters refer to resources that do not exist.').
                   3331: 	      '</h3>'.
1.413.2.1! raeburn  3332: 	      '<input type="submit" value="'.&mt('Delete Selected').'" />'.'<br />'.
1.333     albertel 3333: 	      '<br />');
                   3334:     $r->print(&Apache::loncommon::start_data_table().
                   3335: 	      '<tr>'.
                   3336: 	      '<th>'.&mt('Delete').'</th>'.
                   3337: 	      '<th>'.&mt('Parameter').'</th>'.
                   3338: 	      '</tr>');
                   3339:     foreach my $thiskey (sort(keys(%{$resourcedata}))) {
                   3340: 	next if (!exists($resourcedata->{$thiskey.'.type'})
                   3341: 		 && $thiskey=~/\.type$/);
                   3342: 	my %data = &parse_key($thiskey);
1.383     albertel 3343: 	if (1) { #exists($data{'realm_exists'})
                   3344: 	    #&& !$data{'realm_exists'}) {
1.333     albertel 3345: 	    $r->print(&Apache::loncommon::start_data_table_row().
                   3346: 		      '<tr>'.
                   3347: 		      '<td><input type="checkbox" name="del_'.$thiskey.'" /></td>'		      );
                   3348: 	    
                   3349: 	    $r->print('<td>');
1.362     albertel 3350: 	    my $display_value = $resourcedata->{$thiskey};
                   3351: 	    if (&isdateparm($resourcedata->{$thiskey.'.type'})) {
                   3352: 		$display_value = 
                   3353: 		    &Apache::lonlocal::locallocaltime($display_value);
                   3354: 	    }
1.333     albertel 3355: 	    $r->print(&mt('Parameter: "[_1]" with value: "[_2]"',
                   3356: 			  &standard_parameter_names($data{'parameter_name'}),
                   3357: 			  $resourcedata->{$thiskey}));
                   3358: 	    $r->print('<br />');
                   3359: 	    if ($data{'scope_type'} eq 'all') {
                   3360: 		$r->print(&mt('All users'));
                   3361: 	    } elsif ($data{'scope_type'} eq 'user') {
                   3362: 		$r->print(&mt('User: [_1]',join(':',@{$data{'scope'}})));
                   3363: 	    } elsif ($data{'scope_type'} eq 'section') {
                   3364: 		$r->print(&mt('Section: [_1]',$data{'scope'}));
                   3365: 	    } elsif ($data{'scope_type'} eq 'group') {
                   3366: 		$r->print(&mt('Group: [_1]',$data{'scope'}));
                   3367: 	    }
                   3368: 	    $r->print('<br />');
                   3369: 	    if ($data{'realm_type'} eq 'all') {
                   3370: 		$r->print(&mt('All Resources'));
                   3371: 	    } elsif ($data{'realm_type'} eq 'folder') {
                   3372: 		$r->print(&mt('Folder: [_1]'),$data{'realm'});
                   3373: 	    } elsif ($data{'realm_type'} eq 'symb') {
                   3374: 		my ($map,$resid,$url) =
                   3375: 		    &Apache::lonnet::decode_symb($data{'realm'});
                   3376: 		$r->print(&mt('Resource: [_1] <br />&nbsp;&nbsp;&nbsp;with ID: [_2] <br />&nbsp;&nbsp;&nbsp;in folder [_3]',
                   3377: 			      $url,$resid,$map));
                   3378: 	    }
1.362     albertel 3379: 	    $r->print(' <br />&nbsp;&nbsp;&nbsp;'.&mt('Part: [_1]',$data{'parameter_part'}));
1.333     albertel 3380: 	    $r->print('</td></tr>');
                   3381: 	
                   3382: 	}
                   3383:     }
                   3384:     $r->print(&Apache::loncommon::end_data_table().'<p>'.
1.413.2.1! raeburn  3385: 	      '<input type="submit" value="'.&mt('Delete Selected').'" />'.
1.333     albertel 3386: 	      '</p></form>'.
                   3387: 	      &Apache::loncommon::end_page());
                   3388: }
                   3389: 
1.390     www      3390: sub date_shift_one {
                   3391:     my ($r) = @_;
                   3392:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   3393:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
                   3394: 
                   3395:     my $start_page=&Apache::loncommon::start_page('Shift Dates');
                   3396:     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Shift');
                   3397:     $r->print(<<ENDOVER);
                   3398: $start_page
                   3399: $breadcrumbs
                   3400: ENDOVER
                   3401:     $r->print('<form name="shiftform" method="post">'.
                   3402:               '<table><tr><td>'.&mt('Currently set date:').'</td><td>'.
                   3403:               &Apache::lonlocal::locallocaltime($env{'form.timebase'}).'</td></tr>'.
                   3404:               '<tr><td>'.&mt('Shifted date:').'</td><td>'.
                   3405:                     &Apache::lonhtmlcommon::date_setter('shiftform',
                   3406:                                                         'timeshifted',
                   3407:                                                         $env{'form.timebase'},,
                   3408:                                                         '').
                   3409:               '</td></tr></table>'.
                   3410:               '<input type="hidden" name="action" value="dateshift2" />'.
                   3411:               '<input type="hidden" name="timebase" value="'.$env{'form.timebase'}.'" />'.
                   3412:               '<input type="submit" value="'.&mt('Shift all dates accordingly').'" /></form>');
                   3413:     $r->print(&Apache::loncommon::end_page());
                   3414: }
                   3415: 
                   3416: sub date_shift_two {
                   3417:     my ($r) = @_;
                   3418:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   3419:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
                   3420:     my $start_page=&Apache::loncommon::start_page('Shift Dates');
                   3421:     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Shift');
                   3422:     $r->print(<<ENDOVER);
                   3423: $start_page
                   3424: $breadcrumbs
                   3425: ENDOVER
                   3426:     my $timeshifted=&Apache::lonhtmlcommon::get_date_from_form('timeshifted');
                   3427:     $r->print(&mt('Shifting all dates such that [_1] becomes [_2]',
                   3428:               &Apache::lonlocal::locallocaltime($env{'form.timebase'}),
                   3429:               &Apache::lonlocal::locallocaltime($timeshifted)));
                   3430:     my $delta=$timeshifted-$env{'form.timebase'};
                   3431:     &dateshift($delta);
                   3432:     $r->print(&Apache::loncommon::end_page());
                   3433: }
                   3434: 
1.333     albertel 3435: sub parse_key {
                   3436:     my ($key) = @_;
                   3437:     my %data;
                   3438:     my ($middle,$part,$name)=
                   3439: 	($key=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s]+)\.(\w+)$/);
                   3440:     $data{'scope_type'} = 'all';
                   3441:     if ($middle=~/^\[(.*)\]/) {
                   3442:        	$data{'scope'} = $1;
1.350     albertel 3443: 	if ($data{'scope'}=~/^useropt\:($match_username)\:($match_domain)/) {
1.333     albertel 3444: 	    $data{'scope_type'} = 'user';
                   3445: 	    $data{'scope'} = [$1,$2];
                   3446: 	} else {
                   3447: 	    #FIXME check for group scope
                   3448: 	    $data{'scope_type'} = 'section';
                   3449: 	}
                   3450: 	$middle=~s/^\[(.*)\]//;
                   3451:     }
                   3452:     $middle=~s/\.+$//;
                   3453:     $middle=~s/^\.+//;
                   3454:     $data{'realm_type'}='all';
                   3455:     if ($middle=~/^(.+)\_\_\_\(all\)$/) {
                   3456: 	$data{'realm'} = $1;
                   3457: 	$data{'realm_type'} = 'folder';
                   3458: 	$data{'realm_title'} = &Apache::lonnet::gettitle($data{'realm'});
                   3459: 	($data{'realm_exists'}) = &Apache::lonnet::is_on_map($data{'realm'});
                   3460:     } elsif ($middle) {
                   3461: 	$data{'realm'} = $middle;
                   3462: 	$data{'realm_type'} = 'symb';
                   3463: 	$data{'realm_title'} = &Apache::lonnet::gettitle($data{'realm'});
                   3464: 	my ($map,$resid,$url) = &Apache::lonnet::decode_symb($data{'realm'});
                   3465: 	$data{'realm_exists'} = &Apache::lonnet::symbverify($data{'realm'},$url);
                   3466:     }
                   3467:     
                   3468:     $data{'parameter_part'} = $part;
                   3469:     $data{'parameter_name'} = $name;
                   3470: 
                   3471:     return %data;
                   3472: }
                   3473: 
1.59      matthew  3474: ##################################################
                   3475: ##################################################
1.333     albertel 3476: 
1.178     raeburn  3477: =pod
1.239     raeburn  3478: 
                   3479: =item check_cloners
                   3480: 
                   3481: Checks if new users included in list of allowed cloners
                   3482: are valid users.  Replaces supplied list with 
                   3483: cleaned list containing only users with valid usernames
                   3484: and domains.
                   3485: 
                   3486: Inputs: $clonelist, $oldcloner 
                   3487: where $clonelist is ref to array of requested cloners,
                   3488: and $oldcloner is ref to array of currently allowed
                   3489: cloners.
                   3490: 
                   3491: Returns: string - comma separated list of requested
                   3492: cloners (username:domain) who do not exist in system.
                   3493: 
                   3494: =item change_clone
                   3495: 
1.178     raeburn  3496: Modifies the list of courses a user can clone (stored
1.239     raeburn  3497: in the user's environment.db file), called when a
1.178     raeburn  3498: change is made to the list of users allowed to clone
                   3499: a course.
1.239     raeburn  3500: 
1.178     raeburn  3501: Inputs: $action,$cloner
                   3502: where $action is add or drop, and $cloner is identity of 
                   3503: user for whom cloning ability is to be changed in course. 
                   3504: 
                   3505: =cut
1.380     albertel 3506: 
1.178     raeburn  3507: ##################################################
                   3508: ##################################################
                   3509: 
1.239     raeburn  3510: sub extract_cloners {
                   3511:     my ($clonelist,$allowclone) = @_;
                   3512:     if ($clonelist =~ /,/) {
1.380     albertel 3513:         @{$allowclone} = split(/,/,$clonelist);
1.239     raeburn  3514:     } else {
                   3515:         $$allowclone[0] = $clonelist;
                   3516:     }
                   3517: }
                   3518: 
                   3519: sub check_cloners {
                   3520:     my ($clonelist,$oldcloner) = @_;
1.379     raeburn  3521:     my ($clean_clonelist,%disallowed);
1.239     raeburn  3522:     my @allowclone = ();
                   3523:     &extract_cloners($$clonelist,\@allowclone);
                   3524:     foreach my $currclone (@allowclone) {
1.380     albertel 3525:         if (!grep(/^\Q$currclone\E$/,@$oldcloner)) {
1.379     raeburn  3526:             if ($currclone eq '*') {
                   3527:                 $clean_clonelist .= $currclone.',';
                   3528:             } else {
                   3529:                 my ($uname,$udom) = split(/:/,$currclone);
                   3530:                 if ($uname eq '*') {
                   3531:                     if ($udom =~ /^$match_domain$/) {
1.380     albertel 3532:                         if (!&Apache::lonnet::domain($udom)) {
1.379     raeburn  3533:                             $disallowed{'domain'} .= $currclone.',';
                   3534:                         } else {
                   3535:                             $clean_clonelist .= $currclone.',';
                   3536:                         }
                   3537:                     } else {
                   3538:                         $disallowed{'format'} .= $currclone.',';
                   3539:                     }
                   3540:                 } elsif ($currclone !~/^($match_username)\:($match_domain)$/) {
                   3541:                     $disallowed{'format'} .= $currclone.','; 
1.239     raeburn  3542:                 } else {
1.379     raeburn  3543:                     if (&Apache::lonnet::homeserver($uname,$udom) eq 'no_host') {
                   3544:                         $disallowed{'newuser'} .= $currclone.',';
                   3545:                     } else {
                   3546:                         $clean_clonelist .= $currclone.',';
                   3547:                     }
1.239     raeburn  3548:                 }
                   3549:             }
                   3550:         } else {
                   3551:             $clean_clonelist .= $currclone.',';
                   3552:         }
                   3553:     }
1.379     raeburn  3554:     foreach my $key (keys(%disallowed)) {
                   3555:         $disallowed{$key} =~ s/,$//;
1.239     raeburn  3556:     }
                   3557:     if ($clean_clonelist) {
                   3558:         $clean_clonelist =~ s/,$//;
                   3559:     }
                   3560:     $$clonelist = $clean_clonelist;
1.379     raeburn  3561:     return %disallowed;
                   3562: }
1.178     raeburn  3563: 
                   3564: sub change_clone {
                   3565:     my ($clonelist,$oldcloner) = @_;
                   3566:     my ($uname,$udom);
1.190     albertel 3567:     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                   3568:     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
1.178     raeburn  3569:     my $clone_crs = $cnum.':'.$cdom;
                   3570:     
                   3571:     if ($cnum && $cdom) {
1.239     raeburn  3572:         my @allowclone;
                   3573:         &extract_cloners($clonelist,\@allowclone);
1.178     raeburn  3574:         foreach my $currclone (@allowclone) {
1.380     albertel 3575:             if (!grep(/^$currclone$/,@$oldcloner)) {
1.379     raeburn  3576:                 if ($currclone ne '*') {
1.380     albertel 3577:                     ($uname,$udom) = split(/:/,$currclone);
1.379     raeburn  3578:                     if ($uname && $udom && $uname ne '*') {
                   3579:                         if (&Apache::lonnet::homeserver($uname,$udom) ne 'no_host') {
                   3580:                             my %currclonecrs = &Apache::lonnet::dump('environment',$udom,$uname,'cloneable');
                   3581:                             if ($currclonecrs{'cloneable'} !~ /\Q$clone_crs\E/) {
                   3582:                                 if ($currclonecrs{'cloneable'} eq '') {
                   3583:                                     $currclonecrs{'cloneable'} = $clone_crs;
                   3584:                                 } else {
                   3585:                                     $currclonecrs{'cloneable'} .= ','.$clone_crs;
                   3586:                                 }
                   3587:                                 &Apache::lonnet::put('environment',\%currclonecrs,$udom,$uname);
1.178     raeburn  3588:                             }
                   3589:                         }
                   3590:                     }
                   3591:                 }
                   3592:             }
                   3593:         }
                   3594:         foreach my $oldclone (@$oldcloner) {
1.380     albertel 3595:             if (!grep(/^\Q$oldclone\E$/,@allowclone)) {
1.379     raeburn  3596:                 if ($oldclone ne '*') {
1.380     albertel 3597:                     ($uname,$udom) = split(/:/,$oldclone);
1.379     raeburn  3598:                     if ($uname && $udom && $uname ne '*' ) {
                   3599:                         if (&Apache::lonnet::homeserver($uname,$udom) ne 'no_host') {
                   3600:                             my %currclonecrs = &Apache::lonnet::dump('environment',$udom,$uname,'cloneable');
                   3601:                             my %newclonecrs = ();
                   3602:                             if ($currclonecrs{'cloneable'} =~ /\Q$clone_crs\E/) {
                   3603:                                 if ($currclonecrs{'cloneable'} =~ /,/) {
                   3604:                                     my @currclonecrs = split/,/,$currclonecrs{'cloneable'};
                   3605:                                     foreach my $crs (@currclonecrs) {
                   3606:                                         if ($crs ne $clone_crs) {
                   3607:                                             $newclonecrs{'cloneable'} .= $crs.',';
                   3608:                                         }
1.178     raeburn  3609:                                     }
1.379     raeburn  3610:                                     $newclonecrs{'cloneable'} =~ s/,$//;
                   3611:                                 } else {
                   3612:                                     $newclonecrs{'cloneable'} = '';
1.178     raeburn  3613:                                 }
1.379     raeburn  3614:                                 &Apache::lonnet::put('environment',\%newclonecrs,$udom,$uname);
1.178     raeburn  3615:                             }
                   3616:                         }
                   3617:                     }
                   3618:                 }
                   3619:             }
                   3620:         }
                   3621:     }
                   3622: }
                   3623: 
1.193     albertel 3624: 
                   3625: ##################################################
                   3626: ##################################################
                   3627: 
                   3628: =pod
                   3629: 
                   3630: =item * header
                   3631: 
                   3632: Output html header for page
                   3633: 
                   3634: =cut
                   3635: 
                   3636: ##################################################
                   3637: ##################################################
                   3638: sub header {
1.280     albertel 3639:     return &Apache::loncommon::start_page('Parameter Manager');
1.193     albertel 3640: }
                   3641: ##################################################
                   3642: ##################################################
                   3643: sub print_main_menu {
                   3644:     my ($r,$parm_permission)=@_;
                   3645:     #
                   3646:     $r->print(<<ENDMAINFORMHEAD);
                   3647: <form method="post" enctype="multipart/form-data"
                   3648:       action="/adm/parmset" name="studentform">
                   3649: ENDMAINFORMHEAD
                   3650: #
1.195     albertel 3651:     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                   3652:     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
1.268     albertel 3653:     my $vgr  = &Apache::lonnet::allowed('vgr',$env{'request.course.id'});
1.366     albertel 3654:     my $mgr  = &Apache::lonnet::allowed('mgr',$env{'request.course.id'});
1.268     albertel 3655: 
1.193     albertel 3656:     my @menu =
1.322     www      3657:         ( { divider=>'Settings for Your Course',
                   3658: 	  },
1.323     albertel 3659:           { text => 'Set Course Environment',
1.204     www      3660: 	    action => 'crsenv',
1.193     albertel 3661:             permission => $parm_permission,
1.324     www      3662:             help => 'Course_Environment',
1.193     albertel 3663:             },
1.255     banghart 3664:           { text => 'Set Portfolio Metadata',
1.259     banghart 3665: 	    action => 'setrestrictmeta',
1.240     banghart 3666:             permission => $parm_permission,
                   3667:             },
1.271     www      3668: 	  { text => 'Manage Course Slots',
1.268     albertel 3669: 	    url => '/adm/slotrequest?command=showslots',
                   3670: 	    permission => $vgr,
                   3671:             },
1.366     albertel 3672: 	  { text => 'Reset Student Access Times',
                   3673: 	    url => '/adm/helper/resettimes.helper',
                   3674: 	    permission => $mgr,
                   3675:             },
                   3676: 
1.322     www      3677:           { text => 'Set Parameter Setting Default Actions',
                   3678:             action => 'setdefaults',
                   3679:             permission => $parm_permission,
                   3680:             },          
                   3681: 	  { divider => 'New and Existing Parameter Settings for Your Resources',
1.268     albertel 3682: 	    },
1.216     www      3683:           { text => 'Set/Modify Resource Parameters - Helper Mode',
1.193     albertel 3684:             url => '/adm/helper/parameter.helper',
                   3685:             permission => $parm_permission,
1.324     www      3686:             help => 'Parameter_Helper',
1.193     albertel 3687:             },
1.322     www      3688:  	  { text => 'Set/Modify Resource Parameters - Overview Mode',
1.208     www      3689:             action => 'newoverview',
                   3690:             permission => $parm_permission,
1.324     www      3691:             help => 'Parameter_Overview',
1.193     albertel 3692:             },
1.216     www      3693:           { text => 'Set/Modify Resource Parameters - Table Mode',
1.193     albertel 3694:             action => 'settable',
                   3695:             permission => $parm_permission,
1.324     www      3696:             help => 'Table_Mode',
1.193     albertel 3697:             },
1.322     www      3698:            { divider => 'Existing Parameter Settings for Your Resources',
                   3699: 	  },
                   3700: 	  { text => 'Modify Resource Parameters - Overview Mode',
                   3701:             action => 'setoverview',
1.220     www      3702:             permission => $parm_permission,
1.324     www      3703:             help => 'Parameter_Overview',
1.322     www      3704:  	    },          
1.292     www      3705: 	  { text => 'Parameter Change Log and Course Blog Posting/User Notification',
1.284     www      3706:             action => 'parameterchangelog',
                   3707:             permission => $parm_permission,
1.220     www      3708:             },
1.193     albertel 3709:           );
                   3710:     my $menu_html = '';
                   3711:     foreach my $menu_item (@menu) {
1.268     albertel 3712: 	if ($menu_item->{'divider'}) {
1.322     www      3713: 	    $menu_html .= '<h3>'.&mt($menu_item->{'divider'}).'</h3>';
1.268     albertel 3714: 	    next;
                   3715: 	}
1.193     albertel 3716:         next if (! $menu_item->{'permission'});
                   3717:         $menu_html.='<p>';
1.316     albertel 3718:         $menu_html.='<span class="LC_parm_menu_item">';
1.193     albertel 3719:         if (exists($menu_item->{'url'})) {
                   3720:             $menu_html.=qq{<a href="$menu_item->{'url'}">};
                   3721:         } else {
                   3722:             $menu_html.=
                   3723:                 qq{<a href="/adm/parmset?action=$menu_item->{'action'}">};
                   3724:         }
1.316     albertel 3725:         $menu_html.= &mt($menu_item->{'text'}).'</a></span>';
1.193     albertel 3726:         if (exists($menu_item->{'help'})) {
                   3727:             $menu_html.=
                   3728:                 &Apache::loncommon::help_open_topic($menu_item->{'help'});
                   3729:         }
                   3730:         $menu_html.='</p>'.$/;
                   3731:     }
                   3732:     $r->print($menu_html);
                   3733:     return;
                   3734: }
1.255     banghart 3735: ### Set portfolio metadata
1.252     banghart 3736: sub output_row {
1.347     banghart 3737:     my ($r, $field_name, $field_text, $added_flag) = @_;
1.252     banghart 3738:     my $output;
1.263     banghart 3739:     my $options=$env{'course.'.$env{'request.course.id'}.'.metadata.'.$field_name.'.options'};
                   3740:     my $values=$env{'course.'.$env{'request.course.id'}.'.metadata.'.$field_name.'.values'};
1.337     banghart 3741:     if (!defined($options)) {
1.254     banghart 3742:         $options = 'active,stuadd';
1.261     banghart 3743:         $values = '';
1.252     banghart 3744:     }
1.337     banghart 3745:     if (!($options =~ /deleted/)) {
                   3746:         my @options= ( ['active', 'Show to student'],
1.351     banghart 3747:                     ['stuadd', 'Provide text area for students to type catalog information'],
                   3748:                     ['choices','Provide choices for students to select from']);
                   3749: #		   ['onlyone','Student may select only one choice']);
1.337     banghart 3750:         if ($added_flag) {
                   3751:             push @options,['deleted', 'Delete Metadata Field'];
                   3752:         }
1.351     banghart 3753:        $output = &Apache::loncommon::start_data_table_row();
                   3754:         $output .= '<td><span class="LC_metadata"><strong>'.$field_text.':</strong></span></td>';
                   3755:         $output .= &Apache::loncommon::end_data_table_row();
1.337     banghart 3756:         foreach my $opt (@options) {
                   3757: 	    my $checked = ($options =~ m/$opt->[0]/) ? ' checked="checked" ' : '' ;
1.347     banghart 3758: 	    $output .= &Apache::loncommon::continue_data_table_row();
1.351     banghart 3759: 	    $output .= '<td>'.('&nbsp;' x 5).'<span class="LC_metadata"><label>
                   3760: 	               <input type="checkbox" name="'.
                   3761: 	               $field_name.'_'.$opt->[0].'" value="yes"'.$checked.' />'.
                   3762: 	               &mt($opt->[1]).'</label></span> </td>';
1.347     banghart 3763: 	    $output .= &Apache::loncommon::end_data_table_row();
1.337     banghart 3764: 	}
1.351     banghart 3765:         $output .= &Apache::loncommon::continue_data_table_row();
                   3766:         $output .= '<td>'.('&nbsp;' x 10).'<span class="LC_metadata"><input name="'.$field_name.'_values" type="text" value="'.$values.'" size="80" /></span></td>';
                   3767:         $output .= &Apache::loncommon::end_data_table_row();
                   3768:         my $multiple_checked;
                   3769:         my $single_checked;
                   3770:         if ($options =~ m/onlyone/) {
                   3771:             $multiple_checked = "";
                   3772:             $single_checked = " CHECKED ";
                   3773:         } else {
                   3774:             $multiple_checked = " CHECKED ";
                   3775:             $single_checked = "";
                   3776:         }
                   3777: 	$output .= &Apache::loncommon::continue_data_table_row();
                   3778: 	$output .= '<td>'.('&nbsp;' x 10).'<span class="LC_metadata">
                   3779: 	            <input type="radio" name="'.$field_name.'_onlyone" value="multiple" '.$multiple_checked .'/>
                   3780: 	            Student may select multiple choices from list</span></td>';
                   3781: 	$output .= &Apache::loncommon::end_data_table_row();
                   3782: 	$output .= &Apache::loncommon::continue_data_table_row();
                   3783: 	$output .= '<td>'.('&nbsp;' x 10).'<span class="LC_metadata">
                   3784: 	            <input type="radio" name="'.$field_name.'_onlyone"  value="single" '.$single_checked.'/>
                   3785: 	            Student may select only one choice from list</span></td>';
                   3786: 	$output .= &Apache::loncommon::end_data_table_row();
1.252     banghart 3787:     }
                   3788:     return ($output);
                   3789: }
1.340     banghart 3790: sub order_meta_fields {
                   3791:     my ($r)=@_;
                   3792:     my $idx = 1;
                   3793:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   3794:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.341     banghart 3795:     $r->print(&Apache::loncommon::start_page('Order Metadata Fields'));
1.345     banghart 3796:     &Apache::lonhtmlcommon::add_breadcrumb
                   3797:             ({href=>"/adm/parmset?action=setrestrictmeta",
                   3798:               text=>"Restrict Metadata"},
                   3799:              {text=>"Order Metadata"});
                   3800:     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Order Metadata'));
1.340     banghart 3801:     if ($env{'form.storeorder'}) {
                   3802:         my $newpos = $env{'form.newpos'} - 1;
                   3803:         my $currentpos = $env{'form.currentpos'} - 1;
                   3804:         my @neworder = ();
                   3805:         my @oldorder = split /,/,$env{'course.'.$env{'request.course.id'}.'.metadata.addedorder'};
                   3806:         my $i;
1.341     banghart 3807:         if ($newpos > $currentpos) {
1.340     banghart 3808:         # moving stuff up
                   3809:             for ($i=0;$i<$currentpos;$i++) {
                   3810:         	$neworder[$i]=$oldorder[$i];
                   3811:             }
                   3812:             for ($i=$currentpos;$i<$newpos;$i++) {
                   3813:         	$neworder[$i]=$oldorder[$i+1];
                   3814:             }
                   3815:             $neworder[$newpos]=$oldorder[$currentpos];
                   3816:             for ($i=$newpos+1;$i<=$#oldorder;$i++) {
                   3817:         	$neworder[$i]=$oldorder[$i];
                   3818:             }
                   3819:         } else {
                   3820:         # moving stuff down
                   3821:     	    for ($i=0;$i<$newpos;$i++) {
                   3822:     	        $neworder[$i]=$oldorder[$i];
                   3823:     	    }
                   3824:     	    $neworder[$newpos]=$oldorder[$currentpos];
                   3825:     	    for ($i=$newpos+1;$i<$currentpos+1;$i++) {
                   3826:     	        $neworder[$i]=$oldorder[$i-1];
                   3827:     	    }
                   3828:     	    for ($i=$currentpos+1;$i<=$#oldorder;$i++) {
                   3829:     	        $neworder[$i]=$oldorder[$i];
                   3830:     	    }
                   3831:         }
                   3832: 	my $ordered_fields = join ",", @neworder;
1.343     banghart 3833:         my $put_result = &Apache::lonnet::put('environment',
                   3834:                            {'metadata.addedorder'=>$ordered_fields},$dom,$crs); 	
1.393     raeburn  3835: 	&Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.metadata.addedorder' => $ordered_fields});
1.340     banghart 3836:     }
1.357     raeburn  3837:     my $fields = &get_added_meta_fieldnames($env{'request.course.id'});
1.341     banghart 3838:     my $ordered_fields;
1.340     banghart 3839:     my @fields_in_order = split /,/,$env{'course.'.$env{'request.course.id'}.'.metadata.addedorder'};
                   3840:     if (!@fields_in_order) {
                   3841:         # no order found, pick sorted order then create metadata.addedorder key.
                   3842:         foreach my $key (sort keys %$fields) {
                   3843:             push @fields_in_order, $key;
1.341     banghart 3844:             $ordered_fields = join ",", @fields_in_order;
1.340     banghart 3845:         }
1.341     banghart 3846:         my $put_result = &Apache::lonnet::put('environment',
                   3847:                             {'metadata.addedorder'=>$ordered_fields},$dom,$crs); 
                   3848:     } 
1.340     banghart 3849:     $r->print('<table>');
                   3850:     my $num_fields = scalar(@fields_in_order);
                   3851:     foreach my $key (@fields_in_order) {
                   3852:         $r->print('<tr><td>');
                   3853:         $r->print('<form method="post" action="">');
                   3854:         $r->print('<select name="newpos" onChange="this.form.submit()">');
                   3855:         for (my $i = 1;$i le $num_fields;$i ++) {
                   3856:             if ($i eq $idx) {
                   3857:                 $r->print('<option value="'.$i.'"  SELECTED>('.$i.')</option>');
                   3858:             } else {
                   3859:                 $r->print('<option value="'.$i.'">'.$i.'</option>');
                   3860:             }
                   3861:         }
                   3862:         $r->print('</select></td><td>');
                   3863:         $r->print('<input type="hidden" name="currentpos" value="'.$idx.'" />');
                   3864:         $r->print('<input type="hidden" name="storeorder" value="true" />');
                   3865:         $r->print('</form>');
                   3866:         $r->print($$fields{$key}.'</td></tr>');
                   3867:         $idx ++;
                   3868:     }
                   3869:     $r->print('</table>');
                   3870:     return 'ok';
                   3871: }
1.359     banghart 3872: sub continue {
                   3873:     my $output;
                   3874:     $output .= '<form action="" method="post">';
                   3875:     $output .= '<input type="hidden" name="action" value="setrestrictmeta" />';
                   3876:     $output .= '<input type="submit" value="Continue" />';
                   3877:     return ($output);
                   3878: }
1.334     banghart 3879: sub addmetafield {
                   3880:     my ($r)=@_;
                   3881:     $r->print(&Apache::loncommon::start_page('Add Metadata Field'));
                   3882:     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Add Metadata Field'));
1.335     banghart 3883:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   3884:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.339     banghart 3885:     if (exists($env{'form.undelete'})) {
1.358     banghart 3886:         my @meta_fields = &Apache::loncommon::get_env_multiple('form.undeletefield');
1.339     banghart 3887:         foreach my $meta_field(@meta_fields) {
                   3888:             my $options = $env{'course.'.$env{'request.course.id'}.'.metadata.'.$meta_field.'.options'};
                   3889:             $options =~ s/deleted//;
                   3890:             $options =~ s/,,/,/;
                   3891:             my $put_result = &Apache::lonnet::put('environment',
                   3892:                                         {'metadata.'.$meta_field.'.options'=>$options},$dom,$crs);
                   3893:                                         
                   3894:             $r->print('Undeleted Metadata Field <strong>'.$env{'course.'.$env{'request.course.id'}.'.metadata.'.$meta_field.'.added'}."</strong> with result ".$put_result.'<br />');
                   3895:         }
1.359     banghart 3896:         $r->print(&continue());
1.339     banghart 3897:     } elsif (exists($env{'form.fieldname'})) {
1.335     banghart 3898:         my $meta_field = $env{'form.fieldname'};
                   3899:         my $display_field = $env{'form.fieldname'};
                   3900:         $meta_field =~ s/\W/_/g;
1.338     banghart 3901:         $meta_field =~ tr/A-Z/a-z/;
1.335     banghart 3902:         my $put_result = &Apache::lonnet::put('environment',
                   3903:                             {'metadata.'.$meta_field.'.values'=>"",
                   3904:                              'metadata.'.$meta_field.'.added'=>"$display_field",
                   3905:                              'metadata.'.$meta_field.'.options'=>""},$dom,$crs);
1.359     banghart 3906:         $r->print('Added new Metadata Field <strong>'.$env{'form.fieldname'}."</strong> with result ".$put_result.'<br />');
                   3907:         $r->print(&continue());
1.335     banghart 3908:     } else {
1.357     raeburn  3909:         my $fields = &get_deleted_meta_fieldnames($env{'request.course.id'});
1.339     banghart 3910:         if ($fields) {
                   3911:             $r->print('You may undelete previously deleted fields.<br />Check those you wish to undelete and click Undelete.<br />');
                   3912:             $r->print('<form method="post" action="">');
                   3913:             foreach my $key(keys(%$fields)) {
1.358     banghart 3914:                 $r->print('<input type="checkbox" name="undeletefield" value="'.$key.'" />'.$$fields{$key}.'<br /');
1.339     banghart 3915:             }
                   3916:             $r->print('<input type="submit" name="undelete" value="Undelete" />');
                   3917:             $r->print('</form>');
                   3918:         }
                   3919:         $r->print('<hr /><strong>Or</strong> you may enter a new metadata field name.<form method="post" action="/adm/parmset?action=addmetadata"');
1.335     banghart 3920:         $r->print('<input type="text" name="fieldname" /><br />');
                   3921:         $r->print('<input type="submit" value="Add Metadata Field" />');
1.334     banghart 3922:     }
1.361     albertel 3923:     $r->print('</form>');
1.334     banghart 3924: }
1.259     banghart 3925: sub setrestrictmeta {
1.240     banghart 3926:     my ($r)=@_;
1.242     banghart 3927:     my $next_meta;
1.244     banghart 3928:     my $output;
1.245     banghart 3929:     my $item_num;
1.246     banghart 3930:     my $put_result;
1.280     albertel 3931:     $r->print(&Apache::loncommon::start_page('Restrict Metadata'));
1.298     albertel 3932:     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Restrict Metadata'));
1.240     banghart 3933:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   3934:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.259     banghart 3935:     my $key_base = $env{'course.'.$env{'request.course.id'}.'.'};
1.252     banghart 3936:     my $save_field = '';
1.259     banghart 3937:     if ($env{'form.restrictmeta'}) {
1.254     banghart 3938:         foreach my $field (sort(keys(%env))) {
1.252     banghart 3939:             if ($field=~m/^form.(.+)_(.+)$/) {
1.254     banghart 3940:                 my $options;
1.252     banghart 3941:                 my $meta_field = $1;
                   3942:                 my $meta_key = $2;
1.253     banghart 3943:                 if ($save_field ne $meta_field) {
1.252     banghart 3944:                     $save_field = $meta_field;
1.253     banghart 3945:             	    if ($env{'form.'.$meta_field.'_stuadd'}) {
1.254     banghart 3946:             	        $options.='stuadd,';
                   3947:             	    } 
1.351     banghart 3948:             	    if ($env{'form.'.$meta_field.'_choices'}) {
                   3949:             	        $options.='choices,';
                   3950:             	    } 
                   3951:             	    if ($env{'form.'.$meta_field.'_onlyone'} eq 'single') {
1.254     banghart 3952:             	        $options.='onlyone,';
                   3953:             	    } 
                   3954:             	    if ($env{'form.'.$meta_field.'_active'}) {
                   3955:             	        $options.='active,';
1.253     banghart 3956:             	    }
1.337     banghart 3957:             	    if ($env{'form.'.$meta_field.'_deleted'}) {
                   3958:             	        $options.='deleted,';
                   3959:             	    }
1.259     banghart 3960:                     my $name = $save_field;
1.253     banghart 3961:                      $put_result = &Apache::lonnet::put('environment',
1.262     banghart 3962:                                                   {'metadata.'.$meta_field.'.options'=>$options,
                   3963:                                                    'metadata.'.$meta_field.'.values'=>$env{'form.'.$meta_field.'_values'},
1.253     banghart 3964:                                                    },$dom,$crs);
1.252     banghart 3965:                 }
                   3966:             }
                   3967:         }
                   3968:     }
1.296     albertel 3969:     &Apache::lonnet::coursedescription($env{'request.course.id'},
                   3970: 				       {'freshen_cache' => 1});
1.335     banghart 3971:     # Get the default metadata fields
1.258     albertel 3972:     my %metadata_fields = &Apache::lonmeta::fieldnames('portfolio');
1.335     banghart 3973:     # Now get possible added metadata fields
1.357     raeburn  3974:     my $added_metadata_fields = &get_added_meta_fieldnames($env{'request.course.id'});
1.346     banghart 3975:     my $row_alt = 1;
1.347     banghart 3976:     $output .= &Apache::loncommon::start_data_table();
1.258     albertel 3977:     foreach my $field (sort(keys(%metadata_fields))) {
1.265     banghart 3978:         if ($field ne 'courserestricted') {
1.346     banghart 3979:             $row_alt = $row_alt ? 0 : 1;
1.347     banghart 3980: 	    $output.= &output_row($r, $field, $metadata_fields{$field});
1.265     banghart 3981: 	}
1.255     banghart 3982:     }
1.351     banghart 3983:     my $buttons = (<<ENDButtons);
                   3984:         <input type="submit" name="restrictmeta" value="Save" />
                   3985:         </form><br />
                   3986:         <form method="post" action="/adm/parmset?action=addmetadata" name="form1">
                   3987:         <input type="submit" name="restrictmeta" value="Add a Metadata Field" />
                   3988:         </form>
                   3989:         <br />
                   3990:         <form method="post" action="/adm/parmset?action=ordermetadata" name="form2">
                   3991:         <input type="submit" name="restrictmeta" value="Order Metadata Fields" />
                   3992: ENDButtons
1.337     banghart 3993:     my $added_flag = 1;
1.335     banghart 3994:     foreach my $field (sort(keys(%$added_metadata_fields))) {
1.346     banghart 3995:         $row_alt = $row_alt ? 0 : 1;
                   3996:         $output.= &output_row($r, $field, $$added_metadata_fields{$field},$added_flag, $row_alt);
1.335     banghart 3997:     }
1.347     banghart 3998:     $output .= &Apache::loncommon::end_data_table();
1.244     banghart 3999:     $r->print(<<ENDenv);       
1.259     banghart 4000:         <form method="post" action="/adm/parmset?action=setrestrictmeta" name="form">
1.244     banghart 4001:         $output
1.351     banghart 4002:         $buttons
1.340     banghart 4003:         </form>
1.244     banghart 4004: ENDenv
1.280     albertel 4005:     $r->print(&Apache::loncommon::end_page());
1.240     banghart 4006:     return 'ok';
                   4007: }
1.220     www      4008: ##################################################
1.335     banghart 4009: sub get_added_meta_fieldnames {
1.357     raeburn  4010:     my ($cid) = @_;
1.335     banghart 4011:     my %fields;
                   4012:     foreach my $key(%env) {
1.357     raeburn  4013:         if ($key =~ m/\Q$cid\E\.metadata\.(.+)\.added$/) {
1.335     banghart 4014:             my $field_name = $1;
                   4015:             my ($display_field_name) = $env{$key};
                   4016:             $fields{$field_name} = $display_field_name;
                   4017:         }
                   4018:     }
                   4019:     return \%fields;
                   4020: }
1.339     banghart 4021: sub get_deleted_meta_fieldnames {
1.357     raeburn  4022:     my ($cid) = @_;
1.339     banghart 4023:     my %fields;
                   4024:     foreach my $key(%env) {
1.357     raeburn  4025:         if ($key =~ m/\Q$cid\E\.metadata\.(.+)\.added$/) {
1.339     banghart 4026:             my $field_name = $1;
                   4027:             if ($env{'course.'.$env{'request.course.id'}.'.metadata.'.$field_name.'.options'} =~ m/deleted/) {
                   4028:                 my ($display_field_name) = $env{$key};
                   4029:                 $fields{$field_name} = $display_field_name;
                   4030:             }
                   4031:         }
                   4032:     }
                   4033:     return \%fields;
                   4034: }
1.220     www      4035: sub defaultsetter {
1.280     albertel 4036:     my ($r) = @_;
                   4037: 
                   4038:     my $start_page = 
                   4039: 	&Apache::loncommon::start_page('Parameter Setting Default Actions');
1.298     albertel 4040:     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Defaults');
1.220     www      4041:     $r->print(<<ENDDEFHEAD);
1.280     albertel 4042: $start_page
1.220     www      4043: $breadcrumbs
                   4044: <form method="post" action="/adm/parmset?action=setdefaults" name="defaultform">
                   4045: ENDDEFHEAD
1.280     albertel 4046: 
                   4047:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   4048:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.221     www      4049:     my @ids=();
                   4050:     my %typep=();
                   4051:     my %keyp=();
                   4052:     my %allparms=();
                   4053:     my %allparts=();
                   4054:     my %allmaps=();
                   4055:     my %mapp=();
                   4056:     my %symbp=();
                   4057:     my %maptitles=();
                   4058:     my %uris=();
                   4059:     my %keyorder=&standardkeyorder();
                   4060:     my %defkeytype=();
                   4061: 
                   4062:     &extractResourceInformation(\@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allmaps, 
                   4063: 				\%mapp, \%symbp,\%maptitles,\%uris,
                   4064: 				\%keyorder,\%defkeytype);
1.224     www      4065:     if ($env{'form.storerules'}) {
                   4066: 	my %newrules=();
                   4067: 	my @delrules=();
1.226     www      4068: 	my %triggers=();
1.225     albertel 4069: 	foreach my $key (keys(%env)) {
                   4070:             if ($key=~/^form\.(\w+)\_action$/) {
1.224     www      4071: 		my $tempkey=$1;
1.226     www      4072: 		my $action=$env{$key};
                   4073:                 if ($action) {
                   4074: 		    $newrules{$tempkey.'_action'}=$action;
                   4075: 		    if ($action ne 'default') {
                   4076: 			my ($whichaction,$whichparm)=($action=~/^(.*\_)([^\_]+)$/);
                   4077: 			$triggers{$whichparm}.=$tempkey.':';
                   4078: 		    }
                   4079: 		    $newrules{$tempkey.'_type'}=$defkeytype{$tempkey};
1.224     www      4080: 		    if (&isdateparm($defkeytype{$tempkey})) {
1.227     www      4081: 			$newrules{$tempkey.'_days'}=$env{'form.'.$tempkey.'_days'};
1.224     www      4082: 			$newrules{$tempkey.'_hours'}=$env{'form.'.$tempkey.'_hours'};
                   4083: 			$newrules{$tempkey.'_min'}=$env{'form.'.$tempkey.'_min'};
                   4084: 			$newrules{$tempkey.'_sec'}=$env{'form.'.$tempkey.'_sec'};
                   4085: 		    } else {
                   4086: 			$newrules{$tempkey.'_value'}=$env{'form.'.$tempkey.'_value'};
1.227     www      4087: 			$newrules{$tempkey.'_triggervalue'}=$env{'form.'.$tempkey.'_triggervalue'};
1.224     www      4088: 		    }
                   4089: 		} else {
1.225     albertel 4090: 		    push(@delrules,$tempkey.'_action');
1.226     www      4091: 		    push(@delrules,$tempkey.'_type');
1.225     albertel 4092: 		    push(@delrules,$tempkey.'_hours');
                   4093: 		    push(@delrules,$tempkey.'_min');
                   4094: 		    push(@delrules,$tempkey.'_sec');
                   4095: 		    push(@delrules,$tempkey.'_value');
1.224     www      4096: 		}
                   4097: 	    }
                   4098: 	}
1.226     www      4099: 	foreach my $key (keys %allparms) {
                   4100: 	    $newrules{$key.'_triggers'}=$triggers{$key};
                   4101: 	}
1.224     www      4102: 	&Apache::lonnet::put('parmdefactions',\%newrules,$dom,$crs);
                   4103: 	&Apache::lonnet::del('parmdefactions',\@delrules,$dom,$crs);
                   4104: 	&resetrulescache();
                   4105:     }
1.227     www      4106:     my %lt=&Apache::lonlocal::texthash('days' => 'Days',
                   4107: 				       'hours' => 'Hours',
1.221     www      4108: 				       'min' => 'Minutes',
                   4109: 				       'sec' => 'Seconds',
                   4110: 				       'yes' => 'Yes',
                   4111: 				       'no' => 'No');
1.222     www      4112:     my @standardoptions=('','default');
                   4113:     my @standarddisplay=('',&mt('Default value when manually setting'));
                   4114:     my @dateoptions=('','default');
                   4115:     my @datedisplay=('',&mt('Default value when manually setting'));
                   4116:     foreach my $tempkey (&keysindisplayorder(\%allparms,\%keyorder)) {
                   4117: 	unless ($tempkey) { next; }
                   4118: 	push @standardoptions,'when_setting_'.$tempkey;
                   4119: 	push @standarddisplay,&mt('Automatically set when setting ').$tempkey;
                   4120: 	if (&isdateparm($defkeytype{$tempkey})) {
                   4121: 	    push @dateoptions,'later_than_'.$tempkey;
                   4122: 	    push @datedisplay,&mt('Automatically set later than ').$tempkey;
                   4123: 	    push @dateoptions,'earlier_than_'.$tempkey;
                   4124: 	    push @datedisplay,&mt('Automatically set earlier than ').$tempkey;
                   4125: 	} 
                   4126:     }
1.231     www      4127: $r->print(&mt('Manual setting rules apply to all interfaces.').'<br />'.
                   4128: 	  &mt('Automatic setting rules apply to table mode interfaces only.'));
1.318     albertel 4129:     $r->print("\n".&Apache::loncommon::start_data_table().
                   4130: 	      &Apache::loncommon::start_data_table_header_row().
                   4131: 	      "<th>".&mt('Rule for parameter').'</th><th>'.
                   4132: 	      &mt('Action').'</th><th>'.&mt('Value').'</th>'.
                   4133: 	      &Apache::loncommon::end_data_table_header_row());
1.221     www      4134:     foreach my $tempkey (&keysindisplayorder(\%allparms,\%keyorder)) {
1.222     www      4135: 	unless ($tempkey) { next; }
1.318     albertel 4136: 	$r->print("\n".&Apache::loncommon::start_data_table_row().
                   4137: 		  "<td>".$allparms{$tempkey}."\n<br />(".$tempkey.')</td><td>');
1.222     www      4138: 	my $action=&rulescache($tempkey.'_action');
                   4139: 	$r->print('<select name="'.$tempkey.'_action">');
                   4140: 	if (&isdateparm($defkeytype{$tempkey})) {
                   4141: 	    for (my $i=0;$i<=$#dateoptions;$i++) {
                   4142: 		if ($dateoptions[$i]=~/\_$tempkey$/) { next; }
                   4143: 		$r->print("\n<option value='$dateoptions[$i]'".
                   4144: 			  ($dateoptions[$i] eq $action?' selected="selected"':'').
                   4145: 			  ">$datedisplay[$i]</option>");
                   4146: 	    }
                   4147: 	} else {
                   4148: 	    for (my $i=0;$i<=$#standardoptions;$i++) {
                   4149: 		if ($standardoptions[$i]=~/\_$tempkey$/) { next; }
                   4150: 		$r->print("\n<option value='$standardoptions[$i]'".
                   4151: 			  ($standardoptions[$i] eq $action?' selected="selected"':'').
                   4152: 			  ">$standarddisplay[$i]</option>");
                   4153: 	    }
                   4154: 	}
                   4155: 	$r->print('</select>');
1.227     www      4156: 	unless (&isdateparm($defkeytype{$tempkey})) {
                   4157: 	    $r->print("\n<br />".&mt('Triggering value(s) of other parameter (optional, comma-separated):').
                   4158: 		      '<input type="text" size="20" name="'.$tempkey.'_triggervalue" value="'.&rulescache($tempkey.'_triggervalue').'" />');
                   4159: 	}
1.222     www      4160: 	$r->print("\n</td><td>\n");
                   4161: 
1.221     www      4162:         if (&isdateparm($defkeytype{$tempkey})) {
1.227     www      4163: 	    my $days=&rulescache($tempkey.'_days');
1.222     www      4164: 	    my $hours=&rulescache($tempkey.'_hours');
                   4165: 	    my $min=&rulescache($tempkey.'_min');
                   4166: 	    my $sec=&rulescache($tempkey.'_sec');
1.221     www      4167: 	    $r->print(<<ENDINPUTDATE);
1.227     www      4168: <input name="$tempkey\_days" type="text" size="4" value="$days" />$lt{'days'}<br />
1.222     www      4169: <input name="$tempkey\_hours" type="text" size="4" value="$hours" />$lt{'hours'}<br />
                   4170: <input name="$tempkey\_min" type="text" size="4" value="$min" />$lt{'min'}<br />
                   4171: <input name="$tempkey\_sec" type="text" size="4" value="$sec" />$lt{'sec'}
1.221     www      4172: ENDINPUTDATE
                   4173: 	} elsif ($defkeytype{$tempkey} eq 'string_yesno') {
1.222     www      4174:             my $yeschecked='';
                   4175:             my $nochecked='';
                   4176:             if (&rulescache($tempkey.'_value') eq 'yes') { $yeschecked='checked="checked"'; }
                   4177:             if (&rulescache($tempkey.'_value') eq 'no') { $nochecked='checked="checked"'; }
                   4178: 
1.221     www      4179: 	    $r->print(<<ENDYESNO);
1.224     www      4180: <label><input type="radio" name="$tempkey\_value" value="yes" $yeschecked /> $lt{'yes'}</label><br />
                   4181: <label><input type="radio" name="$tempkey\_value" value="no" $nochecked /> $lt{'no'}</label>
1.221     www      4182: ENDYESNO
                   4183:         } else {
1.224     www      4184: 	    $r->print('<input type="text" size="20" name="'.$tempkey.'_value" value="'.&rulescache($tempkey.'_value').'" />');
1.221     www      4185: 	}
1.318     albertel 4186:         $r->print('</td>'.&Apache::loncommon::end_data_table_row());
1.221     www      4187:     }
1.318     albertel 4188:     $r->print(&Apache::loncommon::end_data_table().
                   4189: 	      "\n<input type='submit' name='storerules' value='".
1.365     albertel 4190: 	      &mt('Save Rules')."' /></form>\n".
1.280     albertel 4191: 	      &Apache::loncommon::end_page());
1.220     www      4192:     return;
                   4193: }
1.193     albertel 4194: 
1.290     www      4195: sub components {
1.330     albertel 4196:     my ($key,$uname,$udom,$exeuser,$exedomain,$typeflag)=@_;
                   4197: 
                   4198:     if ($typeflag) {
1.290     www      4199: 	$key=~s/\.type$//;
                   4200:     }
1.330     albertel 4201: 
                   4202:     my ($middle,$part,$name)=
                   4203: 	($key=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s]+)\.(\w+)$/);
1.291     www      4204:     my $issection;
1.330     albertel 4205: 
1.290     www      4206:     my $section=&mt('All Students');
                   4207:     if ($middle=~/^\[(.*)\]/) {
1.291     www      4208: 	$issection=$1;
                   4209: 	$section=&mt('Group/Section').': '.$issection;
1.290     www      4210: 	$middle=~s/^\[(.*)\]//;
                   4211:     }
                   4212:     $middle=~s/\.+$//;
                   4213:     $middle=~s/^\.+//;
1.291     www      4214:     if ($uname) {
                   4215: 	$section=&mt('User').": ".&Apache::loncommon::plainname($uname,$udom);
                   4216: 	$issection='';
                   4217:     }
1.316     albertel 4218:     my $realm='<span class="LC_parm_scope_all">'.&mt('All Resources').'</span>';
1.304     www      4219:     my $realmdescription=&mt('all resources'); 
1.290     www      4220:     if ($middle=~/^(.+)\_\_\_\(all\)$/) {
1.316     albertel 4221: 	$realm='<span class="LC_parm_scope_folder">'.&mt('Folder/Map').': '.&Apache::lonnet::gettitle($1).' <span class="LC_parm_folder"><br />('.$1.')</span></span>';
1.304     www      4222:  	$realmdescription=&mt('folder').' '.&Apache::lonnet::gettitle($1);
                   4223:    } elsif ($middle) {
1.290     www      4224: 	my ($map,$id,$url)=&Apache::lonnet::decode_symb($middle);
1.316     albertel 4225: 	$realm='<span class="LC_parm_scope_resource">'.&mt('Resource').': '.&Apache::lonnet::gettitle($middle).' <br /><span class="LC_parm_symb">('.$url.' in '.$map.' id: '.$id.')</span></span>';
1.304     www      4226: 	$realmdescription=&mt('resource').' '.&Apache::lonnet::gettitle($middle);
1.290     www      4227:     }
1.291     www      4228:     my $what=$part.'.'.$name;
1.330     albertel 4229:     return ($realm,$section,$name,$part,
1.304     www      4230: 	    $what,$middle,$uname,$udom,$issection,$realmdescription);
1.290     www      4231: }
1.293     www      4232: 
1.328     albertel 4233: my %standard_parms;
                   4234: sub load_parameter_names {
                   4235:     open(my $config,"<$Apache::lonnet::perlvar{'lonTabDir'}/packages.tab");
                   4236:     while (my $configline=<$config>) {
                   4237: 	if ($configline !~ /\S/ || $configline=~/^\#/) { next; }
                   4238: 	chomp($configline);
                   4239: 	my ($short,$plain)=split(/:/,$configline);
                   4240: 	my (undef,$name,$type)=split(/\&/,$short,3);
                   4241: 	if ($type eq 'display') {
                   4242: 	    $standard_parms{$name} = $plain;
                   4243: 	}
                   4244:     }
                   4245:     close($config);
                   4246:     $standard_parms{'int_pos'}      = 'Positive Integer';
                   4247:     $standard_parms{'int_zero_pos'} = 'Positive Integer or Zero';
                   4248:     %standard_parms=&Apache::lonlocal::texthash(%standard_parms);	
                   4249: }
                   4250: 
1.292     www      4251: sub standard_parameter_names {
                   4252:     my ($name)=@_;
1.328     albertel 4253:     if (!%standard_parms) {
                   4254: 	&load_parameter_names();
                   4255:     }
1.292     www      4256:     if ($standard_parms{$name}) {
                   4257: 	return $standard_parms{$name}; 
                   4258:     } else { 
                   4259: 	return $name; 
                   4260:     }
                   4261: }
1.290     www      4262: 
1.309     www      4263: #
                   4264: # Parameter Change Log
                   4265: #
                   4266: 
                   4267: 
1.285     albertel 4268: sub parm_change_log {
1.284     www      4269:     my ($r)=@_;
1.327     albertel 4270:     $r->print(&Apache::loncommon::start_page('Parameter Change Log'));
                   4271:     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Parameter Change Log'));
                   4272: 
1.286     www      4273:     my %parmlog=&Apache::lonnet::dump('nohist_parameterlog',
                   4274: 				      $env{'course.'.$env{'request.course.id'}.'.domain'},
                   4275: 				      $env{'course.'.$env{'request.course.id'}.'.num'});
1.311     albertel 4276: 
1.301     www      4277:     if ((keys(%parmlog))[0]=~/^error\:/) { undef(%parmlog); }
1.311     albertel 4278: 
1.327     albertel 4279:     $r->print('<form action="/adm/parmset?action=parameterchangelog"
                   4280:                      method="post" name="parameterlog">');
1.311     albertel 4281:     
                   4282:     my %saveable_parameters = ('show' => 'scalar',);
                   4283:     &Apache::loncommon::store_course_settings('parameter_log',
                   4284:                                               \%saveable_parameters);
                   4285:     &Apache::loncommon::restore_course_settings('parameter_log',
                   4286:                                                 \%saveable_parameters);
1.348     www      4287:     $r->print(&Apache::loncommon::display_filter().
1.326     www      4288:               '<label>'.&Apache::lonhtmlcommon::checkbox('includetypes',$env{'form.includetypes'},'1').
                   4289: 	      ' '.&mt('Include parameter types').'</label>'.
1.327     albertel 4290: 	      '<input type="submit" value="'.&mt('Display').'" /></form>');
1.301     www      4291: 
1.291     www      4292:     my $courseopt=&Apache::lonnet::get_courseresdata($env{'course.'.$env{'request.course.id'}.'.num'},
                   4293: 						     $env{'course.'.$env{'request.course.id'}.'.domain'});
1.301     www      4294:     $r->print(&Apache::loncommon::start_data_table().&Apache::loncommon::start_data_table_header_row().
                   4295: 	      '<th>'.&mt('Time').'</th><th>'.&mt('User').'</th><th>'.&mt('Extent').'</th><th>'.&mt('Users').'</th><th>'.
                   4296: 	      &mt('Parameter').'</th><th>'.&mt('Part').'</th><th>'.&mt('New Value').'</th><th>'.&mt('Announce').'</th>'.
                   4297: 	      &Apache::loncommon::end_data_table_header_row());
1.309     www      4298:     my $shown=0;
1.349     www      4299:     my $folder='';
                   4300:     if ($env{'form.displayfilter'} eq 'currentfolder') {
                   4301: 	my $last='';
                   4302: 	if (tie(my %hash,'GDBM_File',$env{'request.course.fn'}.'_symb.db',
                   4303: 		&GDBM_READER(),0640)) {
                   4304: 	    $last=$hash{'last_known'};
                   4305: 	    untie(%hash);
                   4306: 	}
                   4307: 	if ($last) { ($folder) = &Apache::lonnet::decode_symb($last); }
                   4308:     }
1.356     albertel 4309:     foreach my $id (sort 
                   4310: 		    {
                   4311: 			if ($parmlog{$b}{'exe_time'} ne $parmlog{$a}{'exe_time'}) {
                   4312: 			    return $parmlog{$b}{'exe_time'} <=>$parmlog{$a}{'exe_time'}
                   4313: 			}
                   4314: 			my $aid = (split('00000',$a))[-1];
                   4315: 			my $bid = (split('00000',$b))[-1];
                   4316: 			return $bid<=>$aid;
                   4317: 		    } (keys(%parmlog))) {
1.294     www      4318:         my @changes=keys(%{$parmlog{$id}{'logentry'}});
1.332     albertel 4319: 	my $count = 0;
1.288     albertel 4320: 	my $time =
1.294     www      4321: 	    &Apache::lonlocal::locallocaltime($parmlog{$id}{'exe_time'});
1.289     www      4322: 	my $plainname = 
1.294     www      4323: 	    &Apache::loncommon::plainname($parmlog{$id}{'exe_uname'},
                   4324: 					  $parmlog{$id}{'exe_udom'});
1.288     albertel 4325: 	my $about_me_link = 
1.289     www      4326: 	    &Apache::loncommon::aboutmewrapper($plainname,
1.294     www      4327: 					       $parmlog{$id}{'exe_uname'},
                   4328: 					       $parmlog{$id}{'exe_udom'});
1.293     www      4329: 	my $send_msg_link='';
1.294     www      4330: 	if ((($parmlog{$id}{'exe_uname'} ne $env{'user.name'}) 
                   4331: 	     || ($parmlog{$id}{'exe_udom'} ne $env{'user.domain'}))) {
1.293     www      4332: 	    $send_msg_link ='<br />'.
1.288     albertel 4333: 		&Apache::loncommon::messagewrapper(&mt('Send message'),
1.294     www      4334: 						   $parmlog{$id}{'exe_uname'},
                   4335: 						   $parmlog{$id}{'exe_udom'});
1.288     albertel 4336: 	}
1.301     www      4337: 	my $row_start=&Apache::loncommon::start_data_table_row();
1.290     www      4338: 	my $makenewrow=0;
                   4339: 	my %istype=();
1.332     albertel 4340: 	my $output;
1.293     www      4341: 	foreach my $changed (reverse(sort(@changes))) {
1.330     albertel 4342:             my $value=$parmlog{$id}{'logentry'}{$changed};
1.331     albertel 4343: 	    my $typeflag = ($changed =~/\.type$/ &&
                   4344: 			    !exists($parmlog{$id}{'logentry'}{$changed.'.type'}));
1.330     albertel 4345:             my ($realm,$section,$parmname,$part,$what,$middle,$uname,$udom,$issection,$realmdescription)=
                   4346: 		&components($changed,$parmlog{$id}{'uname'},$parmlog{$id}{'udom'},undef,undef,$typeflag);
1.349     www      4347: 	    if ($env{'form.displayfilter'} eq 'currentfolder') {
                   4348: 		if ($folder) {
                   4349: 		    if ($middle!~/^\Q$folder\E/) { next; }
                   4350: 		}
                   4351: 	    }
1.326     www      4352: 	    if ($typeflag) {
1.329     albertel 4353: 		$istype{$parmname}=$value; 
1.326     www      4354: 		if (!$env{'form.includetypes'}) { next; } 
                   4355: 	    }
1.332     albertel 4356: 	    $count++;
                   4357: 	    if ($makenewrow) {
                   4358: 		$output .= $row_start;
                   4359: 	    } else {
                   4360: 		$makenewrow=1;
                   4361: 	    }
                   4362: 	    $output .='<td>'.$realm.'</td><td>'.$section.'</td><td>'.
1.292     www      4363: 		      &standard_parameter_names($parmname).'</td><td>'.
1.332     albertel 4364: 		      ($part?&mt('Part: [_1]',$part):&mt('All Parts')).'</td><td>';
1.291     www      4365: 	    my $stillactive=0;
1.332     albertel 4366: 	    if ($parmlog{$id}{'delflag'}) {
                   4367: 		$output .= &mt('Deleted');
1.288     albertel 4368: 	    } else {
1.290     www      4369: 		if ($typeflag) {
1.332     albertel 4370: 		    $output .= &mt('Type: [_1]',&standard_parameter_names($value));
1.290     www      4371: 		} else {
1.291     www      4372: 		    my ($level,@all)=&parmval_by_symb($what,$middle,&Apache::lonnet::metadata($middle,$what),
                   4373: 						      $uname,$udom,$issection,$issection,$courseopt);
                   4374: 		    if (&isdateparm($istype{$parmname})) {
1.332     albertel 4375: 			$output .= &Apache::lonlocal::locallocaltime($value);
1.291     www      4376: 		    } else {
1.332     albertel 4377: 			$output .= $value;
1.291     www      4378: 		    }
                   4379: 		    if ($value ne $all[$level]) {
1.332     albertel 4380: 			$output .= '<br /><span class="LC_warning">'.&mt('Not active anymore').'</span>';
1.291     www      4381: 		    } else {
                   4382: 			$stillactive=1;
                   4383: 		    }
1.290     www      4384: 		}
1.288     albertel 4385: 	    }
1.332     albertel 4386: 	    $output .= '</td><td>';
1.291     www      4387: 	    if ($stillactive) {
1.304     www      4388: 		my $title=&mt('Changed [_1]',&standard_parameter_names($parmname));
                   4389:                 my $description=&mt('Changed [_1] for [_2] to [_3]',&standard_parameter_names($parmname),$realmdescription,
                   4390: 				    (&isdateparm($istype{$parmname})?&Apache::lonlocal::locallocaltime($value):$value));
1.292     www      4391: 		if (($uname) && ($udom)) {
1.332     albertel 4392: 		    $output .= 
                   4393: 			&Apache::loncommon::messagewrapper('Notify User',
                   4394: 							   $uname,$udom,$title,
                   4395: 							   $description);
1.292     www      4396: 		} else {
1.332     albertel 4397: 		    $output .= 
                   4398: 			&Apache::lonrss::course_blog_link($id,$title,
                   4399: 							  $description);
1.292     www      4400: 		}
1.291     www      4401: 	    }
1.332     albertel 4402: 	    $output .= '</td>'.&Apache::loncommon::end_data_table_row();
1.288     albertel 4403: 	}
1.349     www      4404:         if ($env{'form.displayfilter'} eq 'containing') {
                   4405: 	    my $wholeentry=$about_me_link.':'.
                   4406: 		$parmlog{$id}{'exe_uname'}.':'.$parmlog{$id}{'exe_udom'}.':'.
                   4407: 		$output;
                   4408: 	    if ($wholeentry!~/\Q$env{'form.containingphrase'}\E/i) { next; }        
                   4409: 	}
                   4410:         if ($count) {
                   4411: 	    $r->print($row_start.'<td rowspan="'.$count.'">'.$time.'</td>
1.332     albertel 4412:                        <td rowspan="'.$count.'">'.$about_me_link.
                   4413: 		  '<br /><tt>'.$parmlog{$id}{'exe_uname'}.
                   4414: 			          ':'.$parmlog{$id}{'exe_udom'}.'</tt>'.
                   4415: 		  $send_msg_link.'</td>'.$output);
1.349     www      4416: 	    $shown++;
                   4417: 	}
1.311     albertel 4418: 	if (!($env{'form.show'} eq &mt('all') 
                   4419: 	      || $shown<=$env{'form.show'})) { last; }
1.286     www      4420:     }
1.301     www      4421:     $r->print(&Apache::loncommon::end_data_table());
1.284     www      4422:     $r->print(&Apache::loncommon::end_page());
                   4423: }
                   4424: 
1.355     albertel 4425: sub check_for_course_info {
                   4426:     my $navmap = Apache::lonnavmaps::navmap->new();
                   4427:     return 1 if ($navmap);
                   4428:     return 0;
                   4429: }
                   4430: 
1.178     raeburn  4431: ##################################################
                   4432: ##################################################
1.30      www      4433: 
1.59      matthew  4434: =pod
                   4435: 
1.83      bowersj2 4436: =item * handler
1.59      matthew  4437: 
                   4438: Main handler.  Calls &assessparms and &crsenv subroutines.
                   4439: 
                   4440: =cut
1.376     albertel 4441: 
1.59      matthew  4442: ##################################################
                   4443: ##################################################
1.259     banghart 4444: 
1.30      www      4445: sub handler {
1.43      albertel 4446:     my $r=shift;
1.30      www      4447: 
1.376     albertel 4448:     &reset_caches();
                   4449: 
1.43      albertel 4450:     if ($r->header_only) {
1.126     www      4451: 	&Apache::loncommon::content_type($r,'text/html');
1.43      albertel 4452: 	$r->send_http_header;
                   4453: 	return OK;
                   4454:     }
1.193     albertel 4455:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.205     www      4456: 					    ['action','state',
                   4457:                                              'pres_marker',
                   4458:                                              'pres_value',
1.206     www      4459:                                              'pres_type',
1.390     www      4460:                                              'udom','uname','symb','serial','timebase']);
1.131     www      4461: 
1.83      bowersj2 4462: 
1.193     albertel 4463:     &Apache::lonhtmlcommon::clear_breadcrumbs();
1.194     albertel 4464:     &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/parmset",
                   4465: 					    text=>"Parameter Manager",
1.204     www      4466: 					    faq=>10,
1.324     www      4467: 					    bug=>'Instructor Interface',
                   4468:                                             help => 'Parameter_Manager'});
1.203     www      4469: 
1.30      www      4470: # ----------------------------------------------------- Needs to be in a course
1.194     albertel 4471:     my $parm_permission =
                   4472: 	(&Apache::lonnet::allowed('opa',$env{'request.course.id'}) ||
1.190     albertel 4473: 	 &Apache::lonnet::allowed('opa',$env{'request.course.id'}.'/'.
1.193     albertel 4474: 				  $env{'request.course.sec'}));
1.355     albertel 4475:     my $exists = &check_for_course_info();
                   4476: 
                   4477:     if ($env{'request.course.id'} &&  $parm_permission && $exists) {
1.193     albertel 4478: 
                   4479:         # Start Page
1.126     www      4480:         &Apache::loncommon::content_type($r,'text/html');
1.106     www      4481:         $r->send_http_header;
1.30      www      4482: 
1.203     www      4483: 
1.193     albertel 4484:         #
                   4485:         # Main switch on form.action and form.state, as appropriate
                   4486:         #
                   4487:         # Check first if coming from someone else headed directly for
                   4488:         #  the table mode
                   4489:         if ((($env{'form.command'} eq 'set') && ($env{'form.url'})
                   4490: 	     && (!$env{'form.dis'})) || ($env{'form.symb'})) {
1.324     www      4491:             &Apache::lonhtmlcommon::add_breadcrumb({help=>'Problem_Parameters',
                   4492: 						    text=>"Problem Parameters"});
1.193     albertel 4493: 	    &assessparms($r);
                   4494: 
                   4495:         } elsif (! exists($env{'form.action'})) {
                   4496:             $r->print(&header());
1.298     albertel 4497:             $r->print(&Apache::lonhtmlcommon::breadcrumbs('Parameter Manager'));
1.193     albertel 4498:             &print_main_menu($r,$parm_permission);
                   4499:         } elsif ($env{'form.action'} eq 'crsenv' && $parm_permission) {
1.194     albertel 4500:             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=crsenv',
                   4501: 						    text=>"Course Environment"});
1.193     albertel 4502:             &crsenv($r); 
                   4503:         } elsif ($env{'form.action'} eq 'setoverview' && $parm_permission) {
1.194     albertel 4504:             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview',
                   4505: 						    text=>"Overview Mode"});
1.121     www      4506: 	    &overview($r);
1.334     banghart 4507: 	} elsif ($env{'form.action'} eq 'addmetadata' && $parm_permission) {
                   4508:             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=addmetadata',
                   4509: 						    text=>"Add Metadata Field"});
                   4510: 	    &addmetafield($r);
1.340     banghart 4511: 	} elsif ($env{'form.action'} eq 'ordermetadata' && $parm_permission) {
                   4512:             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=addmetadata',
                   4513: 						    text=>"Add Metadata Field"});
                   4514: 	    &order_meta_fields($r);
1.259     banghart 4515:         } elsif ($env{'form.action'} eq 'setrestrictmeta' && $parm_permission) {
                   4516:             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setrestrictmeta',
                   4517: 						    text=>"Restrict Metadata"});
                   4518: 	    &setrestrictmeta($r);
1.208     www      4519:         } elsif ($env{'form.action'} eq 'newoverview' && $parm_permission) {
                   4520:             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview',
                   4521: 						    text=>"Overview Mode"});
                   4522: 	    &newoverview($r);
1.220     www      4523:         }  elsif ($env{'form.action'} eq 'setdefaults' && $parm_permission) {
                   4524:             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setdefaults',
                   4525: 						    text=>"Set Defaults"});
                   4526: 	    &defaultsetter($r);
                   4527: 	} elsif ($env{'form.action'} eq 'settable' && $parm_permission) {
1.194     albertel 4528:             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=settable',
1.204     www      4529: 						    text=>"Table Mode",
                   4530: 						    help => 'Course_Setting_Parameters'});
1.121     www      4531: 	    &assessparms($r);
1.284     www      4532:         } elsif ($env{'form.action'} eq 'parameterchangelog' && $parm_permission) {
                   4533:             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=settable',
1.292     www      4534: 						    text=>"Parameter Change Log"});
1.285     albertel 4535: 	    &parm_change_log($r);
1.333     albertel 4536:         } elsif ($env{'form.action'} eq 'cleanparameters' && $parm_permission) {
                   4537:             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=cleanparameters',
                   4538: 						    text=>"Clean Parameters"});
                   4539: 	    &clean_parameters($r);
1.390     www      4540:         } elsif ($env{'form.action'} eq 'dateshift1' && $parm_permission) {
                   4541:             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=dateshift1&timebase='.$env{'form.timebase'},
1.391     www      4542:                                                     text=>"Shifting Dates"});
1.390     www      4543:             &date_shift_one($r);
                   4544:         } elsif ($env{'form.action'} eq 'dateshift2' && $parm_permission) {
                   4545:             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=dateshift1&timebase='.$env{'form.timebase'},
1.391     www      4546:                                                     text=>"Shifting Dates"});
1.390     www      4547:             &date_shift_two($r);
1.403     raeburn  4548: 	} elsif ($env{'form.action'} eq 'categorizecourse' && $parm_permission) {
                   4549:             &assign_course_categories($r);
                   4550:         } 
1.43      albertel 4551:     } else {
1.1       www      4552: # ----------------------------- Not in a course, or not allowed to modify parms
1.355     albertel 4553: 	if ($exists) {
                   4554: 	    $env{'user.error.msg'}=
                   4555: 		"/adm/parmset:opa:0:0:Cannot modify assessment parameters";
                   4556: 	} else {
                   4557: 	    $env{'user.error.msg'}=
                   4558: 		"/adm/parmset::0:1:Course environment gone, reinitialize the course";
                   4559: 	}
1.43      albertel 4560: 	return HTTP_NOT_ACCEPTABLE;
                   4561:     }
1.376     albertel 4562:     &reset_caches();
                   4563: 
1.43      albertel 4564:     return OK;
1.1       www      4565: }
                   4566: 
                   4567: 1;
                   4568: __END__
                   4569: 
1.59      matthew  4570: =pod
1.38      harris41 4571: 
                   4572: =back
                   4573: 
                   4574: =cut
1.1       www      4575: 
                   4576: 
                   4577: 

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