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

1.1       www         1: # The LearningOnline Network with CAPA
                      2: # Handler to set parameters for assessments
                      3: #
1.304   ! www         4: # $Id: lonparmset.pm,v 1.303 2006/05/11 17:38:44 www 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.303     www        66: use Apache::lonrss;
1.1       www        67: 
1.198     www        68: # --- Caches local to lonparmset
1.2       www        69: 
1.199     www        70: my $parmhashid;
                     71: my %parmhash;
1.201     www        72: my $symbsid;
                     73: my %symbs;
1.221     www        74: my $rulesid;
                     75: my %rules;
1.198     www        76: 
                     77: # --- end local caches
                     78: 
1.59      matthew    79: ##################################################
                     80: ##################################################
                     81: 
                     82: =pod
                     83: 
                     84: =item parmval
                     85: 
                     86: Figure out a cascading parameter.
                     87: 
1.71      albertel   88: Inputs:  $what - a parameter spec (incluse part info and name I.E. 0.weight)
1.162     albertel   89:          $id   - a bighash Id number
1.71      albertel   90:          $def  - the resource's default value   'stupid emacs
                     91: 
1.269     raeburn    92: 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   93: 
1.269     raeburn    94: 14 - General Course
                     95: 13 - Map or Folder level in course
                     96: 12- resource default
                     97: 11- map default
                     98: 10 - resource level in course
                     99: 9 - General for section
                    100: 8 - Map or Folder level for section
                    101: 7 - resource level in section
                    102: 6 - General for group
                    103: 5 - Map or Folder level for group
                    104: 4 - resource level in group
1.71      albertel  105: 3 - General for specific student
1.82      www       106: 2 - Map or Folder level for specific student
1.71      albertel  107: 1 - resource level for specific student
1.2       www       108: 
1.59      matthew   109: =cut
                    110: 
                    111: ##################################################
1.2       www       112: sub parmval {
1.275     raeburn   113:     my ($what,$id,$def,$uname,$udom,$csec,$cgroup,$courseopt)=@_;
                    114:     return &parmval_by_symb($what,&symbcache($id),$def,$uname,$udom,$csec,
                    115:                                                            $cgroup,$courseopt);
1.201     www       116: }
                    117: 
                    118: sub parmval_by_symb {
1.275     raeburn   119:     my ($what,$symb,$def,$uname,$udom,$csec,$cgroup,$courseopt)=@_;
1.198     www       120: # load caches
                    121:     &cacheparmhash();
1.200     www       122: 
                    123:     my $useropt=&Apache::lonnet::get_userresdata($uname,$udom);
                    124: 
1.8       www       125:     my $result='';
1.44      albertel  126:     my @outpar=();
1.2       www       127: # ----------------------------------------------------- Cascading lookup scheme
1.201     www       128:     my $map=(&Apache::lonnet::decode_symb($symb))[0];    
1.10      www       129: 
1.201     www       130:     my $symbparm=$symb.'.'.$what;
                    131:     my $mapparm=$map.'___(all).'.$what;
1.10      www       132: 
1.269     raeburn   133:     my $grplevel=$env{'request.course.id'}.'.['.$cgroup.'].'.$what;
                    134:     my $grplevelr=$env{'request.course.id'}.'.['.$cgroup.'].'.$symbparm;
                    135:     my $grplevelm=$env{'request.course.id'}.'.['.$cgroup.'].'.$mapparm;
                    136: 
1.190     albertel  137:     my $seclevel=$env{'request.course.id'}.'.['.$csec.'].'.$what;
                    138:     my $seclevelr=$env{'request.course.id'}.'.['.$csec.'].'.$symbparm;
                    139:     my $seclevelm=$env{'request.course.id'}.'.['.$csec.'].'.$mapparm;
                    140: 
                    141:     my $courselevel=$env{'request.course.id'}.'.'.$what;
                    142:     my $courselevelr=$env{'request.course.id'}.'.'.$symbparm;
                    143:     my $courselevelm=$env{'request.course.id'}.'.'.$mapparm;
1.2       www       144: 
1.11      www       145: 
1.182     albertel  146: # --------------------------------------------------------- first, check course
1.11      www       147: 
1.200     www       148:     if (defined($$courseopt{$courselevel})) {
1.269     raeburn   149: 	$outpar[14]=$$courseopt{$courselevel};
                    150: 	$result=14;
1.43      albertel  151:     }
1.11      www       152: 
1.200     www       153:     if (defined($$courseopt{$courselevelm})) {
1.269     raeburn   154: 	$outpar[13]=$$courseopt{$courselevelm};
                    155: 	$result=13;
1.43      albertel  156:     }
1.11      www       157: 
1.182     albertel  158: # ------------------------------------------------------- second, check default
                    159: 
1.269     raeburn   160:     if (defined($def)) { $outpar[12]=$def; $result=12; }
1.182     albertel  161: 
                    162: # ------------------------------------------------------ third, check map parms
                    163: 
                    164:     my $thisparm=$parmhash{$symbparm};
1.269     raeburn   165:     if (defined($thisparm)) { $outpar[11]=$thisparm; $result=11; }
1.182     albertel  166: 
1.200     www       167:     if (defined($$courseopt{$courselevelr})) {
1.269     raeburn   168: 	$outpar[10]=$$courseopt{$courselevelr};
                    169: 	$result=10;
1.43      albertel  170:     }
1.11      www       171: 
1.182     albertel  172: # ------------------------------------------------------ fourth, back to course
1.71      albertel  173:     if (defined($csec)) {
1.200     www       174:         if (defined($$courseopt{$seclevel})) {
1.269     raeburn   175: 	    $outpar[9]=$$courseopt{$seclevel};
                    176: 	    $result=9;
1.43      albertel  177: 	}
1.200     www       178:         if (defined($$courseopt{$seclevelm})) {
1.269     raeburn   179: 	    $outpar[8]=$$courseopt{$seclevelm};
                    180: 	    $result=8;
1.43      albertel  181: 	}
                    182: 
1.200     www       183:         if (defined($$courseopt{$seclevelr})) {
1.269     raeburn   184: 	    $outpar[7]=$$courseopt{$seclevelr};
                    185: 	    $result=7;
1.43      albertel  186: 	}
                    187:     }
1.275     raeburn   188: # ------------------------------------------------------ fifth, check course group
1.269     raeburn   189:     if (defined($cgroup)) {
                    190:         if (defined($$courseopt{$grplevel})) {
                    191:             $outpar[6]=$$courseopt{$grplevel};
                    192:             $result=6;
                    193:         }
                    194:         if (defined($$courseopt{$grplevelm})) {
                    195:             $outpar[5]=$$courseopt{$grplevelm};
                    196:             $result=5;
                    197:         }
                    198:         if (defined($$courseopt{$grplevelr})) {
                    199:             $outpar[4]=$$courseopt{$grplevelr};
                    200:             $result=4;
                    201:         }
                    202:     }
1.11      www       203: 
1.182     albertel  204: # ---------------------------------------------------------- fifth, check user
1.11      www       205: 
1.71      albertel  206:     if (defined($uname)) {
1.200     www       207: 	if (defined($$useropt{$courselevel})) {
                    208: 	    $outpar[3]=$$useropt{$courselevel};
1.43      albertel  209: 	    $result=3;
                    210: 	}
1.10      www       211: 
1.200     www       212: 	if (defined($$useropt{$courselevelm})) {
                    213: 	    $outpar[2]=$$useropt{$courselevelm};
1.43      albertel  214: 	    $result=2;
                    215: 	}
1.2       www       216: 
1.200     www       217: 	if (defined($$useropt{$courselevelr})) {
                    218: 	    $outpar[1]=$$useropt{$courselevelr};
1.43      albertel  219: 	    $result=1;
                    220: 	}
                    221:     }
1.44      albertel  222:     return ($result,@outpar);
1.2       www       223: }
                    224: 
1.198     www       225: sub resetparmhash {
                    226:     $parmhashid='';
                    227: }
                    228: 
                    229: sub cacheparmhash {
                    230:     if ($parmhashid eq  $env{'request.course.fn'}) { return; }
                    231:     my %parmhashfile;
                    232:     if (tie(%parmhashfile,'GDBM_File',
                    233: 	      $env{'request.course.fn'}.'_parms.db',&GDBM_READER(),0640)) {
                    234: 	%parmhash=%parmhashfile;
                    235: 	untie %parmhashfile;
                    236: 	$parmhashid=$env{'request.course.fn'};
                    237:     }
                    238: }
                    239: 
1.203     www       240: sub resetsymbcache {
                    241:     $symbsid='';
                    242: }
                    243: 
1.201     www       244: sub symbcache {
                    245:     my $id=shift;
                    246:     if ($symbsid ne $env{'request.course.id'}) {
                    247: 	%symbs=();
                    248:     }
                    249:     unless ($symbs{$id}) {
                    250: 	my $navmap = Apache::lonnavmaps::navmap->new();
                    251: 	if ($id=~/\./) {
                    252: 	    my $resource=$navmap->getById($id);
                    253: 	    $symbs{$id}=$resource->symb();
                    254: 	} else {
                    255: 	    my $resource=$navmap->getByMapPc($id);
                    256: 	    $symbs{$id}=&Apache::lonnet::declutter($resource->src());
                    257: 	}
                    258: 	$symbsid=$env{'request.course.id'};
                    259:     }
                    260:     return $symbs{$id};
                    261: }
                    262: 
1.221     www       263: sub resetrulescache {
                    264:     $rulesid='';
                    265: }
                    266: 
                    267: sub rulescache {
                    268:     my $id=shift;
                    269:     if ($rulesid ne $env{'request.course.id'}) {
                    270: 	%rules=();
                    271:     }
1.224     www       272:     unless (defined($rules{$id})) {
1.221     www       273: 	my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                    274: 	my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.224     www       275: 	%rules=&Apache::lonnet::dump('parmdefactions',$dom,$crs);
1.221     www       276: 	$rulesid=$env{'request.course.id'};
                    277:     }
                    278:     return $rules{$id};
                    279: }
                    280: 
1.229     www       281: sub preset_defaults {
                    282:     my $type=shift;
                    283:     if (&rulescache($type.'_action') eq 'default') {
                    284: # yes, there is something
                    285: 	return (&rulescache($type.'_hours'),
                    286: 		&rulescache($type.'_min'),
                    287: 		&rulescache($type.'_sec'),
                    288: 		&rulescache($type.'_value'));
                    289:     } else {
                    290: # nothing there or something else
                    291: 	return ('','','','','');
                    292:     }
                    293: }
                    294: 
1.186     www       295: ##################################################
1.277     www       296: 
                    297: sub date_sanity_info {
                    298:    my $checkdate=shift;
                    299:    unless ($checkdate) { return ''; }
                    300:    my $result='';
                    301:    my $crsprefix='course.'.$env{'request.course.id'}.'.';
                    302:    if ($env{$crsprefix.'default_enrollment_end_date'}) {
                    303:       if ($checkdate>$env{$crsprefix.'default_enrollment_end_date'}) {
                    304:          $result.='<br />'.&mt('After course enrollment end!');
                    305:       }
                    306:    }
                    307:    if ($env{$crsprefix.'default_enrollment_start_date'}) {
                    308:       if ($checkdate<$env{$crsprefix.'default_enrollment_start_date'}) {
                    309:          $result.='<br />'.&mt('Before course enrollment start!');
                    310:       }
                    311:    }
                    312:    return $result;
                    313: }
                    314: ##################################################
1.186     www       315: ##################################################
                    316: #
1.197     www       317: # Store a parameter by ID
1.186     www       318: #
                    319: # Takes
                    320: # - resource id
                    321: # - name of parameter
                    322: # - level
                    323: # - new value
                    324: # - new type
1.187     www       325: # - username
                    326: # - userdomain
                    327: 
1.186     www       328: sub storeparm {
1.269     raeburn   329:     my ($sresid,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$cgroup)=@_;
1.275     raeburn   330:     &storeparm_by_symb(&symbcache($sresid),$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,'',$cgroup);
1.197     www       331: }
                    332: 
                    333: #
                    334: # Store a parameter by symb
                    335: #
                    336: # Takes
                    337: # - symb
                    338: # - name of parameter
                    339: # - level
                    340: # - new value
                    341: # - new type
                    342: # - username
                    343: # - userdomain
                    344: 
1.226     www       345: my %recstack;
1.197     www       346: sub storeparm_by_symb {
1.275     raeburn   347:     my ($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$recflag,$cgroup)=@_;
1.226     www       348:     unless ($recflag) {
                    349: # first time call
                    350: 	%recstack=();
                    351: 	$recflag=1;
                    352:     }
                    353: # store parameter
                    354:     &storeparm_by_symb_inner
1.269     raeburn   355: 	($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$cgroup);
1.266     www       356: # don't do anything if parameter was reset
                    357:     unless ($nval) { return; }
1.226     www       358:     my ($prefix,$parm)=($spnam=~/^(.*[\_\.])([^\_\.]+)$/);
                    359: # remember that this was set
                    360:     $recstack{$parm}=1;
                    361: # what does this trigger?
                    362:     foreach my $triggered (split(/\:/,&rulescache($parm.'_triggers'))) {
                    363: # don't backfire
                    364:        unless ((!$triggered) || ($recstack{$triggered})) {
                    365: 	   my $action=&rulescache($triggered.'_action');
                    366: 	   my ($whichaction,$whichparm)=($action=~/^(.*\_)([^\_]+)$/);
                    367: # set triggered parameter on same level
                    368: 	   my $newspnam=$prefix.$triggered;
1.227     www       369: 	   my $newvalue='';
1.228     www       370: 	   my $active=1;
                    371: 	   if ($action=~/^when\_setting/) {
                    372: # are there restrictions?
                    373: 	       if (&rulescache($triggered.'_triggervalue')=~/\w/) {
                    374: 		   $active=0;
                    375: 		   foreach my $possiblevalue (split(/\s*\,\s*/,&rulescache($triggered.'_triggervalue'))) {
                    376: 		       if (lc($possiblevalue) eq lc($nval)) { $active=1; }
                    377: 		   }
                    378: 	       }
                    379: 	       $newvalue=&rulescache($triggered.'_value');
1.227     www       380: 	   } else {
                    381: 	       my $totalsecs=((&rulescache($triggered.'_days')*24+&rulescache($triggered.'_hours'))*60+&rulescache($triggered.'_min'))*60+&rulescache($triggered.'_sec');
1.228     www       382: 	       if ($action=~/^later\_than/) {
                    383: 		   $newvalue=$nval+$totalsecs;
                    384: 	       } else {
                    385: 		   $newvalue=$nval-$totalsecs;
                    386: 	       }
                    387: 	   }
                    388: 	   if ($active) {
                    389: 	       &storeparm_by_symb($symb,$newspnam,$snum,$newvalue,&rulescache($triggered.'_type'),
1.275     raeburn   390: 				   $uname,$udom,$csec,$recflag,$cgroup);
1.227     www       391: 	   }
1.226     www       392:        }
                    393:     }
                    394:     return '';
                    395: }
                    396: 
1.293     www       397: sub log_parmset {
                    398:     return &Apache::lonnet::instructor_log('parameterlog',@_);
1.284     www       399: }
                    400: 
1.226     www       401: sub storeparm_by_symb_inner {
1.197     www       402: # ---------------------------------------------------------- Get symb, map, etc
1.269     raeburn   403:     my ($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$cgroup)=@_;
1.197     www       404: # ---------------------------------------------------------- Construct prefixes
1.186     www       405:     $spnam=~s/\_([^\_]+)$/\.$1/;
1.197     www       406:     my $map=(&Apache::lonnet::decode_symb($symb))[0];    
                    407:     my $symbparm=$symb.'.'.$spnam;
                    408:     my $mapparm=$map.'___(all).'.$spnam;
                    409: 
1.269     raeburn   410:     my $grplevel=$env{'request.course.id'}.'.['.$cgroup.'].'.$spnam;
                    411:     my $grplevelr=$env{'request.course.id'}.'.['.$cgroup.'].'.$symbparm;
                    412:     my $grplevelm=$env{'request.course.id'}.'.['.$cgroup.'].'.$mapparm;
                    413: 
1.190     albertel  414:     my $seclevel=$env{'request.course.id'}.'.['.$csec.'].'.$spnam;
                    415:     my $seclevelr=$env{'request.course.id'}.'.['.$csec.'].'.$symbparm;
                    416:     my $seclevelm=$env{'request.course.id'}.'.['.$csec.'].'.$mapparm;
1.186     www       417:     
1.190     albertel  418:     my $courselevel=$env{'request.course.id'}.'.'.$spnam;
                    419:     my $courselevelr=$env{'request.course.id'}.'.'.$symbparm;
                    420:     my $courselevelm=$env{'request.course.id'}.'.'.$mapparm;
1.186     www       421:     
                    422:     my $storeunder='';
1.269     raeburn   423:     if (($snum==14) || ($snum==3)) { $storeunder=$courselevel; }
                    424:     if (($snum==13) || ($snum==2)) { $storeunder=$courselevelm; }
                    425:     if (($snum==10) || ($snum==1)) { $storeunder=$courselevelr; }
                    426:     if ($snum==9) { $storeunder=$seclevel; }
                    427:     if ($snum==8) { $storeunder=$seclevelm; }
                    428:     if ($snum==7) { $storeunder=$seclevelr; }
                    429:     if ($snum==6) { $storeunder=$grplevel; }
                    430:     if ($snum==5) { $storeunder=$grplevelm; }
                    431:     if ($snum==4) { $storeunder=$grplevelr; }
                    432: 
1.186     www       433:     
                    434:     my $delete;
                    435:     if ($nval eq '') { $delete=1;}
                    436:     my %storecontent = ($storeunder         => $nval,
                    437: 			$storeunder.'.type' => $ntype);
                    438:     my $reply='';
                    439:     if ($snum>3) {
                    440: # ---------------------------------------------------------------- Store Course
                    441: #
1.200     www       442: 	my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                    443: 	my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
1.186     www       444: # Expire sheets
                    445: 	&Apache::lonnet::expirespread('','','studentcalc');
1.269     raeburn   446: 	if (($snum==10) || ($snum==7) || ($snum==4)) {
1.197     www       447: 	    &Apache::lonnet::expirespread('','','assesscalc',$symb);
1.269     raeburn   448: 	} elsif (($snum==11) || ($snum==8) || ($snum==5)) {
1.197     www       449: 	    &Apache::lonnet::expirespread('','','assesscalc',$map);
1.186     www       450: 	} else {
                    451: 	    &Apache::lonnet::expirespread('','','assesscalc');
                    452: 	}
                    453: # Store parameter
                    454: 	if ($delete) {
                    455: 	    $reply=&Apache::lonnet::del
1.200     www       456: 		('resourcedata',[keys(%storecontent)],$cdom,$cnum);
1.290     www       457:             &log_parmset(\%storecontent,1);
1.186     www       458: 	} else {
                    459: 	    $reply=&Apache::lonnet::cput
1.200     www       460: 		('resourcedata',\%storecontent,$cdom,$cnum);
1.290     www       461: 	    &log_parmset(\%storecontent);
1.186     www       462: 	}
1.200     www       463: 	&Apache::lonnet::devalidatecourseresdata($cnum,$cdom);
1.186     www       464:     } else {
                    465: # ------------------------------------------------------------------ Store User
                    466: #
                    467: # Expire sheets
                    468: 	&Apache::lonnet::expirespread($uname,$udom,'studentcalc');
                    469: 	if ($snum==1) {
                    470: 	    &Apache::lonnet::expirespread
1.197     www       471: 		($uname,$udom,'assesscalc',$symb);
1.186     www       472: 	} elsif ($snum==2) {
                    473: 	    &Apache::lonnet::expirespread
1.197     www       474: 		($uname,$udom,'assesscalc',$map);
1.186     www       475: 	} else {
                    476: 	    &Apache::lonnet::expirespread($uname,$udom,'assesscalc');
                    477: 	}
                    478: # Store parameter
                    479: 	if ($delete) {
                    480: 	    $reply=&Apache::lonnet::del
                    481: 		('resourcedata',[keys(%storecontent)],$udom,$uname);
1.290     www       482: 	    &log_parmset(\%storecontent,1,$uname,$udom);
1.186     www       483: 	} else {
                    484: 	    $reply=&Apache::lonnet::cput
                    485: 		('resourcedata',\%storecontent,$udom,$uname);
1.290     www       486: 	    &log_parmset(\%storecontent,0,$uname,$udom);
1.186     www       487: 	}
1.191     albertel  488: 	&Apache::lonnet::devalidateuserresdata($uname,$udom);
1.186     www       489:     }
                    490:     
                    491:     if ($reply=~/^error\:(.*)/) {
                    492: 	return "<font color=red>Write Error: $1</font>";
                    493:     }
                    494:     return '';
                    495: }
                    496: 
1.59      matthew   497: ##################################################
                    498: ##################################################
                    499: 
                    500: =pod
                    501: 
                    502: =item valout
                    503: 
                    504: Format a value for output.
                    505: 
                    506: Inputs:  $value, $type
                    507: 
                    508: Returns: $value, formatted for output.  If $type indicates it is a date,
                    509: localtime($value) is returned.
1.9       www       510: 
1.59      matthew   511: =cut
                    512: 
                    513: ##################################################
                    514: ##################################################
1.9       www       515: sub valout {
                    516:     my ($value,$type)=@_;
1.59      matthew   517:     my $result = '';
                    518:     # Values of zero are valid.
                    519:     if (! $value && $value ne '0') {
1.71      albertel  520: 	$result = '&nbsp;&nbsp;';
1.59      matthew   521:     } else {
1.66      www       522:         if ($type eq 'date_interval') {
                    523:             my ($sec,$min,$hour,$mday,$mon,$year)=gmtime($value);
                    524:             $year=$year-70;
                    525:             $mday--;
                    526:             if ($year) {
                    527: 		$result.=$year.' yrs ';
                    528:             }
                    529:             if ($mon) {
                    530: 		$result.=$mon.' mths ';
                    531:             }
                    532:             if ($mday) {
                    533: 		$result.=$mday.' days ';
                    534:             }
                    535:             if ($hour) {
                    536: 		$result.=$hour.' hrs ';
                    537:             }
                    538:             if ($min) {
                    539: 		$result.=$min.' mins ';
                    540:             }
                    541:             if ($sec) {
                    542: 		$result.=$sec.' secs ';
                    543:             }
                    544:             $result=~s/\s+$//;
1.213     www       545:         } elsif (&isdateparm($type)) {
1.277     www       546:             $result = localtime($value).&date_sanity_info($value);
1.59      matthew   547:         } else {
                    548:             $result = $value;
                    549:         }
                    550:     }
                    551:     return $result;
1.9       www       552: }
                    553: 
1.59      matthew   554: ##################################################
                    555: ##################################################
                    556: 
                    557: =pod
1.5       www       558: 
1.59      matthew   559: =item plink
                    560: 
                    561: Produces a link anchor.
                    562: 
                    563: Inputs: $type,$dis,$value,$marker,$return,$call
                    564: 
                    565: Returns: scalar with html code for a link which will envoke the 
                    566: javascript function 'pjump'.
                    567: 
                    568: =cut
                    569: 
                    570: ##################################################
                    571: ##################################################
1.5       www       572: sub plink {
                    573:     my ($type,$dis,$value,$marker,$return,$call)=@_;
1.23      www       574:     my $winvalue=$value;
                    575:     unless ($winvalue) {
1.213     www       576: 	if (&isdateparm($type)) {
1.190     albertel  577:             $winvalue=$env{'form.recent_'.$type};
1.23      www       578:         } else {
1.190     albertel  579:             $winvalue=$env{'form.recent_'.(split(/\_/,$type))[0]};
1.23      www       580:         }
                    581:     }
1.229     www       582:     my ($parmname)=((split(/\&/,$marker))[1]=~/\_([^\_]+)$/);
                    583:     my ($hour,$min,$sec,$val)=&preset_defaults($parmname);
                    584:     unless (defined($winvalue)) { $winvalue=$val; }
1.270     www       585:     return '<table width="100%"><tr valign="top" align="right"><td><a name="'.$marker.'" /></td></tr><tr><td align="center">'.
1.43      albertel  586: 	'<a href="javascript:pjump('."'".$type."','".$dis."','".$winvalue."','"
1.229     www       587: 	    .$marker."','".$return."','".$call."','".$hour."','".$min."','".$sec."'".');">'.
1.270     www       588: 		&valout($value,$type).'</a></td></tr></table>';
1.5       www       589: }
                    590: 
1.280     albertel  591: sub page_js {
                    592: 
1.81      www       593:     my $selscript=&Apache::loncommon::studentbrowser_javascript();
1.88      matthew   594:     my $pjump_def = &Apache::lonhtmlcommon::pjump_javascript_definition();
1.280     albertel  595: 
                    596:     return(<<ENDJS);
                    597: <script type="text/javascript">
1.44      albertel  598: 
                    599:     function pclose() {
                    600:         parmwin=window.open("/adm/rat/empty.html","LONCAPAparms",
                    601:                  "height=350,width=350,scrollbars=no,menubar=no");
                    602:         parmwin.close();
                    603:     }
                    604: 
1.88      matthew   605:     $pjump_def
1.44      albertel  606: 
                    607:     function psub() {
                    608:         pclose();
                    609:         if (document.parmform.pres_marker.value!='') {
                    610:             document.parmform.action+='#'+document.parmform.pres_marker.value;
                    611:             var typedef=new Array();
                    612:             typedef=document.parmform.pres_type.value.split('_');
                    613:            if (document.parmform.pres_type.value!='') {
                    614:             if (typedef[0]=='date') {
                    615:                 eval('document.parmform.recent_'+
                    616:                      document.parmform.pres_type.value+
                    617: 		     '.value=document.parmform.pres_value.value;');
                    618:             } else {
                    619:                 eval('document.parmform.recent_'+typedef[0]+
                    620: 		     '.value=document.parmform.pres_value.value;');
                    621:             }
                    622: 	   }
                    623:             document.parmform.submit();
                    624:         } else {
                    625:             document.parmform.pres_value.value='';
                    626:             document.parmform.pres_marker.value='';
                    627:         }
                    628:     }
                    629: 
1.57      albertel  630:     function openWindow(url, wdwName, w, h, toolbar,scrollbar) {
                    631:         var options = "width=" + w + ",height=" + h + ",";
                    632:         options += "resizable=yes,scrollbars="+scrollbar+",status=no,";
                    633:         options += "menubar=no,toolbar="+toolbar+",location=no,directories=no";
                    634:         var newWin = window.open(url, wdwName, options);
                    635:         newWin.focus();
                    636:     }
1.44      albertel  637: </script>
1.81      www       638: $selscript
1.280     albertel  639: ENDJS
                    640: 
                    641: }
                    642: sub startpage {
                    643:     my ($r) = @_;
1.281     albertel  644: 
1.282     albertel  645:     my %loaditems = ('onunload' => "pclose()",
1.283     albertel  646: 		     'onload'   => "group_or_section('cgroup')",);
1.280     albertel  647: 
1.281     albertel  648:     my $start_page = 
                    649: 	&Apache::loncommon::start_page('Set/Modify Course Parameters',
                    650: 				       &page_js(),
1.282     albertel  651: 				       {'add_entries' => \%loaditems,});
1.280     albertel  652:     my $breadcrumbs = 
1.298     albertel  653: 	&Apache::lonhtmlcommon::breadcrumbs('Table Mode Parameter Setting');
1.280     albertel  654:     $r->print(<<ENDHEAD);
1.281     albertel  655: $start_page
1.193     albertel  656: $breadcrumbs
                    657: <form method="post" action="/adm/parmset?action=settable" name="parmform">
1.280     albertel  658: <input type="hidden" value='' name="pres_value" />
                    659: <input type="hidden" value='' name="pres_type" />
                    660: <input type="hidden" value='' name="pres_marker" />
                    661: <input type="hidden" value='1' name="prevvisit" />
1.44      albertel  662: ENDHEAD
                    663: }
                    664: 
1.209     www       665: 
1.44      albertel  666: sub print_row {
1.201     www       667:     my ($r,$which,$part,$name,$symbp,$rid,$default,$defaulttype,$display,$defbgone,
1.275     raeburn   668: 	$defbgtwo,$defbgthree,$parmlev,$uname,$udom,$csec,$cgroup,$usersgroups)=@_;
                    669:     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                    670:     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                    671:     my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom);
1.66      www       672: # get the values for the parameter in cascading order
                    673: # empty levels will remain empty
1.44      albertel  674:     my ($result,@outpar)=&parmval($$part{$which}.'.'.$$name{$which},
1.275     raeburn   675: 	  $rid,$$default{$which},$uname,$udom,$csec,$cgroup,$courseopt);
1.66      www       676: # get the type for the parameters
                    677: # problem: these may not be set for all levels
                    678:     my ($typeresult,@typeoutpar)=&parmval($$part{$which}.'.'.
1.275     raeburn   679:                                           $$name{$which}.'.type',$rid,
                    680: 		 $$defaulttype{$which},$uname,$udom,$csec,$cgroup,$courseopt);
1.66      www       681: # cascade down manually
1.182     albertel  682:     my $cascadetype=$$defaulttype{$which};
1.269     raeburn   683:     for (my $i=14;$i>0;$i--) {
1.66      www       684: 	 if ($typeoutpar[$i]) { 
                    685:             $cascadetype=$typeoutpar[$i];
                    686: 	} else {
                    687:             $typeoutpar[$i]=$cascadetype;
                    688:         }
                    689:     }
1.57      albertel  690:     my $parm=$$display{$which};
                    691: 
1.203     www       692:     if ($parmlev eq 'full') {
1.57      albertel  693:         $r->print('<td bgcolor='.$defbgtwo.' align="center">'
                    694:                   .$$part{$which}.'</td>');
                    695:     } else {    
                    696:         $parm=~s|\[.*\]\s||g;
                    697:     }
1.231     www       698:     my $automatic=&rulescache(($which=~/\_([^\_]+)$/)[0].'_triggers');
                    699:     if ($automatic) {
                    700: 	$parm.='<font color="red"><br />'.&mt('Automatically sets').' '.join(', ',split(/\:/,$automatic)).'</font>';
                    701:     }
1.159     albertel  702:     $r->print('<td bgcolor='.$defbgone.'>'.$parm.'</td>');
1.57      albertel  703:    
1.44      albertel  704:     my $thismarker=$which;
                    705:     $thismarker=~s/^parameter\_//;
                    706:     my $mprefix=$rid.'&'.$thismarker.'&';
1.275     raeburn   707:     my $effective_parm = &valout($outpar[$result],$typeoutpar[$result]);
                    708:     my ($othergrp,$grp_parm,$controlgrp);
1.44      albertel  709: 
1.57      albertel  710:     if ($parmlev eq 'general') {
                    711: 
                    712:         if ($uname) {
1.66      www       713:             &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
1.269     raeburn   714:         } elsif ($cgroup) {
                    715:             &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
1.57      albertel  716:         } elsif ($csec) {
1.269     raeburn   717:             &print_td($r,9,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); 
1.57      albertel  718:         } else {
1.269     raeburn   719:             &print_td($r,14,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); 
1.57      albertel  720:         }
                    721:     } elsif ($parmlev eq 'map') {
                    722: 
                    723:         if ($uname) {
1.66      www       724:             &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
1.269     raeburn   725:         } elsif ($cgroup) {
                    726:             &print_td($r,5,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
1.57      albertel  727:         } elsif ($csec) {
1.269     raeburn   728:             &print_td($r,8,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
1.57      albertel  729:         } else {
1.269     raeburn   730:             &print_td($r,13,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
1.57      albertel  731:         }
                    732:     } else {
1.275     raeburn   733:         if ($uname) {
                    734:             if (@{$usersgroups} > 1) {
                    735:                 my ($coursereply,$grp_parm,$controlgrp);
                    736:                 ($coursereply,$othergrp,$grp_parm,$controlgrp) =
                    737:                     &print_usergroups($r,$$part{$which}.'.'.$$name{$which},
                    738:                        $rid,$cgroup,$defbgone,$usersgroups,$result,$courseopt);
                    739:                 if ($coursereply && $result > 3) {
                    740:                     if (defined($controlgrp)) {
                    741:                         if ($cgroup ne $controlgrp) {
                    742:                             $effective_parm = $grp_parm;
                    743:                             $result = 0;
                    744:                         }
                    745:                     }
                    746:                 }
                    747:             }
                    748:         }
1.57      albertel  749: 
1.269     raeburn   750:         &print_td($r,14,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
1.57      albertel  751: 
1.269     raeburn   752: 	&print_td($r,13,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
                    753: 	&print_td($r,12,'#FFDDDD',$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
                    754: 	&print_td($r,11,'#FFDDDD',$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
1.203     www       755: 	&print_td($r,10,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
                    756: 	
                    757: 	if ($csec) {
1.269     raeburn   758: 	    &print_td($r,9,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
                    759: 	    &print_td($r,8,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
                    760: 	    &print_td($r,7,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
1.203     www       761: 	}
1.269     raeburn   762: 
                    763:         if ($cgroup) {
                    764:             &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
                    765:             &print_td($r,5,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
                    766:             &print_td($r,4,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
                    767:         }
1.275     raeburn   768:      
1.203     www       769: 	if ($uname) {
1.275     raeburn   770:             if ($othergrp) {
                    771:                 $r->print($othergrp);
                    772:             }
1.203     www       773: 	    &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
                    774: 	    &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
                    775: 	    &print_td($r,1,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display);
                    776: 	}
1.57      albertel  777: 
                    778:     } # end of $parmlev if/else
1.275     raeburn   779:     $r->print('<td bgcolor="#CCCCFF" align="center">'.$effective_parm.'</td>');
1.136     albertel  780: 
1.203     www       781:     if ($parmlev eq 'full') {
1.136     albertel  782:         my $sessionval=&Apache::lonnet::EXT('resource.'.$$part{$which}.
1.201     www       783:                                         '.'.$$name{$which},$$symbp{$rid});
1.136     albertel  784:         my $sessionvaltype=$typeoutpar[$result];
                    785:         if (!defined($sessionvaltype)) { $sessionvaltype=$$defaulttype{$which}; }
1.275     raeburn   786:         $r->print('<td bgcolor="#999999" align="center"><font color="#FFFFFF">'.
1.66      www       787:                   &valout($sessionval,$sessionvaltype).'&nbsp;'.
1.57      albertel  788:                   '</font></td>');
1.136     albertel  789:     }
1.44      albertel  790:     $r->print('</tr>');
1.57      albertel  791:     $r->print("\n");
1.44      albertel  792: }
1.59      matthew   793: 
1.44      albertel  794: sub print_td {
1.66      www       795:     my ($r,$which,$defbg,$result,$outpar,$mprefix,$value,$typeoutpar,$display)=@_;
1.57      albertel  796:     $r->print('<td bgcolor='.(($result==$which)?'"#AAFFAA"':$defbg).
1.114     www       797:               ' align="center">');
1.269     raeburn   798:     if ($which<11 || $which > 12) {
1.114     www       799: 	$r->print(&plink($$typeoutpar[$which],
                    800: 			 $$display{$value},$$outpar[$which],
                    801: 			 $mprefix."$which",'parmform.pres','psub'));
                    802:     } else {
                    803: 	$r->print(&valout($$outpar[$which],$$typeoutpar[$which]));
                    804:     }
                    805:     $r->print('</td>'."\n");
1.57      albertel  806: }
                    807: 
1.275     raeburn   808: sub print_usergroups {
                    809:     my ($r,$what,$rid,$cgroup,$defbg,$usersgroups,$result,$courseopt) = @_;
                    810:     my $courseid = $env{'request.course.id'};
                    811:     my $output;
                    812:     my $symb = &symbcache($rid);
                    813:     my $symbparm=$symb.'.'.$what;
                    814:     my $map=(&Apache::lonnet::decode_symb($symb))[0];
                    815:     my $mapparm=$map.'___(all).'.$what;
                    816:     my ($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype) =
                    817:           &parm_control_group($courseid,$usersgroups,$symbparm,$mapparm,$what,
                    818:                                                                    $courseopt);
                    819:     my $bgcolor = $defbg;
                    820:     my $grp_parm;
                    821:     if (($coursereply) && ($cgroup ne $resultgroup)) { 
                    822:         if ($result > 3) {
                    823:             $bgcolor = '"#AAFFAA"';
                    824:             $grp_parm = &valout($coursereply,$resulttype);
                    825:         }
                    826:         $grp_parm = &valout($coursereply,$resulttype);
                    827:         $output = '<td bgcolor='.$bgcolor.' align="center">';
                    828:         if ($resultgroup && $resultlevel) {
                    829:             $output .= '<small><b>'.$resultgroup.'</b> ('.$resultlevel.'): </small>'.$grp_parm;
                    830:         } else {
                    831:             $output .= '&nbsp;';
                    832:         }
                    833:         $output .= '</td>';
                    834:     } else {
                    835:         $output .= '<td bgcolor='.$bgcolor.'>&nbsp;</td>';
                    836:     }
                    837:     return ($coursereply,$output,$grp_parm,$resultgroup);
                    838: }
                    839: 
                    840: sub parm_control_group {
                    841:     my ($courseid,$usersgroups,$symbparm,$mapparm,$what,$courseopt) = @_;
                    842:     my ($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype);
                    843:     my $grpfound = 0;
                    844:     my @levels = ($symbparm,$mapparm,$what);
                    845:     my @levelnames = ('resource','map/folder','general');
                    846:     foreach my $group (@{$usersgroups}) {
                    847:         if ($grpfound) { last; }
                    848:         for (my $i=0; $i<@levels; $i++) {
                    849:             my $item = $courseid.'.['.$group.'].'.$levels[$i];
                    850:             if (defined($$courseopt{$item})) {
                    851:                 $coursereply = $$courseopt{$item};
                    852:                 $resultitem = $item;
                    853:                 $resultgroup = $group;
                    854:                 $resultlevel = $levelnames[$i];
                    855:                 $resulttype = $$courseopt{$item.'.type'};
                    856:                 $grpfound = 1;
                    857:                 last;
                    858:             }
                    859:         }
                    860:     }
                    861:     return($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype);
                    862: }
1.201     www       863: 
1.63      bowersj2  864: =pod
                    865: 
                    866: =item B<extractResourceInformation>: Given the course data hash, extractResourceInformation extracts lots of information about the course's resources into a variety of hashes.
                    867: 
                    868: Input: See list below:
                    869: 
                    870: =over 4
                    871: 
                    872: =item B<ids>: An array that will contain all of the ids in the course.
                    873: 
                    874: =item B<typep>: hash, id->type, where "type" contains the extension of the file, thus, I<problem exam quiz assess survey form>.
                    875: 
1.171     www       876: =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  877: 
                    878: =item B<allparms>: hash, name of parameter->display value (what is the display value?)
                    879: 
                    880: =item B<allparts>: hash, part identification->text representation of part, where the text representation is "[Part $part]"
                    881: 
                    882: =item B<allkeys>: hash, full key to part->display value (what's display value?)
                    883: 
                    884: =item B<allmaps>: hash, ???
                    885: 
                    886: =item B<fcat>: ???
                    887: 
                    888: =item B<defp>: hash, ???
                    889: 
                    890: =item B<mapp>: ??
                    891: 
                    892: =item B<symbp>: hash, id->full sym?
                    893: 
                    894: =back
                    895: 
                    896: =cut
                    897: 
                    898: sub extractResourceInformation {
                    899:     my $ids = shift;
                    900:     my $typep = shift;
                    901:     my $keyp = shift;
                    902:     my $allparms = shift;
                    903:     my $allparts = shift;
                    904:     my $allmaps = shift;
                    905:     my $mapp = shift;
                    906:     my $symbp = shift;
1.82      www       907:     my $maptitles=shift;
1.196     www       908:     my $uris=shift;
1.210     www       909:     my $keyorder=shift;
1.211     www       910:     my $defkeytype=shift;
1.196     www       911: 
1.210     www       912:     my $keyordercnt=100;
1.63      bowersj2  913: 
1.196     www       914:     my $navmap = Apache::lonnavmaps::navmap->new();
                    915:     my @allres=$navmap->retrieveResources(undef,undef,1,undef,1);
                    916:     foreach my $resource (@allres) {
                    917: 	my $id=$resource->id();
                    918:         my ($mapid,$resid)=split(/\./,$id);
                    919: 	if ($mapid eq '0') { next; }
                    920: 	$$ids[$#$ids+1]=$id;
                    921: 	my $srcf=$resource->src();
                    922: 	$srcf=~/\.(\w+)$/;
                    923: 	$$typep{$id}=$1;
                    924: 	$$keyp{$id}='';
                    925:         $$uris{$id}=$srcf;
                    926: 	foreach (split(/\,/,&Apache::lonnet::metadata($srcf,'allpossiblekeys'))) {
                    927: 	    if ($_=~/^parameter\_(.*)/) {
                    928: 		my $key=$_;
1.209     www       929: # Hidden parameters
                    930: 		if (&Apache::lonnet::metadata($srcf,$key.'.hidden') eq 'parm') {
                    931: 		    next;
1.63      bowersj2  932: 		}
1.196     www       933: 		my $display= &Apache::lonnet::metadata($srcf,$key.'.display');
                    934: 		my $name=&Apache::lonnet::metadata($srcf,$key.'.name');
                    935: 		my $part= &Apache::lonnet::metadata($srcf,$key.'.part');
1.209     www       936: #
                    937: # allparms is a hash of parameter names
                    938: #
1.196     www       939: 		my $parmdis = $display;
1.209     www       940: 		$parmdis =~ s/\[Part.*$//g;
                    941:                 $$allparms{$name}=$parmdis;
1.211     www       942: 		$$defkeytype{$name}=&Apache::lonnet::metadata($srcf,$key.'.type');
1.209     www       943: #
                    944: # allparts is a hash of all parts
                    945: #
                    946: 		$$allparts{$part} = "Part: $part";
                    947: #
                    948: # Remember all keys going with this resource
                    949: #
1.196     www       950: 		if ($$keyp{$id}) {
                    951: 		    $$keyp{$id}.=','.$key;
1.175     albertel  952: 		} else {
1.196     www       953: 		    $$keyp{$id}=$key;
1.175     albertel  954: 		}
1.210     www       955: #
                    956: # Put in order
                    957: # 
                    958:                 unless ($$keyorder{$key}) {
                    959:                     $$keyorder{$key}=$keyordercnt;
                    960:                     $keyordercnt++;
                    961: 		}
                    962: 
1.63      bowersj2  963: 	    }
                    964: 	}
1.196     www       965: 	$$mapp{$id}=
                    966: 	    &Apache::lonnet::declutter($resource->enclosing_map_src());
                    967: 	$$mapp{$mapid}=$$mapp{$id};
                    968: 	$$allmaps{$mapid}=$$mapp{$id};
                    969: 	if ($mapid eq '1') {
                    970: 	    $$maptitles{$mapid}='Main Course Documents';
                    971: 	} else {
                    972: 	    $$maptitles{$mapid}=&Apache::lonnet::gettitle(&Apache::lonnet::clutter($$mapp{$id}));
                    973: 	}
                    974: 	$$maptitles{$$mapp{$id}}=$$maptitles{$mapid};
                    975: 	$$symbp{$id}=&Apache::lonnet::encode_symb($$mapp{$id},$resid,$srcf);
                    976: 	$$symbp{$mapid}=$$mapp{$id}.'___(all)';
1.63      bowersj2  977:     }
                    978: }
                    979: 
1.208     www       980: 
                    981: ##################################################
                    982: ##################################################
                    983: 
1.213     www       984: sub isdateparm {
                    985:     my $type=shift;
                    986:     return (($type=~/^date/) && (!($type eq 'date_interval')));
                    987: }
                    988: 
1.208     www       989: sub parmmenu {
1.211     www       990:     my ($r,$allparms,$pscat,$keyorder)=@_;
1.208     www       991:     my $tempkey;
                    992:     $r->print(<<ENDSCRIPT);
                    993: <script type="text/javascript">
                    994:     function checkall(value, checkName) {
                    995: 	for (i=0; i<document.forms.parmform.elements.length; i++) {
                    996:             ele = document.forms.parmform.elements[i];
                    997:             if (ele.name == checkName) {
                    998:                 document.forms.parmform.elements[i].checked=value;
                    999:             }
                   1000:         }
                   1001:     }
1.210     www      1002: 
                   1003:     function checkthis(thisvalue, checkName) {
                   1004: 	for (i=0; i<document.forms.parmform.elements.length; i++) {
                   1005:             ele = document.forms.parmform.elements[i];
                   1006:             if (ele.name == checkName) {
                   1007: 		if (ele.value == thisvalue) {
                   1008: 		    document.forms.parmform.elements[i].checked=true;
                   1009: 		}
                   1010:             }
                   1011:         }
                   1012:     }
                   1013: 
                   1014:     function checkdates() {
                   1015: 	checkthis('duedate','pscat');
                   1016:  	checkthis('opendate','pscat');
                   1017: 	checkthis('answerdate','pscat');
1.218     www      1018:     }
                   1019: 
                   1020:     function checkdisset() {
                   1021: 	checkthis('discussend','pscat');
                   1022:  	checkthis('discusshide','pscat');
                   1023:     }
                   1024: 
                   1025:     function checkcontdates() {
                   1026: 	checkthis('contentopen','pscat');
                   1027:  	checkthis('contentclose','pscat');
                   1028:     }
                   1029:  
1.210     www      1030: 
                   1031:     function checkvisi() {
                   1032: 	checkthis('hiddenresource','pscat');
                   1033:  	checkthis('encrypturl','pscat');
                   1034: 	checkthis('problemstatus','pscat');
                   1035: 	checkthis('contentopen','pscat');
                   1036: 	checkthis('opendate','pscat');
                   1037:     }
                   1038: 
                   1039:     function checkparts() {
                   1040: 	checkthis('hiddenparts','pscat');
                   1041: 	checkthis('display','pscat');
                   1042: 	checkthis('ordered','pscat');
                   1043:     }
                   1044: 
                   1045:     function checkstandard() {
                   1046:         checkall(false,'pscat');
                   1047: 	checkdates();
                   1048: 	checkthis('weight','pscat');
                   1049: 	checkthis('maxtries','pscat');
                   1050:     }
                   1051: 
1.208     www      1052: </script>
                   1053: ENDSCRIPT
1.209     www      1054:     $r->print();
1.208     www      1055:     $r->print("\n<table><tr>");
                   1056:     my $cnt=0;
1.211     www      1057:     foreach $tempkey (&keysindisplayorder($allparms,$keyorder)) {
1.235     albertel 1058: 	$r->print("\n<td><font size='-1'><label><input type='checkbox' name='pscat' ");
1.208     www      1059: 	$r->print('value="'.$tempkey.'"');
                   1060: 	if ($$pscat[0] eq "all" || grep $_ eq $tempkey, @{$pscat}) {
                   1061: 	    $r->print(' checked');
                   1062: 	}
1.235     albertel 1063: 	$r->print('>'.$$allparms{$tempkey}.'</label></font></td>');
1.209     www      1064:  	$cnt++;
                   1065:         if ($cnt==3) {
                   1066: 	    $r->print("</tr>\n<tr>");
                   1067: 	    $cnt=0;
                   1068: 	}
1.208     www      1069:     }
                   1070:     $r->print('
                   1071: </tr><tr><td>
1.233     albertel 1072: <a href="javascript:checkall(true, \'pscat\')">Select&nbsp;All</a><br />
                   1073: <a href="javascript:checkstandard()">Select&nbsp;Common&nbsp;Only</a>
1.210     www      1074: </td><td>
1.233     albertel 1075: <a href="javascript:checkdates()">Add&nbsp;Problem&nbsp;Dates</a>
                   1076: <a href="javascript:checkcontdates()">Add&nbsp;Content&nbsp;Dates</a><br />
                   1077: <a href="javascript:checkdisset()">Add&nbsp;Discussion&nbsp;Settings</a>
                   1078: <a href="javascript:checkvisi()">Add&nbsp;Visibilities</a><br />
                   1079: <a href="javascript:checkparts()">Add&nbsp;Part&nbsp;Parameters</a>
1.210     www      1080: </td><td>
1.233     albertel 1081: <a href="javascript:checkall(false, \'pscat\')">Unselect&nbsp;All</a>
1.208     www      1082: </td>
                   1083: ');
                   1084:     $r->print('</tr></table>');
                   1085: }
                   1086: 
1.209     www      1087: sub partmenu {
                   1088:     my ($r,$allparts,$psprt)=@_;
1.211     www      1089:     $r->print('<select multiple name="psprt" size="8">');
1.208     www      1090:     $r->print('<option value="all"');
                   1091:     $r->print(' selected') unless (@{$psprt});
                   1092:     $r->print('>'.&mt('All Parts').'</option>');
                   1093:     my %temphash=();
                   1094:     foreach (@{$psprt}) { $temphash{$_}=1; }
1.234     albertel 1095:     foreach my $tempkey (sort {
                   1096: 	if ($a==$b) { return ($a cmp $b) } else { return ($a <=> $b); }
                   1097:     } keys(%{$allparts})) {
1.208     www      1098: 	unless ($tempkey =~ /\./) {
                   1099: 	    $r->print('<option value="'.$tempkey.'"');
                   1100: 	    if ($$psprt[0] eq "all" ||  $temphash{$tempkey}) {
                   1101: 		$r->print(' selected');
                   1102: 	    }
                   1103: 	    $r->print('>'.$$allparts{$tempkey}.'</option>');
                   1104: 	}
                   1105:     }
1.209     www      1106:     $r->print('</select>');
                   1107: }
                   1108: 
                   1109: sub usermenu {
1.275     raeburn  1110:     my ($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,$usersgroups)=@_;
1.209     www      1111:     my $chooseopt=&Apache::loncommon::select_dom_form($udom,'udom').' '.
                   1112:         &Apache::loncommon::selectstudent_link('parmform','uname','udom');
                   1113:     my $selscript=&Apache::loncommon::studentbrowser_javascript();
                   1114:     my %lt=&Apache::lonlocal::texthash(
1.269     raeburn  1115: 		    'se'    => "Section",
                   1116:                     'gr'    => "Group",
1.209     www      1117: 		    'fu'    => "For User",
                   1118: 		    'oi'    => "or ID",
                   1119: 		    'ad'    => "at Domain"
                   1120: 				       );
                   1121:     my $sections='';
1.300     albertel 1122:     my %sectionhash = &Apache::loncommon::get_sections();
                   1123: 
1.269     raeburn  1124:     my $groups;
1.299     albertel 1125:     my %grouphash = &Apache::loncommon::coursegroups();
                   1126: 
1.300     albertel 1127:     if (%sectionhash) {
1.269     raeburn  1128:         $sections=$lt{'se'}.': <select name="csec"';
1.299     albertel 1129:         if (%grouphash && $parmlev ne 'full') {
1.269     raeburn  1130:             $sections .= qq| onchange="group_or_section('csec')" |;
                   1131:         }
                   1132:         $sections .= '>';
1.275     raeburn  1133: 	foreach my $section ('',sort keys %sectionhash) {
                   1134: 	    $sections.='<option value="'.$section.'" '.
                   1135: 		($section eq $csec?'selected="selected"':'').'>'.$section.
                   1136:                                                               '</option>';
1.209     www      1137:         }
                   1138:         $sections.='</select>';
1.269     raeburn  1139:     }
1.300     albertel 1140:     if (%sectionhash && %grouphash && $parmlev ne 'full') {
1.269     raeburn  1141:         $sections .= '&nbsp;or&nbsp;';
                   1142:         $sections .= qq|
                   1143: <script type="text/javascript">
                   1144: function group_or_section(caller) {
                   1145:    if (caller == "cgroup") {
                   1146:        if (document.parmform.cgroup.selectedIndex != 0) {
                   1147:            document.parmform.csec.selectedIndex = 0;
                   1148:        }
                   1149:    } else {
                   1150:        if (document.parmform.csec.selectedIndex != 0) {
                   1151:            document.parmform.cgroup.selectedIndex = 0;
                   1152:        }
                   1153:    }
                   1154: }
                   1155: </script>
                   1156: |;
                   1157:     } else {
                   1158:         $sections .= qq|
                   1159: <script type="text/javascript">
                   1160: function group_or_section(caller) {
                   1161:     return;
                   1162: }
                   1163: </script>
                   1164: |;
                   1165:     } 
1.299     albertel 1166: 
                   1167:     if (%grouphash) {
1.269     raeburn  1168:         $groups=$lt{'gr'}.': <select name="cgroup"';
1.300     albertel 1169:         if (%sectionhash && $env{'form.action'} eq 'settable') {
1.269     raeburn  1170:             $groups .= qq| onchange="group_or_section('cgroup')" |;
                   1171:         }
                   1172:         $groups .= '>';
1.275     raeburn  1173:         foreach my $grp ('',sort keys %grouphash) {
                   1174:             $groups.='<option value="'.$grp.'" ';
                   1175:             if ($grp eq $cgroup) {
                   1176:                 unless ((defined($uname)) && ($grp eq '')) {
                   1177:                     $groups .=  'selected="selected" ';
                   1178:                 }
                   1179:             } elsif (!defined($cgroup)) {
                   1180:                 if (@{$usersgroups} == 1) {
                   1181:                     if ($grp eq $$usersgroups[0]) {
                   1182:                         $groups .=  'selected="selected" ';
                   1183:                     }
                   1184:                 }
                   1185:             }
                   1186:             $groups .= '>'.$grp.'</option>';
1.269     raeburn  1187:         }
                   1188:         $groups.='</select>';
                   1189:     }
                   1190:     $r->print(<<ENDMENU);
1.209     www      1191: <b>
                   1192: $sections
1.269     raeburn  1193: $groups
1.209     www      1194: <br />
                   1195: $lt{'fu'} 
                   1196: <input type="text" value="$uname" size="12" name="uname" />
                   1197: $lt{'oi'}
                   1198: <input type="text" value="$id" size="12" name="id" /> 
                   1199: $lt{'ad'}
                   1200: $chooseopt
                   1201: </b>
                   1202: ENDMENU
                   1203: }
                   1204: 
                   1205: sub displaymenu {
1.211     www      1206:     my ($r,$allparms,$allparts,$pscat,$psprt,$keyorder)=@_;
1.209     www      1207:     $r->print('<table border="1"><tr><th>'.&mt('Select Parameters to View').'</th><th>'.
                   1208: 	     &mt('Select Parts to View').'</th></tr><tr><td>');  
1.211     www      1209:     &parmmenu($r,$allparms,$pscat,$keyorder);
1.209     www      1210:     $r->print('</td><td>');
                   1211:     &partmenu($r,$allparts,$psprt);
                   1212:     $r->print('</td></tr></table>');
                   1213: }
                   1214: 
                   1215: sub mapmenu {
                   1216:     my ($r,$allmaps,$pschp,$maptitles)=@_;
1.231     www      1217:     $r->print('<b>'.&mt('Select Enclosing Map or Folder').'</b> ');
1.209     www      1218:     $r->print('<select name="pschp">');
                   1219:     $r->print('<option value="all">'.&mt('All Maps or Folders').'</option>');
                   1220:     foreach (sort {$$allmaps{$a} cmp $$allmaps{$b}} keys %{$allmaps}) {
1.208     www      1221: 	$r->print('<option value="'.$_.'"');
1.209     www      1222: 	if (($pschp eq $_)) { $r->print(' selected'); }
                   1223: 	$r->print('>'.$$maptitles{$_}.($$allmaps{$_}!~/^uploaded/?' ['.$$allmaps{$_}.']':'').'</option>');
                   1224:     }
                   1225:     $r->print("</select>");
                   1226: }
                   1227: 
                   1228: sub levelmenu {
                   1229:     my ($r,$alllevs,$parmlev)=@_;
1.231     www      1230:     $r->print('<b>'.&mt('Select Parameter Level').
                   1231: 	      &Apache::loncommon::help_open_topic('Course_Parameter_Levels').'</b> ');
1.209     www      1232:     $r->print('<select name="parmlev">');
                   1233:     foreach (reverse sort keys %{$alllevs}) {
                   1234: 	$r->print('<option value="'.$$alllevs{$_}.'"');
                   1235: 	if ($parmlev eq $$alllevs{$_}) {
                   1236: 	    $r->print(' selected'); 
                   1237: 	}
                   1238: 	$r->print('>'.$_.'</option>');
1.208     www      1239:     }
1.209     www      1240:     $r->print("</select>");
1.208     www      1241: }
                   1242: 
1.211     www      1243: 
                   1244: sub sectionmenu {
                   1245:     my ($r,$selectedsections)=@_;
1.300     albertel 1246:     my %sectionhash = &Apache::loncommon::get_sections();
                   1247:     return if (!%sectionhash);
                   1248: 
                   1249:     $r->print('<select name="Section" multiple="true" size="8" >');
                   1250:     foreach my $s ('all',sort keys %sectionhash) {
                   1251: 	$r->print('    <option value="'.$s.'"');
                   1252: 	foreach (@{$selectedsections}) {
                   1253: 	    if ($s eq $_) {
                   1254: 		$r->print(' selected');
                   1255: 		last;
1.212     www      1256: 	    }
                   1257: 	}
1.300     albertel 1258: 	$r->print('>'.$s."</option>\n");
                   1259:     }
                   1260:     $r->print("</select>\n");
1.269     raeburn  1261: }
                   1262: 
                   1263: sub groupmenu {
                   1264:     my ($r,$selectedgroups)=@_;
1.299     albertel 1265:     my %grouphash = &Apache::loncommon::coursegroups();
                   1266:     return if (!%grouphash);
                   1267: 
                   1268:     $r->print('<select name="Group" multiple="true" size="8" >');
                   1269:     foreach my $group (sort(keys(%grouphash))) {
                   1270: 	$r->print('    <option value="'.$group.'"');
                   1271: 	foreach (@{$selectedgroups}) {
                   1272: 	    if ($group eq $_) {
                   1273: 		$r->print(' selected');
                   1274: 		last;
                   1275: 	    }
                   1276: 	}
                   1277: 	$r->print('>'.$group."</option>\n");
1.211     www      1278:     }
1.299     albertel 1279:     $r->print("</select>\n");
1.211     www      1280: }
                   1281: 
1.269     raeburn  1282: 
1.210     www      1283: sub keysplit {
                   1284:     my $keyp=shift;
                   1285:     return (split(/\,/,$keyp));
                   1286: }
                   1287: 
                   1288: sub keysinorder {
                   1289:     my ($name,$keyorder)=@_;
                   1290:     return sort {
                   1291: 	$$keyorder{$a} <=> $$keyorder{$b};
                   1292:     } (keys %{$name});
                   1293: }
                   1294: 
1.236     albertel 1295: sub keysinorder_bytype {
                   1296:     my ($name,$keyorder)=@_;
                   1297:     return sort {
                   1298: 	my $ta=(split('_',$a))[-1];
                   1299: 	my $tb=(split('_',$b))[-1];
                   1300: 	if ($$keyorder{'parameter_0_'.$ta} == $$keyorder{'parameter_0_'.$tb}) {
                   1301: 	    return ($a cmp $b);
                   1302: 	}
                   1303: 	$$keyorder{'parameter_0_'.$ta} <=> $$keyorder{'parameter_0_'.$tb};
                   1304:     } (keys %{$name});
                   1305: }
                   1306: 
1.211     www      1307: sub keysindisplayorder {
                   1308:     my ($name,$keyorder)=@_;
                   1309:     return sort {
                   1310: 	$$keyorder{'parameter_0_'.$a} <=> $$keyorder{'parameter_0_'.$b};
                   1311:     } (keys %{$name});
                   1312: }
                   1313: 
1.214     www      1314: sub sortmenu {
                   1315:     my ($r,$sortorder)=@_;
1.236     albertel 1316:     $r->print('<br /><label><input type="radio" name="sortorder" value="realmstudent"');
1.214     www      1317:     if ($sortorder eq 'realmstudent') {
                   1318:        $r->print(' checked="on"');
                   1319:     }
                   1320:     $r->print(' />'.&mt('Sort by realm first, then student (group/section)'));
1.236     albertel 1321:     $r->print('</label><br /><label><input type="radio" name="sortorder" value="studentrealm"');
1.214     www      1322:     if ($sortorder eq 'studentrealm') {
                   1323:        $r->print(' checked="on"');
                   1324:     }
1.236     albertel 1325:     $r->print(' />'.&mt('Sort by student (group/section) first, then realm').
                   1326: 	      '</label>');
1.214     www      1327: }
                   1328: 
1.211     www      1329: sub standardkeyorder {
                   1330:     return ('parameter_0_opendate' => 1,
                   1331: 	    'parameter_0_duedate' => 2,
                   1332: 	    'parameter_0_answerdate' => 3,
                   1333: 	    'parameter_0_interval' => 4,
                   1334: 	    'parameter_0_weight' => 5,
                   1335: 	    'parameter_0_maxtries' => 6,
                   1336: 	    'parameter_0_hinttries' => 7,
                   1337: 	    'parameter_0_contentopen' => 8,
                   1338: 	    'parameter_0_contentclose' => 9,
                   1339: 	    'parameter_0_type' => 10,
                   1340: 	    'parameter_0_problemstatus' => 11,
                   1341: 	    'parameter_0_hiddenresource' => 12,
                   1342: 	    'parameter_0_hiddenparts' => 13,
                   1343: 	    'parameter_0_display' => 14,
                   1344: 	    'parameter_0_ordered' => 15,
                   1345: 	    'parameter_0_tol' => 16,
                   1346: 	    'parameter_0_sig' => 17,
1.218     www      1347: 	    'parameter_0_turnoffunit' => 18,
                   1348:             'parameter_0_discussend' => 19,
                   1349:             'parameter_0_discusshide' => 20);
1.211     www      1350: }
                   1351: 
1.59      matthew  1352: ##################################################
                   1353: ##################################################
                   1354: 
                   1355: =pod
                   1356: 
                   1357: =item assessparms
                   1358: 
                   1359: Show assessment data and parameters.  This is a large routine that should
                   1360: be simplified and shortened... someday.
                   1361: 
                   1362: Inputs: $r
                   1363: 
                   1364: Returns: nothing
                   1365: 
1.63      bowersj2 1366: Variables used (guessed by Jeremy):
                   1367: 
                   1368: =over 4
                   1369: 
                   1370: =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.
                   1371: 
                   1372: =item B<psprt>: ParameterS PaRTs? a list of the parts of a problem that we are displaying? Used to display only selected parts?
                   1373: 
                   1374: =item B<allmaps>:
                   1375: 
                   1376: =back
                   1377: 
1.59      matthew  1378: =cut
                   1379: 
                   1380: ##################################################
                   1381: ##################################################
1.30      www      1382: sub assessparms {
1.1       www      1383: 
1.43      albertel 1384:     my $r=shift;
1.201     www      1385: 
                   1386:     my @ids=();
                   1387:     my %symbp=();
                   1388:     my %mapp=();
                   1389:     my %typep=();
                   1390:     my %keyp=();
                   1391:     my %uris=();
                   1392:     my %maptitles=();
                   1393: 
1.2       www      1394: # -------------------------------------------------------- Variable declaration
1.209     www      1395: 
1.129     www      1396:     my %allmaps=();
                   1397:     my %alllevs=();
1.57      albertel 1398: 
1.187     www      1399:     my $uname;
                   1400:     my $udom;
                   1401:     my $uhome;
                   1402:     my $csec;
1.269     raeburn  1403:     my $cgroup;
1.275     raeburn  1404:     my @usersgroups = ();
1.187     www      1405:  
1.190     albertel 1406:     my $coursename=$env{'course.'.$env{'request.course.id'}.'.description'};
1.187     www      1407: 
1.57      albertel 1408:     $alllevs{'Resource Level'}='full';
1.215     www      1409:     $alllevs{'Map/Folder Level'}='map';
1.57      albertel 1410:     $alllevs{'Course Level'}='general';
                   1411: 
                   1412:     my %allparms;
                   1413:     my %allparts;
1.210     www      1414: #
                   1415: # Order in which these parameters will be displayed
                   1416: #
1.211     www      1417:     my %keyorder=&standardkeyorder();
                   1418: 
1.43      albertel 1419:     @ids=();
                   1420:     %symbp=();
                   1421:     %typep=();
                   1422: 
                   1423:     my $message='';
                   1424: 
1.190     albertel 1425:     $csec=$env{'form.csec'};
1.269     raeburn  1426:     $cgroup=$env{'form.cgroup'};
1.188     www      1427: 
1.190     albertel 1428:     if      ($udom=$env{'form.udom'}) {
                   1429:     } elsif ($udom=$env{'request.role.domain'}) {
                   1430:     } elsif ($udom=$env{'user.domain'}) {
1.172     albertel 1431:     } else {
                   1432: 	$udom=$r->dir_config('lonDefDomain');
                   1433:     }
1.43      albertel 1434: 
1.134     albertel 1435:     my @pscat=&Apache::loncommon::get_env_multiple('form.pscat');
1.190     albertel 1436:     my $pschp=$env{'form.pschp'};
1.134     albertel 1437:     my @psprt=&Apache::loncommon::get_env_multiple('form.psprt');
1.76      www      1438:     if (!@psprt) { $psprt[0]='0'; }
1.57      albertel 1439: 
1.43      albertel 1440:     my $pssymb='';
1.57      albertel 1441:     my $parmlev='';
                   1442:  
1.190     albertel 1443:     unless ($env{'form.parmlev'}) {
1.57      albertel 1444:         $parmlev = 'map';
                   1445:     } else {
1.190     albertel 1446:         $parmlev = $env{'form.parmlev'};
1.57      albertel 1447:     }
1.26      www      1448: 
1.29      www      1449: # ----------------------------------------------- Was this started from grades?
                   1450: 
1.190     albertel 1451:     if (($env{'form.command'} eq 'set') && ($env{'form.url'})
                   1452: 	&& (!$env{'form.dis'})) {
                   1453: 	my $url=$env{'form.url'};
1.194     albertel 1454: 	$url=~s-^http://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--;
1.43      albertel 1455: 	$pssymb=&Apache::lonnet::symbread($url);
1.92      albertel 1456: 	if (!@pscat) { @pscat=('all'); }
1.43      albertel 1457: 	$pschp='';
1.57      albertel 1458:         $parmlev = 'full';
1.190     albertel 1459:     } elsif ($env{'form.symb'}) {
                   1460: 	$pssymb=$env{'form.symb'};
1.92      albertel 1461: 	if (!@pscat) { @pscat=('all'); }
1.43      albertel 1462: 	$pschp='';
1.57      albertel 1463:         $parmlev = 'full';
1.43      albertel 1464:     } else {
1.190     albertel 1465: 	$env{'form.url'}='';
1.43      albertel 1466:     }
                   1467: 
1.190     albertel 1468:     my $id=$env{'form.id'};
1.43      albertel 1469:     if (($id) && ($udom)) {
                   1470: 	$uname=(&Apache::lonnet::idget($udom,$id))[1];
                   1471: 	if ($uname) {
                   1472: 	    $id='';
                   1473: 	} else {
                   1474: 	    $message=
1.133     www      1475: 		"<font color=red>".&mt("Unknown ID")." '$id' ".
                   1476: 		&mt('at domain')." '$udom'</font>";
1.43      albertel 1477: 	}
                   1478:     } else {
1.190     albertel 1479: 	$uname=$env{'form.uname'};
1.43      albertel 1480:     }
                   1481:     unless ($udom) { $uname=''; }
                   1482:     $uhome='';
                   1483:     if ($uname) {
                   1484: 	$uhome=&Apache::lonnet::homeserver($uname,$udom);
                   1485:         if ($uhome eq 'no_host') {
                   1486: 	    $message=
1.133     www      1487: 		"<font color=red>".&mt("Unknown user")." '$uname' ".
                   1488: 		&mt("at domain")." '$udom'</font>";
1.43      albertel 1489: 	    $uname='';
1.12      www      1490:         } else {
1.103     albertel 1491: 	    $csec=&Apache::lonnet::getsection($udom,$uname,
1.190     albertel 1492: 					      $env{'request.course.id'});
1.269     raeburn  1493:             
1.43      albertel 1494: 	    if ($csec eq '-1') {
                   1495: 		$message="<font color=red>".
1.133     www      1496: 		    &mt("User")." '$uname' ".&mt("at domain")." '$udom' ".
                   1497: 		    &mt("not in this course")."</font>";
1.43      albertel 1498: 		$uname='';
1.190     albertel 1499: 		$csec=$env{'form.csec'};
1.269     raeburn  1500:                 $cgroup=$env{'form.cgroup'};
1.43      albertel 1501: 	    } else {
                   1502: 		my %name=&Apache::lonnet::userenvironment($udom,$uname,
                   1503: 		      ('firstname','middlename','lastname','generation','id'));
1.133     www      1504: 		$message="\n<p>\n".&mt("Full Name").": ".
1.43      albertel 1505: 		    $name{'firstname'}.' '.$name{'middlename'}.' '
                   1506: 			.$name{'lastname'}.' '.$name{'generation'}.
1.133     www      1507: 			    "<br>\n".&mt('ID').": ".$name{'id'}.'<p>';
1.43      albertel 1508: 	    }
1.297     raeburn  1509:             @usersgroups = &Apache::lonnet::get_users_groups(
1.275     raeburn  1510:                                        $udom,$uname,$env{'request.course.id'});
1.297     raeburn  1511:             if (@usersgroups > 0) {
1.275     raeburn  1512:                 unless (grep/^\Q$cgroup\E$/,@usersgroups) {
                   1513:                     $cgroup = $usersgroups[0];
1.297     raeburn  1514:                 }
1.269     raeburn  1515:             }
1.12      www      1516:         }
1.43      albertel 1517:     }
1.2       www      1518: 
1.43      albertel 1519:     unless ($csec) { $csec=''; }
1.269     raeburn  1520:     unless ($cgroup) { $cgroup=''; }
1.12      www      1521: 
1.14      www      1522: # --------------------------------------------------------- Get all assessments
1.210     www      1523:     &extractResourceInformation(\@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allmaps, 
                   1524: 				\%mapp, \%symbp,\%maptitles,\%uris,
                   1525: 				\%keyorder);
1.63      bowersj2 1526: 
1.57      albertel 1527:     $mapp{'0.0'} = '';
                   1528:     $symbp{'0.0'} = '';
1.99      albertel 1529: 
1.14      www      1530: # ---------------------------------------------------------- Anything to store?
1.190     albertel 1531:     if ($env{'form.pres_marker'}) {
1.205     www      1532:         my @markers=split(/\&\&\&/,$env{'form.pres_marker'});
                   1533:         my @values=split(/\&\&\&/,$env{'form.pres_value'});
                   1534:         my @types=split(/\&\&\&/,$env{'form.pres_type'});
                   1535: 	for (my $i=0;$i<=$#markers;$i++) {
                   1536: 	    $message.=&storeparm(split(/\&/,$markers[$i]),
                   1537: 				 $values[$i],
                   1538: 				 $types[$i],
1.269     raeburn  1539: 				 $uname,$udom,$csec,$cgroup);
1.205     www      1540: 	}
1.68      www      1541: # ---------------------------------------------------------------- Done storing
1.130     www      1542: 	$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      1543:     }
1.57      albertel 1544: #----------------------------------------------- if all selected, fill in array
1.209     www      1545:     if ($pscat[0] eq "all") {@pscat = (keys %allparms);}
                   1546:     if (!@pscat) { @pscat=('duedate','opendate','answerdate','weight','maxtries') }; 
1.57      albertel 1547:     if ($psprt[0] eq "all" || !@psprt) {@psprt = (keys %allparts);}
1.2       www      1548: # ------------------------------------------------------------------ Start page
1.63      bowersj2 1549: 
1.209     www      1550:     &startpage($r);
1.57      albertel 1551: 
1.44      albertel 1552:     foreach ('tolerance','date_default','date_start','date_end',
                   1553: 	     'date_interval','int','float','string') {
                   1554: 	$r->print('<input type="hidden" value="'.
1.190     albertel 1555: 		  $env{'form.recent_'.$_}.'" name="recent_'.$_.'">');
1.44      albertel 1556:     }
1.57      albertel 1557:                         
1.44      albertel 1558:     if (!$pssymb) {
1.209     www      1559:         $r->print('<table border="1"><tr><td>');
                   1560:         &levelmenu($r,\%alllevs,$parmlev);
1.128     albertel 1561: 	if ($parmlev ne 'general') {
1.209     www      1562:             $r->print('<td>');
                   1563: 	    &mapmenu($r,\%allmaps,$pschp,\%maptitles);
                   1564: 	    $r->print('</td>');
1.128     albertel 1565: 	}
1.209     www      1566:         $r->print('</td></tr></table>');
1.211     www      1567: 	&displaymenu($r,\%allparms,\%allparts,\@pscat,\@psprt,\%keyorder);
1.44      albertel 1568:     } else {
1.125     www      1569:         my ($map,$id,$resource)=&Apache::lonnet::decode_symb($pssymb);
1.209     www      1570:         $r->print(&mt('Specific Resource').": ".$resource.
1.238     www      1571:                   '<input type="hidden" value="'.$pssymb.'" name="symb">'.
                   1572: 		  '<br /><label><b>'.&mt('Show all parts').': <input type="checkbox" name="psprt" value="all"'.
                   1573: 		  ($env{'form.psprt'}?' checked="checked"':'').' /></b></label><br />');
1.57      albertel 1574:     }
1.275     raeburn  1575:     &usermenu($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,\@usersgroups);    
1.57      albertel 1576: 
1.210     www      1577:     $r->print('<p>'.$message.'</p>');
                   1578: 
1.209     www      1579:     $r->print('<br /><input type="submit" name="dis" value="'.&mt("Update Parameter Display").'" />');
1.57      albertel 1580: 
                   1581:     my @temp_pscat;
                   1582:     map {
                   1583:         my $cat = $_;
                   1584:         push(@temp_pscat, map { $_.'.'.$cat } @psprt);
                   1585:     } @pscat;
                   1586: 
                   1587:     @pscat = @temp_pscat;
                   1588: 
1.209     www      1589:     if (($env{'form.prevvisit'}) || ($pschp) || ($pssymb)) {
1.10      www      1590: # ----------------------------------------------------------------- Start Table
1.57      albertel 1591:         my @catmarker=map { tr|.|_|; 'parameter_'.$_; } @pscat;
1.190     albertel 1592:         my $csuname=$env{'user.name'};
                   1593:         my $csudom=$env{'user.domain'};
1.57      albertel 1594: 
1.203     www      1595:         if ($parmlev eq 'full') {
1.57      albertel 1596:            my $coursespan=$csec?8:5;
1.275     raeburn  1597:            my $userspan=3;
1.269     raeburn  1598:            if ($cgroup ne '') {
                   1599:               $coursespan += 3;
                   1600:            } 
                   1601:       
1.57      albertel 1602:            $r->print('<p><table border=2>');
                   1603:            $r->print('<tr><td colspan=5></td>');
1.130     www      1604:            $r->print('<th colspan='.($coursespan).'>'.&mt('Any User').'</th>');
1.57      albertel 1605:            if ($uname) {
1.275     raeburn  1606:                if (@usersgroups > 1) {
                   1607:                    $userspan ++;
                   1608:                }
                   1609:                $r->print('<th colspan="'.$userspan.'" rowspan="2">');
1.130     www      1610:                $r->print(&mt("User")." $uname ".&mt('at Domain')." $udom</th>");
1.57      albertel 1611:            }
1.133     www      1612: 	   my %lt=&Apache::lonlocal::texthash(
                   1613: 				  'pie'    => "Parameter in Effect",
                   1614: 				  'csv'    => "Current Session Value",
                   1615:                                   'at'     => 'at',
                   1616:                                   'rl'     => "Resource Level",
                   1617: 				  'ic'     => 'in Course',
                   1618: 				  'aut'    => "Assessment URL and Title",
1.143     albertel 1619: 				  'type'   => 'Type',
1.133     www      1620: 				  'emof'   => "Enclosing Map or Folder",
1.143     albertel 1621: 				  'part'   => 'Part',
1.133     www      1622:                                   'pn'     => 'Parameter Name',
                   1623: 				  'def'    => 'default',
                   1624: 				  'femof'  => 'from Enclosing Map or Folder',
                   1625: 				  'gen'    => 'general',
                   1626: 				  'foremf' => 'for Enclosing Map or Folder',
                   1627: 				  'fr'     => 'for Resource'
                   1628: 					      );
1.57      albertel 1629:            $r->print(<<ENDTABLETWO);
1.133     www      1630: <th rowspan=3>$lt{'pie'}</th>
                   1631: <th rowspan=3>$lt{'csv'}<br>($csuname $lt{'at'} $csudom)</th>
1.182     albertel 1632: </tr><tr><td colspan=5></td><th colspan=2>$lt{'ic'}</th><th colspan=2>$lt{'rl'}</th>
                   1633: <th colspan=1>$lt{'ic'}</th>
                   1634: 
1.10      www      1635: ENDTABLETWO
1.57      albertel 1636:            if ($csec) {
1.133     www      1637:                 $r->print("<th colspan=3>".
1.269     raeburn  1638: 			  &mt("in Section")." $csec</th>");
                   1639:            }
                   1640:            if ($cgroup) {
                   1641:                 $r->print("<th colspan=3>".
                   1642:                           &mt("in Group")." $cgroup</th>");
1.57      albertel 1643:            }
                   1644:            $r->print(<<ENDTABLEHEADFOUR);
1.133     www      1645: </tr><tr><th>$lt{'aut'}</th><th>$lt{'type'}</th>
                   1646: <th>$lt{'emof'}</th><th>$lt{'part'}</th><th>$lt{'pn'}</th>
1.192     albertel 1647: <th>$lt{'gen'}</th><th>$lt{'foremf'}</th>
                   1648: <th>$lt{'def'}</th><th>$lt{'femof'}</th><th>$lt{'fr'}</th>
1.10      www      1649: ENDTABLEHEADFOUR
1.57      albertel 1650: 
                   1651:            if ($csec) {
1.130     www      1652:                $r->print('<th>'.&mt('general').'</th><th>'.&mt('for Enclosing Map or Folder').'</th><th>'.&mt('for Resource').'</th>');
1.57      albertel 1653:            }
                   1654: 
1.269     raeburn  1655:            if ($cgroup) {
                   1656:                $r->print('<th>'.&mt('general').'</th><th>'.&mt('for Enclosing Map or Folder').'</th><th>'.&mt('for Resource').'</th>');
                   1657:            }
                   1658: 
1.57      albertel 1659:            if ($uname) {
1.275     raeburn  1660:                if (@usersgroups > 1) {
                   1661:                    $r->print('<th>'.&mt('Control by other group?').'</th>');
                   1662:                }
1.130     www      1663:                $r->print('<th>'.&mt('general').'</th><th>'.&mt('for Enclosing Map or Folder').'</th><th>'.&mt('for Resource').'</th>');
1.57      albertel 1664:            }
                   1665: 
                   1666:            $r->print('</tr>');
                   1667: 
                   1668:            my $defbgone='';
                   1669:            my $defbgtwo='';
1.269     raeburn  1670:            my $defbgthree = '';
1.57      albertel 1671: 
                   1672:            foreach (@ids) {
                   1673: 
                   1674:                 my $rid=$_;
                   1675:                 my ($inmapid)=($rid=~/\.(\d+)$/);
                   1676: 
1.152     albertel 1677:                 if ((!$pssymb && 
                   1678: 		     (($pschp eq 'all') || ($allmaps{$pschp} eq $mapp{$rid})))
                   1679: 		    ||
                   1680: 		    ($pssymb && $pssymb eq $symbp{$rid})) {
1.4       www      1681: # ------------------------------------------------------ Entry for one resource
1.184     albertel 1682:                     if ($defbgone eq '"#E0E099"') {
                   1683:                         $defbgone='"#E0E0DD"';
1.57      albertel 1684:                     } else {
1.184     albertel 1685:                         $defbgone='"#E0E099"';
1.57      albertel 1686:                     }
1.184     albertel 1687:                     if ($defbgtwo eq '"#FFFF99"') {
                   1688:                         $defbgtwo='"#FFFFDD"';
1.57      albertel 1689:                     } else {
1.184     albertel 1690:                         $defbgtwo='"#FFFF99"';
1.57      albertel 1691:                     }
1.269     raeburn  1692:                     if ($defbgthree eq '"#FFBB99"') {
                   1693:                         $defbgthree='"#FFBBDD"';
                   1694:                     } else {
                   1695:                         $defbgthree='"#FFBB99"';
                   1696:                     }
                   1697: 
1.57      albertel 1698:                     my $thistitle='';
                   1699:                     my %name=   ();
                   1700:                     undef %name;
                   1701:                     my %part=   ();
                   1702:                     my %display=();
                   1703:                     my %type=   ();
                   1704:                     my %default=();
1.196     www      1705:                     my $uri=&Apache::lonnet::declutter($uris{$rid});
1.57      albertel 1706: 
1.210     www      1707:                     foreach (&keysplit($keyp{$rid})) {
1.57      albertel 1708:                         my $tempkeyp = $_;
                   1709:                         if (grep $_ eq $tempkeyp, @catmarker) {
                   1710:                           $part{$_}=&Apache::lonnet::metadata($uri,$_.'.part');
                   1711:                           $name{$_}=&Apache::lonnet::metadata($uri,$_.'.name');
                   1712:                           $display{$_}=&Apache::lonnet::metadata($uri,$_.'.display');
                   1713:                           unless ($display{$_}) { $display{$_}=''; }
                   1714:                           $display{$_}.=' ('.$name{$_}.')';
                   1715:                           $default{$_}=&Apache::lonnet::metadata($uri,$_);
                   1716:                           $type{$_}=&Apache::lonnet::metadata($uri,$_.'.type');
                   1717:                           $thistitle=&Apache::lonnet::metadata($uri,$_.'.title');
                   1718:                         }
                   1719:                     }
                   1720:                     my $totalparms=scalar keys %name;
                   1721:                     if ($totalparms>0) {
                   1722:                         my $firstrow=1;
1.274     albertel 1723: 			my $title=&Apache::lonnet::gettitle($symbp{$rid});
1.57      albertel 1724:                         $r->print('<tr><td bgcolor='.$defbgone.
                   1725:                              ' rowspan='.$totalparms.
                   1726:                              '><tt><font size=-1>'.
                   1727:                              join(' / ',split(/\//,$uri)).
                   1728:                              '</font></tt><p><b>'.
1.154     albertel 1729:                              "<a href=\"javascript:openWindow('".
1.274     albertel 1730: 				  &Apache::lonnet::clutter($uri).'?symb='.
                   1731: 				  &Apache::lonnet::escape($symbp{$rid}).
1.57      albertel 1732:                              "', 'metadatafile', '450', '500', 'no', 'yes')\";".
1.127     albertel 1733:                              " TARGET=_self>$title");
1.57      albertel 1734: 
                   1735:                         if ($thistitle) {
                   1736:                             $r->print(' ('.$thistitle.')');
                   1737:                         }
                   1738:                         $r->print('</a></b></td>');
                   1739:                         $r->print('<td bgcolor='.$defbgtwo.
                   1740:                                       ' rowspan='.$totalparms.'>'.$typep{$rid}.
                   1741:                                       '</td>');
                   1742: 
                   1743:                         $r->print('<td bgcolor='.$defbgone.
                   1744:                                       ' rowspan='.$totalparms.
1.238     www      1745:                                       '>'.$maptitles{$mapp{$rid}}.'</td>');
1.57      albertel 1746: 
1.236     albertel 1747:                         foreach (&keysinorder_bytype(\%name,\%keyorder)) {
1.57      albertel 1748:                             unless ($firstrow) {
                   1749:                                 $r->print('<tr>');
                   1750:                             } else {
                   1751:                                 undef $firstrow;
                   1752:                             }
1.201     www      1753:                             &print_row($r,$_,\%part,\%name,\%symbp,$rid,\%default,
1.57      albertel 1754:                                        \%type,\%display,$defbgone,$defbgtwo,
1.269     raeburn  1755:                                        $defbgthree,$parmlev,$uname,$udom,$csec,
1.275     raeburn  1756:                                                             $cgroup,\@usersgroups);
1.57      albertel 1757:                         }
                   1758:                     }
                   1759:                 }
                   1760:             } # end foreach ids
1.43      albertel 1761: # -------------------------------------------------- End entry for one resource
1.57      albertel 1762:             $r->print('</table>');
1.203     www      1763:         } # end of  full
1.57      albertel 1764: #--------------------------------------------------- Entry for parm level map
                   1765:         if ($parmlev eq 'map') {
                   1766:             my $defbgone = '"E0E099"';
                   1767:             my $defbgtwo = '"FFFF99"';
1.269     raeburn  1768:             my $defbgthree = '"FFBB99"';
1.57      albertel 1769: 
                   1770:             my %maplist;
                   1771: 
                   1772:             if ($pschp eq 'all') {
                   1773:                 %maplist = %allmaps; 
                   1774:             } else {
                   1775:                 %maplist = ($pschp => $mapp{$pschp});
                   1776:             }
                   1777: 
                   1778: #-------------------------------------------- for each map, gather information
                   1779:             my $mapid;
1.60      albertel 1780: 	    foreach $mapid (sort {$maplist{$a} cmp $maplist{$b}} keys %maplist) {
                   1781:                 my $maptitle = $maplist{$mapid};
1.57      albertel 1782: 
                   1783: #-----------------------  loop through ids and get all parameter types for map
                   1784: #-----------------------------------------          and associated information
                   1785:                 my %name = ();
                   1786:                 my %part = ();
                   1787:                 my %display = ();
                   1788:                 my %type = ();
                   1789:                 my %default = ();
                   1790:                 my $map = 0;
                   1791: 
                   1792: #		$r->print("Catmarker: @catmarker<br />\n");
                   1793:                
                   1794:                 foreach (@ids) {
                   1795:                   ($map)=(/([\d]*?)\./);
                   1796:                   my $rid = $_;
                   1797:         
                   1798: #                  $r->print("$mapid:$map:   $rid <br /> \n");
                   1799: 
                   1800:                   if ($map eq $mapid) {
1.196     www      1801:                     my $uri=&Apache::lonnet::declutter($uris{$rid});
1.57      albertel 1802: #                    $r->print("Keys: $keyp{$rid} <br />\n");
                   1803: 
                   1804: #--------------------------------------------------------------------
                   1805: # @catmarker contains list of all possible parameters including part #s
                   1806: # $fullkeyp contains the full part/id # for the extraction of proper parameters
                   1807: # $tempkeyp contains part 0 only (no ids - ie, subparts)
                   1808: # When storing information, store as part 0
                   1809: # When requesting information, request from full part
                   1810: #-------------------------------------------------------------------
1.210     www      1811:                     foreach (&keysplit($keyp{$rid})) {
1.57      albertel 1812:                       my $tempkeyp = $_;
                   1813:                       my $fullkeyp = $tempkeyp;
1.73      albertel 1814:                       $tempkeyp =~ s/_\w+_/_0_/;
1.57      albertel 1815:                       
                   1816:                       if ((grep $_ eq $fullkeyp, @catmarker) &&(!$name{$tempkeyp})) {
                   1817:                         $part{$tempkeyp}="0";
                   1818:                         $name{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.name');
                   1819:                         $display{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.display');
                   1820:                         unless ($display{$tempkeyp}) { $display{$tempkeyp}=''; }
                   1821:                         $display{$tempkeyp}.=' ('.$name{$tempkeyp}.')';
1.73      albertel 1822:                         $display{$tempkeyp} =~ s/_\w+_/_0_/;
1.57      albertel 1823:                         $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp);
                   1824:                         $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.type');
                   1825:                       }
                   1826:                     } # end loop through keys
                   1827:                   }
                   1828:                 } # end loop through ids
                   1829:                                  
                   1830: #---------------------------------------------------- print header information
1.133     www      1831:                 my $foldermap=&mt($maptitle=~/^uploaded/?'Folder':'Map');
1.82      www      1832:                 my $showtitle=$maptitles{$maptitle}.($maptitle!~/^uploaded/?' ['.$maptitle.']':'');
1.57      albertel 1833:                 $r->print(<<ENDMAPONE);
                   1834: <center><h4>
1.135     albertel 1835: Set Defaults for All Resources in $foldermap<br />
                   1836: <font color="red"><i>$showtitle</i></font><br />
1.57      albertel 1837: Specifically for
                   1838: ENDMAPONE
                   1839:                 if ($uname) {
1.267     albertel 1840: 		    my $person=&Apache::loncommon::plainname($uname,$udom);
1.135     albertel 1841:                     $r->print(&mt("User")." <font color=\"red\"><i>$uname \($person\) </i></font> ".
1.130     www      1842:                         &mt('in')." \n");
1.57      albertel 1843:                 } else {
1.135     albertel 1844:                     $r->print("<font color=\"red\"><i>".&mt('all').'</i></font> '.&mt('users in')." \n");
1.57      albertel 1845:                 }
1.269     raeburn  1846:                 if ($cgroup) {
                   1847:                     $r->print(&mt("Group")." <font color=\"red\"><i>$cgroup".
                   1848:                               "</i></font> ".&mt('of')." \n");
                   1849:                     $csec = '';
                   1850:                 } elsif ($csec) {
                   1851:                     $r->print(&mt("Section")." <font color=\"red\"><i>$csec".
                   1852:                               "</i></font> ".&mt('of')." \n");
                   1853:                 }
1.135     albertel 1854:                 $r->print("<font color=\"red\"><i>$coursename</i></font><br />");
                   1855:                 $r->print("</h4>\n");
1.57      albertel 1856: #---------------------------------------------------------------- print table
                   1857:                 $r->print('<p><table border="2">');
1.130     www      1858:                 $r->print('<tr><th>'.&mt('Parameter Name').'</th>');
                   1859:                 $r->print('<th>'.&mt('Default Value').'</th>');
                   1860:                 $r->print('<th>'.&mt('Parameter in Effect').'</th></tr>');
1.57      albertel 1861: 
1.210     www      1862: 	        foreach (&keysinorder(\%name,\%keyorder)) {
1.168     matthew  1863:                     $r->print('<tr>');
1.201     www      1864:                     &print_row($r,$_,\%part,\%name,\%symbp,$mapid,\%default,
1.269     raeburn  1865:                            \%type,\%display,$defbgone,$defbgtwo,$defbgthree,
                   1866:                            $parmlev,$uname,$udom,$csec,$cgroup);
1.57      albertel 1867:                 }
                   1868:                 $r->print("</table></center>");
                   1869:             } # end each map
                   1870:         } # end of $parmlev eq map
                   1871: #--------------------------------- Entry for parm level general (Course level)
                   1872:         if ($parmlev eq 'general') {
                   1873:             my $defbgone = '"E0E099"';
                   1874:             my $defbgtwo = '"FFFF99"';
1.269     raeburn  1875:             my $defbgthree = '"FFBB99"';
1.57      albertel 1876: 
                   1877: #-------------------------------------------- for each map, gather information
                   1878:             my $mapid="0.0";
                   1879: #-----------------------  loop through ids and get all parameter types for map
                   1880: #-----------------------------------------          and associated information
                   1881:             my %name = ();
                   1882:             my %part = ();
                   1883:             my %display = ();
                   1884:             my %type = ();
                   1885:             my %default = ();
                   1886:                
                   1887:             foreach (@ids) {
                   1888:                 my $rid = $_;
                   1889:         
1.196     www      1890:                 my $uri=&Apache::lonnet::declutter($uris{$rid});
1.57      albertel 1891: 
                   1892: #--------------------------------------------------------------------
                   1893: # @catmarker contains list of all possible parameters including part #s
                   1894: # $fullkeyp contains the full part/id # for the extraction of proper parameters
                   1895: # $tempkeyp contains part 0 only (no ids - ie, subparts)
                   1896: # When storing information, store as part 0
                   1897: # When requesting information, request from full part
                   1898: #-------------------------------------------------------------------
1.210     www      1899:                 foreach (&keysplit($keyp{$rid})) {
1.57      albertel 1900:                   my $tempkeyp = $_;
                   1901:                   my $fullkeyp = $tempkeyp;
1.73      albertel 1902:                   $tempkeyp =~ s/_\w+_/_0_/;
1.57      albertel 1903:                   if ((grep $_ eq $fullkeyp, @catmarker) &&(!$name{$tempkeyp})) {
                   1904:                     $part{$tempkeyp}="0";
                   1905:                     $name{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.name');
                   1906:                     $display{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.display');
                   1907:                     unless ($display{$tempkeyp}) { $display{$tempkeyp}=''; }
                   1908:                     $display{$tempkeyp}.=' ('.$name{$tempkeyp}.')';
1.73      albertel 1909:                     $display{$tempkeyp} =~ s/_\w+_/_0_/;
1.57      albertel 1910:                     $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp);
                   1911:                     $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.type');
                   1912:                   }
                   1913:                 } # end loop through keys
                   1914:             } # end loop through ids
                   1915:                                  
                   1916: #---------------------------------------------------- print header information
1.133     www      1917: 	    my $setdef=&mt("Set Defaults for All Resources in Course");
1.57      albertel 1918:             $r->print(<<ENDMAPONE);
1.133     www      1919: <center><h4>$setdef
1.135     albertel 1920: <font color="red"><i>$coursename</i></font><br />
1.57      albertel 1921: ENDMAPONE
                   1922:             if ($uname) {
1.267     albertel 1923: 		my $person=&Apache::loncommon::plainname($uname,$udom);
1.135     albertel 1924:                 $r->print(" ".&mt("User")."<font color=\"red\"> <i>$uname \($person\) </i></font> \n");
1.57      albertel 1925:             } else {
1.135     albertel 1926:                 $r->print("<i><font color=\"red\"> ".&mt("ALL")."</i> ".&mt("USERS")."</font> \n");
1.57      albertel 1927:             }
                   1928:             
1.135     albertel 1929:             if ($csec) {$r->print(&mt("Section")."<font color=\"red\"> <i>$csec</i></font>\n")};
1.269     raeburn  1930:             if ($cgroup) {$r->print(&mt("Group")."<font color=\"red\"> <i>$csec</i></font>\n")};
1.135     albertel 1931:             $r->print("</h4>\n");
1.57      albertel 1932: #---------------------------------------------------------------- print table
                   1933:             $r->print('<p><table border="2">');
1.130     www      1934:             $r->print('<tr><th>'.&mt('Parameter Name').'</th>');
                   1935:             $r->print('<th>'.&mt('Default Value').'</th>');
                   1936:             $r->print('<th>'.&mt('Parameter in Effect').'</th></tr>');
1.57      albertel 1937: 
1.210     www      1938: 	    foreach (&keysinorder(\%name,\%keyorder)) {
1.168     matthew  1939:                 $r->print('<tr>');
1.201     www      1940:                 &print_row($r,$_,\%part,\%name,\%symbp,$mapid,\%default,
1.269     raeburn  1941:                        \%type,\%display,$defbgone,$defbgtwo,$defbgthree,
                   1942:                                    $parmlev,$uname,$udom,$csec,$cgroup);
1.57      albertel 1943:             }
                   1944:             $r->print("</table></center>");
                   1945:         } # end of $parmlev eq general
1.43      albertel 1946:     }
1.280     albertel 1947:     $r->print('</form>'.&Apache::loncommon::end_page());
1.57      albertel 1948: } # end sub assessparms
1.30      www      1949: 
1.59      matthew  1950: 
                   1951: ##################################################
                   1952: ##################################################
                   1953: 
                   1954: =pod
                   1955: 
                   1956: =item crsenv
                   1957: 
1.105     matthew  1958: Show and set course data and parameters.  This is a large routine that should
1.59      matthew  1959: be simplified and shortened... someday.
                   1960: 
                   1961: Inputs: $r
                   1962: 
                   1963: Returns: nothing
                   1964: 
                   1965: =cut
                   1966: 
                   1967: ##################################################
                   1968: ##################################################
1.30      www      1969: sub crsenv {
                   1970:     my $r=shift;
                   1971:     my $setoutput='';
1.280     albertel 1972: 
1.298     albertel 1973:     my $breadcrumbs = 
                   1974: 	&Apache::lonhtmlcommon::breadcrumbs('Edit Course Environment');
1.190     albertel 1975:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   1976:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.105     matthew  1977: 
                   1978:     #
                   1979:     # Go through list of changes
1.190     albertel 1980:     foreach (keys %env) {
1.105     matthew  1981:         next if ($_!~/^form\.(.+)\_setparmval$/);
                   1982:         my $name  = $1;
1.190     albertel 1983:         my $value = $env{'form.'.$name.'_value'};
1.105     matthew  1984:         if ($name eq 'newp') {
1.190     albertel 1985:             $name = $env{'form.newp_name'};
1.105     matthew  1986:         }
                   1987:         if ($name eq 'url') {
                   1988:             $value=~s/^\/res\///;
                   1989:             my $bkuptime=time;
                   1990:             my @tmp = &Apache::lonnet::get
                   1991:                 ('environment',['url'],$dom,$crs);
1.130     www      1992:             $setoutput.=&mt('Backing up previous URL').': '.
1.105     matthew  1993:                 &Apache::lonnet::put
                   1994:                 ('environment',
                   1995:                  {'top level map backup '.$bkuptime => $tmp[1] },
                   1996:                  $dom,$crs).
                   1997:                      '<br>';
                   1998:         }
                   1999:         #
                   2000:         # Deal with modified default spreadsheets
                   2001:         if ($name =~ /^spreadsheet_default_(classcalc|
                   2002:                                             studentcalc|
                   2003:                                             assesscalc)$/x) {
                   2004:             my $sheettype = $1; 
                   2005:             if ($sheettype eq 'classcalc') {
                   2006:                 # no need to do anything since viewing the sheet will
                   2007:                 # cause it to be updated. 
                   2008:             } elsif ($sheettype eq 'studentcalc') {
                   2009:                 # expire all the student spreadsheets
                   2010:                 &Apache::lonnet::expirespread('','','studentcalc');
                   2011:             } else {
                   2012:                 # expire all the assessment spreadsheets 
                   2013:                 #    this includes non-default spreadsheets, but better to
                   2014:                 #    be safe than sorry.
                   2015:                 &Apache::lonnet::expirespread('','','assesscalc');
                   2016:                 # expire all the student spreadsheets
                   2017:                 &Apache::lonnet::expirespread('','','studentcalc');
1.30      www      2018:             }
1.105     matthew  2019:         }
                   2020:         #
1.107     matthew  2021:         # Deal with the enrollment dates
                   2022:         if ($name =~ /^default_enrollment_(start|end)_date$/) {
                   2023:             $value=&Apache::lonhtmlcommon::get_date_from_form($name.'_value');
                   2024:         }
1.178     raeburn  2025:         # Get existing cloners
                   2026:         my @oldcloner = ();
                   2027:         if ($name eq 'cloners') {
                   2028:             my %clonenames=&Apache::lonnet::dump('environment',$dom,$crs,'cloners');
                   2029:             if ($clonenames{'cloners'} =~ /,/) {
                   2030:                 @oldcloner = split/,/,$clonenames{'cloners'};
                   2031:             } else {
                   2032:                 $oldcloner[0] = $clonenames{'cloners'};
                   2033:             }
                   2034:         }
1.107     matthew  2035:         #
1.105     matthew  2036:         # Let the user know we made the changes
1.153     albertel 2037:         if ($name && defined($value)) {
1.239     raeburn  2038:             my $failed_cloners;
1.178     raeburn  2039:             if ($name eq 'cloners') {
1.239     raeburn  2040:                 $value =~ s/\s//g;
1.178     raeburn  2041:                 $value =~ s/^,//;
                   2042:                 $value =~ s/,$//;
1.239     raeburn  2043:                 # check requested clones are valid users.
                   2044:                 $failed_cloners = &check_cloners(\$value,\@oldcloner);
1.178     raeburn  2045:             }
1.105     matthew  2046:             my $put_result = &Apache::lonnet::put('environment',
                   2047:                                                   {$name=>$value},$dom,$crs);
                   2048:             if ($put_result eq 'ok') {
1.130     www      2049:                 $setoutput.=&mt('Set').' <b>'.$name.'</b> '.&mt('to').' <b>'.$value.'</b>.<br />';
1.178     raeburn  2050:                 if ($name eq 'cloners') {
                   2051:                     &change_clone($value,\@oldcloner);
                   2052:                 }
1.179     raeburn  2053:                 # Flush the course logs so course description is immediately updated
                   2054:                 if ($name eq 'description' && defined($value)) {
                   2055:                     &Apache::lonnet::flushcourselogs();
                   2056:                 }
1.105     matthew  2057:             } else {
1.130     www      2058:                 $setoutput.=&mt('Unable to set').' <b>'.$name.'</b> '.&mt('to').
                   2059: 		    ' <b>'.$value.'</b> '.&mt('due to').' '.$put_result.'.<br />';
1.30      www      2060:             }
1.239     raeburn  2061:             if (($name eq 'cloners') && ($failed_cloners)) {
                   2062:                 $setoutput.= &mt('Unable to include').' - <b>'.$failed_cloners.'</b>, '.
                   2063:                  &mt('reason').' - '.&mt('LON-CAPA user(s) do(es) not exist').
                   2064:                  '.<br />'.&mt('Please ').
                   2065:                  ' <a href="/adm/createuser">'.
                   2066:                  &mt('add the user(s)').'</a>, '.
                   2067:                  &mt('and then return to the ').
                   2068:                  '<a href="/admparmset?action=crsenv">'.
                   2069:                  &mt('Course Parameters page').'</a> '.
                   2070:                  &mt('to add the new user(s) to the list of possible cloners').
                   2071:                  '.<br />';
                   2072:             }
1.30      www      2073:         }
1.38      harris41 2074:     }
1.108     www      2075: # ------------------------- Re-init course environment entries for this session
                   2076: 
1.302     albertel 2077:     &Apache::lonnet::coursedescription($env{'request.course.id'},
1.296     albertel 2078: 				       {'freshen_cache' => 1});
1.105     matthew  2079: 
1.30      www      2080: # -------------------------------------------------------- Get parameters again
1.45      matthew  2081: 
                   2082:     my %values=&Apache::lonnet::dump('environment',$dom,$crs);
1.140     sakharuk 2083:     my $SelectStyleFile=&mt('Select Style File');
1.141     sakharuk 2084:     my $SelectSpreadsheetFile=&mt('Select Spreadsheet File');
1.30      www      2085:     my $output='';
1.45      matthew  2086:     if (! exists($values{'con_lost'})) {
1.30      www      2087:         my %descriptions=
1.140     sakharuk 2088: 	    ('url'            => '<b>'.&mt('Top Level Map').'</b> '.
1.46      matthew  2089:                                  '<a href="javascript:openbrowser'.
1.47      matthew  2090:                                  "('envform','url','sequence')\">".
1.140     sakharuk 2091:                                  &mt('Select Map').'</a><br /><font color=red> '.
                   2092:                                  &mt('Modification may make assessment data inaccessible').
                   2093:                                  '</font>',
                   2094:              'description'    => '<b>'.&mt('Course Description').'</b>',
1.158     sakharuk 2095:              'courseid'       => '<b>'.&mt('Course ID or number').
1.140     sakharuk 2096:                                  '</b><br />'.
                   2097:                                  '('.&mt('internal').', '.&mt('optional').')',
1.177     raeburn  2098:              'cloners'        => '<b>'.&mt('Users allowed to clone course').'</b><br /><tt>(user:domain,user:domain)</tt><br />'.&mt('Users with active Course Coordinator role in the course automatically have the right to clone it, and can be omitted from list.'),
1.150     www      2099:              'grading'        => '<b>'.&mt('Grading').'</b><br />'.
                   2100:                                  '<tt>"standard", "external", or "spreadsheet"</tt> '.&Apache::loncommon::help_open_topic('GradingOptions'),
1.140     sakharuk 2101:              'default_xml_style' => '<b>'.&mt('Default XML Style File').'</b> '.
1.52      www      2102:                     '<a href="javascript:openbrowser'.
                   2103:                     "('envform','default_xml_style'".
1.140     sakharuk 2104:                     ",'sty')\">$SelectStyleFile</a><br>",
1.141     sakharuk 2105:              'question.email' => '<b>'.&mt('Feedback Addresses for Resource Content Question').
                   2106:                                  '</b><br />(<tt>user:domain,'.
1.74      www      2107:                                  'user:domain(section;section;...;*;...),...</tt>)',
1.141     sakharuk 2108:              'comment.email'  => '<b>'.&mt('Feedback Addresses for Course Content Comments').'</b><br />'.
1.74      www      2109:                                  '(<tt>user:domain,user:domain(section;section;...;*;...),...</tt>)',
1.141     sakharuk 2110:              'policy.email'   => '<b>'.&mt('Feedback Addresses for Course Policy').'</b>'.
1.75      albertel 2111:                                  '<br />(<tt>user:domain,user:domain(section;section;...;*;...),...</tt>)',
1.141     sakharuk 2112:              'hideemptyrows'  => '<b>'.&mt('Hide Empty Rows in Spreadsheets').'</b><br />'.
1.158     sakharuk 2113:                                  '('.&mt('"[_1]" for default hiding','<tt>yes</tt>').')',
1.141     sakharuk 2114:              'pageseparators'  => '<b>'.&mt('Visibly Separate Items on Pages').'</b><br />'.
1.158     sakharuk 2115:                                  '('.&mt('"[_1]" for visible separation','<tt>yes</tt>').', '.
1.141     sakharuk 2116:                                  &mt('changes will not show until next login').')',
1.169     matthew  2117:              'student_classlist_view' => '<b>'.&mt('Allow students to view classlist.').'</b>'.&mt('("all":students can view all sections,"section":students can only view their own section.blank or "disabled" prevents student view.'),
1.118     matthew  2118: 
1.141     sakharuk 2119:              'plc.roles.denied'=> '<b>'.&mt('Disallow live chatroom use for Roles').
                   2120:                                   '</b><br />"<tt>st</tt>": '.
1.158     sakharuk 2121:                                   &mt('student').', "<tt>ta</tt>": '.
1.118     matthew  2122:                                   'TA, "<tt>in</tt>": '.
1.158     sakharuk 2123:                                   &mt('instructor').';<br /><tt>'.&mt('role,role,...').'</tt>) '.
1.118     matthew  2124: 	       Apache::loncommon::help_open_topic("Course_Disable_Discussion"),
                   2125:              'plc.users.denied' => 
1.141     sakharuk 2126:                           '<b>'.&mt('Disallow live chatroom use for Users').'</b><br />'.
1.118     matthew  2127:                                  '(<tt>user:domain,user:domain,...</tt>)',
                   2128: 
1.141     sakharuk 2129:              'pch.roles.denied'=> '<b>'.&mt('Disallow Resource Discussion for Roles').
                   2130:                                   '</b><br />"<tt>st</tt>": '.
1.61      albertel 2131:                                   'student, "<tt>ta</tt>": '.
                   2132:                                   'TA, "<tt>in</tt>": '.
1.75      albertel 2133:                                   'instructor;<br /><tt>role,role,...</tt>) '.
1.61      albertel 2134: 	       Apache::loncommon::help_open_topic("Course_Disable_Discussion"),
1.53      www      2135:              'pch.users.denied' => 
1.141     sakharuk 2136:                           '<b>'.&mt('Disallow Resource Discussion for Users').'</b><br />'.
1.53      www      2137:                                  '(<tt>user:domain,user:domain,...</tt>)',
1.49      matthew  2138:              'spreadsheet_default_classcalc' 
1.141     sakharuk 2139:                  => '<b>'.&mt('Default Course Spreadsheet').'</b> '.
1.50      matthew  2140:                     '<a href="javascript:openbrowser'.
                   2141:                     "('envform','spreadsheet_default_classcalc'".
1.141     sakharuk 2142:                     ",'spreadsheet')\">$SelectSpreadsheetFile</a><br />",
1.49      matthew  2143:              'spreadsheet_default_studentcalc' 
1.141     sakharuk 2144:                  => '<b>'.&mt('Default Student Spreadsheet').'</b> '.
1.50      matthew  2145:                     '<a href="javascript:openbrowser'.
                   2146:                     "('envform','spreadsheet_default_calc'".
1.141     sakharuk 2147:                     ",'spreadsheet')\">$SelectSpreadsheetFile</a><br />",
1.49      matthew  2148:              'spreadsheet_default_assesscalc' 
1.141     sakharuk 2149:                  => '<b>'.&mt('Default Assessment Spreadsheet').'</b> '.
1.50      matthew  2150:                     '<a href="javascript:openbrowser'.
                   2151:                     "('envform','spreadsheet_default_assesscalc'".
1.141     sakharuk 2152:                     ",'spreadsheet')\">$SelectSpreadsheetFile</a><br />",
1.75      albertel 2153: 	     'allow_limited_html_in_feedback'
1.141     sakharuk 2154: 	         => '<b>'.&mt('Allow limited HTML in discussion posts').'</b><br />'.
1.158     sakharuk 2155: 	            '('.&mt('Set value to "[_1]" to allow',"<tt>yes</tt>").')',
1.170     raeburn  2156:              'allow_discussion_post_editing'
1.276     raeburn  2157:                  => '<b>'.&mt('Allow users with specified roles to edit/delete their own discussion posts').'</b><br />"<tt>st</tt>": '.
                   2158:                                   &mt('student').', "<tt>ta</tt>": '.
                   2159:                                   'TA, "<tt>in</tt>": '.
                   2160:                                   &mt('instructor').';&nbsp;(<tt>'.&mt('role:section,role:section,..., e.g., st:001,st:002,in,cc would permit students in sections 001 and 002 and instructors in any section, and course coordinators to edit their own posts.').'</tt>)<br />'.
                   2161:                     '('.&mt('or set value to "[_1]" to allow all roles',"<tt>yes</tt>").')',
1.89      albertel 2162: 	     'rndseed'
1.140     sakharuk 2163: 	         => '<b>'.&mt('Randomization algorithm used').'</b> <br />'.
                   2164:                     '<font color="red">'.&mt('Modifying this will make problems').' '.
                   2165:                     &mt('have different numbers and answers').'</font>',
1.151     albertel 2166: 	     'receiptalg'
                   2167: 	         => '<b>'.&mt('Receipt algorithm used').'</b> <br />'.
                   2168:                     &mt('This controls how receipt numbers are generated.'),
1.164     sakharuk 2169:              'suppress_tries'
1.272     albertel 2170:                  => '<b>'.&mt('Suppress number of tries in printing').'</b><br />'.
1.273     www      2171:                     ' ('.&mt('"[_1]" to suppress, anything else to not suppress','<tt>yes</tt>').')',
1.113     sakharuk 2172:              'problem_stream_switch'
1.141     sakharuk 2173:                  => '<b>'.&mt('Allow problems to be split over pages').'</b><br />'.
1.158     sakharuk 2174:                     ' ('.&mt('"[_1]" if allowed, anything else if not','<tt>yes</tt>').')',
1.161     sakharuk 2175:              'default_paper_size' 
                   2176:                  => '<b>'.&mt('Default paper type').'</b><br />'.
                   2177:                     ' ('.&mt('supported types').': Letter [8 1/2x11 in], Legal [8 1/2x14 in],'. 
                   2178:                     ' Tabloid [11x17 in], Executive [7 1/2x10 in], A2 [420x594 mm],'. 
                   2179:                     ' A3 [297x420 mm], A4 [210x297 mm], A5 [148x210 mm], A6 [105x148 mm])',
1.111     sakharuk 2180:              'anonymous_quiz'
1.150     www      2181:                  => '<b>'.&mt('Anonymous quiz/exam').'</b><br />'.
1.141     sakharuk 2182:                     ' (<tt><b>'.&mt('yes').'</b> '.&mt('to avoid print students names').' </tt>)',
1.217     albertel 2183:              'default_enrollment_start_date' => '<b>'.&mt('Default beginning date for student access.').'</b>',
                   2184:              'default_enrollment_end_date'   => '<b>'.&mt('Default ending date for student access.').'</b>',
1.150     www      2185:              'nothideprivileged'   => '<b>'.&mt('Privileged users that should not be hidden on staff listings').'</b>'.
                   2186:                                  '<br />(<tt>user:domain,user:domain,...</tt>)',
1.140     sakharuk 2187:              'languages' => '<b>'.&mt('Languages used').'</b>',
1.115     www      2188:              'disable_receipt_display'
1.141     sakharuk 2189:                  => '<b>'.&mt('Disable display of problem receipts').'</b><br />'.
1.158     sakharuk 2190:                     ' ('.&mt('"[_1]" to disable, anything else if not','<tt>yes</tt>').')',
1.163     albertel 2191: 	     'disablesigfigs'
                   2192: 	         => '<b>'.&mt('Disable checking of Significant Figures').'</b><br />'.
                   2193:                     ' ('.&mt('"[_1]" to disable, anything else if not','<tt>yes</tt>').')',
1.251     albertel 2194: 	     'disableexampointprint'
                   2195: 	         => '<b>'.&mt('Disable automatically printing point values onto exams.').'</b><br />'.
                   2196:                     ' ('.&mt('"[_1]" to disable, anything else if not','<tt>yes</tt>').')',
1.278     www      2197:              'externalsyllabus'
1.279     www      2198:                  => '<b>'.&mt('URL of Syllabus (not using internal handler)').'</b>',
1.149     albertel 2199: 	     'tthoptions'
                   2200: 	         => '<b>'.&mt('Default set of options to pass to tth/m when converting tex').'</b>'
1.107     matthew  2201:              ); 
1.177     raeburn  2202:         my @Display_Order = ('url','description','courseid','cloners','grading',
1.278     www      2203:                              'externalsyllabus',
1.107     matthew  2204:                              'default_xml_style','pageseparators',
                   2205:                              'question.email','comment.email','policy.email',
1.169     matthew  2206:                              'student_classlist_view',
1.118     matthew  2207:                              'plc.roles.denied','plc.users.denied',
1.107     matthew  2208:                              'pch.roles.denied','pch.users.denied',
                   2209:                              'allow_limited_html_in_feedback',
1.170     raeburn  2210:                              'allow_discussion_post_editing',
1.108     www      2211:                              'languages',
1.150     www      2212: 			     'nothideprivileged',
1.107     matthew  2213:                              'rndseed',
1.151     albertel 2214:                              'receiptalg',
1.107     matthew  2215:                              'problem_stream_switch',
1.164     sakharuk 2216: 			     'suppress_tries',
1.161     sakharuk 2217:                              'default_paper_size',
1.115     www      2218:                              'disable_receipt_display',
1.107     matthew  2219:                              'spreadsheet_default_classcalc',
                   2220:                              'spreadsheet_default_studentcalc',
                   2221:                              'spreadsheet_default_assesscalc', 
                   2222:                              'hideemptyrows',
                   2223:                              'default_enrollment_start_date',
                   2224:                              'default_enrollment_end_date',
1.163     albertel 2225: 			     'tthoptions',
1.251     albertel 2226: 			     'disablesigfigs',
                   2227: 			     'disableexampointprint'
1.107     matthew  2228:                              );
                   2229: 	foreach my $parameter (sort(keys(%values))) {
1.244     banghart 2230:             unless (($parameter =~ m/^internal\./)||($parameter =~ m/^metadata\./)) {
1.142     raeburn  2231:                 if (! $descriptions{$parameter}) {
                   2232:                     $descriptions{$parameter}=$parameter;
                   2233:                     push(@Display_Order,$parameter);
                   2234:                 }
                   2235:             }
1.43      albertel 2236: 	}
1.107     matthew  2237:         foreach my $parameter (@Display_Order) {
                   2238:             my $description = $descriptions{$parameter};
1.51      matthew  2239:             # onchange is javascript to automatically check the 'Set' button.
1.69      www      2240:             my $onchange = 'onFocus="javascript:window.document.forms'.
1.107     matthew  2241:                 "['envform'].elements['".$parameter."_setparmval']".
1.51      matthew  2242:                 '.checked=true;"';
1.107     matthew  2243:             $output .= '<tr><td>'.$description.'</td>';
                   2244:             if ($parameter =~ /^default_enrollment_(start|end)_date$/) {
                   2245:                 $output .= '<td>'.
                   2246:                     &Apache::lonhtmlcommon::date_setter('envform',
                   2247:                                                         $parameter.'_value',
                   2248:                                                         $values{$parameter},
                   2249:                                                         $onchange).
                   2250:                                                         '</td>';
                   2251:             } else {
                   2252:                 $output .= '<td>'.
                   2253:                     &Apache::lonhtmlcommon::textbox($parameter.'_value',
                   2254:                                                     $values{$parameter},
                   2255:                                                     40,$onchange).'</td>';
                   2256:             }
                   2257:             $output .= '<td>'.
                   2258:                 &Apache::lonhtmlcommon::checkbox($parameter.'_setparmval').
                   2259:                 '</td>';
                   2260:             $output .= "</tr>\n";
1.51      matthew  2261: 	}
1.69      www      2262:         my $onchange = 'onFocus="javascript:window.document.forms'.
1.51      matthew  2263:             '[\'envform\'].elements[\'newp_setparmval\']'.
                   2264:             '.checked=true;"';
1.130     www      2265: 	$output.='<tr><td><i>'.&mt('Create New Environment Variable').'</i><br />'.
1.51      matthew  2266: 	    '<input type="text" size=40 name="newp_name" '.
                   2267:                 $onchange.' /></td><td>'.
                   2268:             '<input type="text" size=40 name="newp_value" '.
                   2269:                 $onchange.' /></td><td>'.
                   2270: 	    '<input type="checkbox" name="newp_setparmval" /></td></tr>';
1.43      albertel 2271:     }
1.157     sakharuk 2272:     my %lt=&Apache::lonlocal::texthash(
                   2273: 		    'par'   => 'Parameter',
                   2274: 		    'val'   => 'Value',
                   2275: 		    'set'   => 'Set',
                   2276: 		    'sce'   => 'Set Course Environment'
                   2277: 				       );
                   2278: 
1.140     sakharuk 2279:     my $Parameter=&mt('Parameter');
                   2280:     my $Value=&mt('Value');
1.141     sakharuk 2281:     my $Set=&mt('Set');
1.280     albertel 2282:     my $browse_js=
                   2283: 	'<script type="text/javascript" language="Javascript">'.
                   2284: 	&Apache::loncommon::browser_and_searcher_javascript('parmset').
                   2285: 	'</script>';
                   2286:     
                   2287:     my $start_page = 
                   2288: 	&Apache::loncommon::start_page('Set Course Environment Parameters',
                   2289: 				       $browse_js);
                   2290:     my $end_page = 
                   2291: 	&Apache::loncommon::end_page();
                   2292:     $r->print(<<ENDENV);
                   2293: $start_page
1.193     albertel 2294: $breadcrumbs
                   2295: <form method="post" action="/adm/parmset?action=crsenv" name="envform">
1.30      www      2296: $setoutput
                   2297: <p>
                   2298: <table border=2>
1.157     sakharuk 2299: <tr><th>$lt{'par'}</th><th>$lt{'val'}</th><th>$lt{'set'}?</th></tr>
1.30      www      2300: $output
                   2301: </table>
1.157     sakharuk 2302: <input type="submit" name="crsenv" value="$lt{'sce'}">
1.30      www      2303: </form>
1.280     albertel 2304: $end_page
                   2305: ENDENV
1.30      www      2306: }
1.120     www      2307: ##################################################
1.207     www      2308: # Overview mode
                   2309: ##################################################
1.124     www      2310: my $tableopen;
                   2311: 
                   2312: sub tablestart {
                   2313:     if ($tableopen) {
                   2314: 	return '';
                   2315:     } else {
                   2316: 	$tableopen=1;
1.295     albertel 2317: 	return &Apache::loncommon::start_data_table().'<tr><th>'.&mt('Parameter').'</th><th>'.
1.130     www      2318: 	    &mt('Delete').'</th><th>'.&mt('Set to ...').'</th></tr>';
1.124     www      2319:     }
                   2320: }
                   2321: 
                   2322: sub tableend {
                   2323:     if ($tableopen) {
                   2324: 	$tableopen=0;
1.295     albertel 2325: 	return &Apache::loncommon::end_data_table();
1.124     www      2326:     } else {
                   2327: 	return'';
                   2328:     }
                   2329: }
                   2330: 
1.207     www      2331: sub readdata {
                   2332:     my ($crs,$dom)=@_;
                   2333: # Read coursedata
                   2334:     my $resourcedata=&Apache::lonnet::get_courseresdata($crs,$dom);
                   2335: # Read userdata
                   2336: 
                   2337:     my $classlist=&Apache::loncoursedata::get_classlist();
                   2338:     foreach (keys %$classlist) {
                   2339:         # the following undefs are for 'domain', and 'username' respectively.
                   2340:         if ($_=~/^(\w+)\:(\w+)$/) {
                   2341: 	    my ($tuname,$tudom)=($1,$2);
                   2342: 	    my $useropt=&Apache::lonnet::get_userresdata($tuname,$tudom);
                   2343:             foreach my $userkey (keys %{$useropt}) {
                   2344: 		if ($userkey=~/^$env{'request.course.id'}/) {
                   2345:                     my $newkey=$userkey;
                   2346: 		    $newkey=~s/^($env{'request.course.id'}\.)/$1\[useropt\:$tuname\:$tudom\]\./;
                   2347: 		    $$resourcedata{$newkey}=$$useropt{$userkey};
                   2348: 		}
                   2349: 	    }
                   2350: 	}
                   2351:     }
                   2352:     return $resourcedata;
                   2353: }
                   2354: 
                   2355: 
1.124     www      2356: # Setting
1.208     www      2357: 
                   2358: sub storedata {
                   2359:     my ($r,$crs,$dom)=@_;
1.207     www      2360: # Set userlevel immediately
                   2361: # Do an intermediate store of course level
                   2362:     my $olddata=&readdata($crs,$dom);
1.124     www      2363:     my %newdata=();
                   2364:     undef %newdata;
                   2365:     my @deldata=();
                   2366:     undef @deldata;
1.190     albertel 2367:     foreach (keys %env) {
1.124     www      2368: 	if ($_=~/^form\.([a-z]+)\_(.+)$/) {
                   2369: 	    my $cmd=$1;
                   2370: 	    my $thiskey=$2;
1.207     www      2371: 	    my ($tuname,$tudom)=&extractuser($thiskey);
                   2372: 	    my $tkey=$thiskey;
                   2373:             if ($tuname) {
                   2374: 		$tkey=~s/\.\[useropt\:$tuname\:$tudom\]\./\./;
                   2375: 	    }
1.124     www      2376: 	    if ($cmd eq 'set') {
1.190     albertel 2377: 		my $data=$env{$_};
1.212     www      2378:                 my $typeof=$env{'form.typeof_'.$thiskey};
                   2379:  		if ($$olddata{$thiskey} ne $data) { 
1.207     www      2380: 		    if ($tuname) {
1.212     www      2381: 			if (&Apache::lonnet::put('resourcedata',{$tkey=>$data,
                   2382: 								 $tkey.'.type' => $typeof},
                   2383: 						 $tudom,$tuname) eq 'ok') {
1.290     www      2384: 			    &log_parmset({$tkey=>$data,$tkey.'.type' => $typeof},0,$tuname,$tudom);
1.207     www      2385: 			    $r->print('<br />'.&mt('Stored modified parameter for').' '.
                   2386: 				      &Apache::loncommon::plainname($tuname,$tudom));
                   2387: 			} else {
                   2388: 			    $r->print('<h2><font color="red">'.
                   2389: 				      &mt('Error storing parameters').'</font></h2>');
                   2390: 			}
                   2391: 			&Apache::lonnet::devalidateuserresdata($tuname,$tudom);
                   2392: 		    } else {
                   2393: 			$newdata{$thiskey}=$data;
1.212     www      2394:  			$newdata{$thiskey.'.type'}=$typeof; 
                   2395:                    } 
1.207     www      2396: 		}
1.124     www      2397: 	    } elsif ($cmd eq 'del') {
1.207     www      2398: 		if ($tuname) {
                   2399: 		    if (&Apache::lonnet::del('resourcedata',[$tkey],$tudom,$tuname) eq 'ok') {
1.290     www      2400: 			    &log_parmset({$tkey=>''},1,$tuname,$tudom);
1.207     www      2401: 			$r->print('<br />'.&mt('Deleted parameter for').' '.&Apache::loncommon::plainname($tuname,$tudom));
                   2402: 		    } else {
                   2403: 			$r->print('<h2><font color="red">'.
                   2404: 				  &mt('Error deleting parameters').'</font></h2>');
                   2405: 		    }
                   2406: 		    &Apache::lonnet::devalidateuserresdata($tuname,$tudom);
                   2407: 		} else {
                   2408: 		    push (@deldata,$thiskey);
                   2409: 		}
1.124     www      2410: 	    } elsif ($cmd eq 'datepointer') {
1.190     albertel 2411: 		my $data=&Apache::lonhtmlcommon::get_date_from_form($env{$_});
1.212     www      2412:                 my $typeof=$env{'form.typeof_'.$thiskey};
1.207     www      2413: 		if (defined($data) and $$olddata{$thiskey} ne $data) { 
                   2414: 		    if ($tuname) {
1.212     www      2415: 			if (&Apache::lonnet::put('resourcedata',{$tkey=>$data,
                   2416: 								 $tkey.'.type' => $typeof},
                   2417: 						 $tudom,$tuname) eq 'ok') {
1.290     www      2418: 			    &log_parmset({$tkey=>$data,$tkey.'.type' => $typeof},0,$tuname,$tudom);
1.207     www      2419: 			    $r->print('<br />'.&mt('Stored modified date for').' '.&Apache::loncommon::plainname($tuname,$tudom));
                   2420: 			} else {
                   2421: 			    $r->print('<h2><font color="red">'.
                   2422: 				      &mt('Error storing parameters').'</font></h2>');
                   2423: 			}
                   2424: 			&Apache::lonnet::devalidateuserresdata($tuname,$tudom);
                   2425: 		    } else {
1.212     www      2426: 			$newdata{$thiskey}=$data;
                   2427: 			$newdata{$thiskey.'.type'}=$typeof; 
1.207     www      2428: 		    }
                   2429: 		}
1.124     www      2430: 	    }
                   2431: 	}
                   2432:     }
1.207     www      2433: # Store all course level
1.144     www      2434:     my $delentries=$#deldata+1;
                   2435:     my @newdatakeys=keys %newdata;
                   2436:     my $putentries=$#newdatakeys+1;
                   2437:     if ($delentries) {
                   2438: 	if (&Apache::lonnet::del('resourcedata',\@deldata,$dom,$crs) eq 'ok') {
1.290     www      2439: 	    my %loghash=map { $_ => '' } @deldata;
                   2440: 	    &log_parmset(\%loghash,1);
1.144     www      2441: 	    $r->print('<h2>'.&mt('Deleted [_1] parameter(s)</h2>',$delentries));
                   2442: 	} else {
                   2443: 	    $r->print('<h2><font color="red">'.
                   2444: 		      &mt('Error deleting parameters').'</font></h2>');
                   2445: 	}
1.205     www      2446: 	&Apache::lonnet::devalidatecourseresdata($crs,$dom);
1.144     www      2447:     }
                   2448:     if ($putentries) {
                   2449: 	if (&Apache::lonnet::put('resourcedata',\%newdata,$dom,$crs) eq 'ok') {
1.290     www      2450: 			    &log_parmset(\%newdata,0);
1.212     www      2451: 	    $r->print('<h3>'.&mt('Stored [_1] parameter(s)',$putentries/2).'</h3>');
1.144     www      2452: 	} else {
                   2453: 	    $r->print('<h2><font color="red">'.
                   2454: 		      &mt('Error storing parameters').'</font></h2>');
                   2455: 	}
1.205     www      2456: 	&Apache::lonnet::devalidatecourseresdata($crs,$dom);
1.144     www      2457:     }
1.208     www      2458: }
1.207     www      2459: 
1.208     www      2460: sub extractuser {
                   2461:     my $key=shift;
                   2462:     return ($key=~/^$env{'request.course.id'}.\[useropt\:(\w+)\:(\w+)\]\./);
                   2463: }
1.206     www      2464: 
1.208     www      2465: sub listdata {
1.214     www      2466:     my ($r,$resourcedata,$listdata,$sortorder)=@_;
1.207     www      2467: # Start list output
1.206     www      2468: 
1.122     www      2469:     my $oldsection='';
                   2470:     my $oldrealm='';
                   2471:     my $oldpart='';
1.123     www      2472:     my $pointer=0;
1.124     www      2473:     $tableopen=0;
1.145     www      2474:     my $foundkeys=0;
1.248     albertel 2475:     my %keyorder=&standardkeyorder();
1.214     www      2476:     foreach my $thiskey (sort {
                   2477: 	if ($sortorder eq 'realmstudent') {
1.247     albertel 2478: 	    my ($astudent,$arealm)=($a=~/^\Q$env{'request.course.id'}\E\.\[([^\.]+)\]\.(.+)\.[^\.]+$/);
                   2479: 	    my ($bstudent,$brealm)=($b=~/^\Q$env{'request.course.id'}\E\.\[([^\.]+)\]\.(.+)\.[^\.]+$/);
                   2480: 	    if (!defined($astudent)) {
                   2481: 		($arealm)=($a=~/^\Q$env{'request.course.id'}\E\.(.+)$/);
1.237     albertel 2482: 	    }
1.247     albertel 2483: 	    if (!defined($bstudent)) {
                   2484: 		($brealm)=($b=~/^\Q$env{'request.course.id'}\E\.(.+)$/);
                   2485: 	    }
1.248     albertel 2486: 	    $arealm=~s/\.type//;
                   2487: 	    my ($ares, $aparm) = ($arealm=~/^(.*)\.(.*)$/);
                   2488: 	    $aparm=$keyorder{'parameter_0_'.$aparm};
                   2489: 	    $brealm=~s/\.type//;
                   2490: 	    my ($bres, $bparm) = ($brealm=~/^(.*)\.(.*)$/);
                   2491: 	    $bparm=$keyorder{'parameter_0_'.$bparm};	   
                   2492: 	    if ($ares eq $bres) {
                   2493: 		if (defined($aparm) && defined($bparm)) {
                   2494: 		    ($aparm <=> $bparm);
                   2495: 		} elsif (defined($aparm)) {
                   2496: 		    -1;
                   2497: 		} elsif (defined($bparm)) {
                   2498: 		    1;
                   2499: 		} else {
                   2500: 		    ($arealm cmp $brealm) || ($astudent cmp $bstudent);
                   2501: 		}
                   2502: 	    } else {
                   2503: 		($arealm cmp $brealm) || ($astudent cmp $bstudent);
                   2504: 	    }
1.214     www      2505: 	} else {
                   2506: 	    $a cmp $b;
                   2507: 	}
                   2508:     } keys %{$listdata}) {
1.247     albertel 2509: 	 
1.211     www      2510: 	if ($$listdata{$thiskey.'.type'}) {
                   2511:             my $thistype=$$listdata{$thiskey.'.type'};
                   2512:             if ($$resourcedata{$thiskey.'.type'}) {
                   2513: 		$thistype=$$resourcedata{$thiskey.'.type'};
                   2514: 	    }
1.207     www      2515: 	    my ($middle,$part,$name)=
                   2516: 		($thiskey=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s]+)\.(\w+)$/);
1.130     www      2517: 	    my $section=&mt('All Students');
1.207     www      2518: 	    if ($middle=~/^\[(.*)\]/) {
1.206     www      2519: 		my $issection=$1;
                   2520: 		if ($issection=~/^useropt\:(\w+)\:(\w+)/) {
                   2521: 		    $section=&mt('User').": ".&Apache::loncommon::plainname($1,$2);
                   2522: 		} else {
                   2523: 		    $section=&mt('Group/Section').': '.$issection;
                   2524: 		}
1.207     www      2525: 		$middle=~s/^\[(.*)\]//;
1.122     www      2526: 	    }
1.207     www      2527: 	    $middle=~s/\.+$//;
                   2528: 	    $middle=~s/^\.+//;
1.130     www      2529: 	    my $realm='<font color="red">'.&mt('All Resources').'</font>';
1.122     www      2530: 	    if ($middle=~/^(.+)\_\_\_\(all\)$/) {
1.174     albertel 2531: 		$realm='<font color="green">'.&mt('Folder/Map').': '.&Apache::lonnet::gettitle($1).' <br /><font color="#aaaaaa" size="-2">('.$1.')</font></font>';
1.122     www      2532: 	    } elsif ($middle) {
1.174     albertel 2533: 		my ($map,$id,$url)=&Apache::lonnet::decode_symb($middle);
                   2534: 		$realm='<font color="orange">'.&mt('Resource').': '.&Apache::lonnet::gettitle($middle).' <br /><font color="#aaaaaa" size="-2">('.$url.' in '.$map.' id: '.$id.')</font></font>';
1.122     www      2535: 	    }
1.214     www      2536: 	    if ($sortorder eq 'realmstudent') {
                   2537: 		if ($realm ne $oldrealm) {
                   2538: 		    $r->print(&tableend()."\n<hr /><h1>$realm</h1>");
                   2539: 		    $oldrealm=$realm;
                   2540: 		    $oldsection='';
                   2541: 		}
                   2542: 		if ($section ne $oldsection) {
                   2543: 		    $r->print(&tableend()."\n<h2>$section</h2>");
                   2544: 		    $oldsection=$section;
                   2545: 		    $oldpart='';
                   2546: 		}
                   2547: 	    } else {
                   2548: 		if ($section ne $oldsection) {
                   2549: 		    $r->print(&tableend()."\n<hr /><h1>$section</h1>");
                   2550: 		    $oldsection=$section;
                   2551: 		    $oldrealm='';
                   2552: 		}
                   2553: 		if ($realm ne $oldrealm) {
                   2554: 		    $r->print(&tableend()."\n<h2>$realm</h2>");
                   2555: 		    $oldrealm=$realm;
                   2556: 		    $oldpart='';
                   2557: 		}
1.122     www      2558: 	    }
                   2559: 	    if ($part ne $oldpart) {
1.124     www      2560: 		$r->print(&tableend().
1.214     www      2561: 			  "\n<font color='blue'>".&mt('Part').": $part</font>");
1.122     www      2562: 		$oldpart=$part;
                   2563: 	    }
1.123     www      2564: #
1.230     www      2565: # Preset defaults?
                   2566: #
                   2567:             my ($hour,$min,$sec,$val)=('','','','');
                   2568: 	    unless ($$resourcedata{$thiskey}) {
                   2569: 		my ($parmname)=($thiskey=~/\.(\w+)$/);
                   2570: 		($hour,$min,$sec,$val)=&preset_defaults($parmname);
                   2571: 	    }
                   2572: 
                   2573: #
1.123     www      2574: # Ready to print
                   2575: #
1.295     albertel 2576: 	    $r->print(&tablestart().
                   2577: 		      &Apache::loncommon::start_data_table_row().
                   2578: 		      '<td><b>'.&standard_parameter_names($name).
1.293     www      2579: 		      '</b></td><td><input type="checkbox" name="del_'.
1.124     www      2580: 		      $thiskey.'" /></td><td>');
1.145     www      2581: 	    $foundkeys++;
1.213     www      2582: 	    if (&isdateparm($thistype)) {
1.123     www      2583: 		my $jskey='key_'.$pointer;
                   2584: 		$pointer++;
                   2585: 		$r->print(
1.232     albertel 2586: 			  &Apache::lonhtmlcommon::date_setter('parmform',
1.123     www      2587: 							      $jskey,
1.219     www      2588: 						      $$resourcedata{$thiskey},
1.230     www      2589: 							      '',1,'','',$hour,$min,$sec).
1.277     www      2590: '<input type="hidden" name="datepointer_'.$thiskey.'" value="'.$jskey.'" />'.
                   2591: &date_sanity_info($$resourcedata{$thiskey})
1.123     www      2592: 			  );
1.219     www      2593: 	    } elsif ($thistype eq 'string_yesno') {
1.230     www      2594: 		my $showval;
                   2595: 		if (defined($$resourcedata{$thiskey})) {
                   2596: 		    $showval=$$resourcedata{$thiskey};
                   2597: 		} else {
                   2598: 		    $showval=$val;
                   2599: 		}
1.219     www      2600: 		$r->print('<label><input type="radio" name="set_'.$thiskey.
                   2601: 			  '" value="yes"');
1.230     www      2602: 		if ($showval eq 'yes') {
1.219     www      2603: 		    $r->print(' checked="checked"');
                   2604: 		}
                   2605:                 $r->print(' />'.&mt('Yes').'</label> ');
                   2606: 		$r->print('<label><input type="radio" name="set_'.$thiskey.
                   2607: 			  '" value="no"');
1.230     www      2608: 		if ($showval eq 'no') {
1.219     www      2609: 		    $r->print(' checked="checked"');
                   2610: 		}
                   2611:                 $r->print(' />'.&mt('No').'</label>');
1.123     www      2612: 	    } else {
1.230     www      2613: 		my $showval;
                   2614: 		if (defined($$resourcedata{$thiskey})) {
                   2615: 		    $showval=$$resourcedata{$thiskey};
                   2616: 		} else {
                   2617: 		    $showval=$val;
                   2618: 		}
1.211     www      2619: 		$r->print('<input type="text" name="set_'.$thiskey.'" value="'.
1.230     www      2620: 			  $showval.'">');
1.123     www      2621: 	    }
1.211     www      2622: 	    $r->print('<input type="hidden" name="typeof_'.$thiskey.'" value="'.
                   2623: 		      $thistype.'">');
1.295     albertel 2624: 	    $r->print('</td>'.&Apache::loncommon::end_data_table_row());
1.122     www      2625: 	}
1.121     www      2626:     }
1.208     www      2627:     return $foundkeys;
                   2628: }
                   2629: 
                   2630: sub newoverview {
1.280     albertel 2631:     my ($r) = @_;
                   2632: 
1.208     www      2633:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   2634:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.280     albertel 2635:     my $start_page = &Apache::loncommon::start_page('Set Parameters');
1.298     albertel 2636:     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview');
1.208     www      2637:     $r->print(<<ENDOVER);
1.280     albertel 2638: $start_page
1.208     www      2639: $breadcrumbs
1.232     albertel 2640: <form method="post" action="/adm/parmset?action=newoverview" name="parmform">
1.208     www      2641: ENDOVER
1.211     www      2642:     my @ids=();
                   2643:     my %typep=();
                   2644:     my %keyp=();
                   2645:     my %allparms=();
                   2646:     my %allparts=();
                   2647:     my %allmaps=();
                   2648:     my %mapp=();
                   2649:     my %symbp=();
                   2650:     my %maptitles=();
                   2651:     my %uris=();
                   2652:     my %keyorder=&standardkeyorder();
                   2653:     my %defkeytype=();
                   2654: 
                   2655:     my %alllevs=();
                   2656:     $alllevs{'Resource Level'}='full';
1.215     www      2657:     $alllevs{'Map/Folder Level'}='map';
1.211     www      2658:     $alllevs{'Course Level'}='general';
                   2659: 
                   2660:     my $csec=$env{'form.csec'};
1.269     raeburn  2661:     my $cgroup=$env{'form.cgroup'};
1.211     www      2662: 
                   2663:     my @pscat=&Apache::loncommon::get_env_multiple('form.pscat');
                   2664:     my $pschp=$env{'form.pschp'};
                   2665:     my @psprt=&Apache::loncommon::get_env_multiple('form.psprt');
                   2666:     if (!@psprt) { $psprt[0]='0'; }
                   2667: 
                   2668:     my @selected_sections = 
                   2669: 	&Apache::loncommon::get_env_multiple('form.Section');
                   2670:     @selected_sections = ('all') if (! @selected_sections);
                   2671:     foreach (@selected_sections) {
                   2672:         if ($_ eq 'all') {
                   2673:             @selected_sections = ('all');
                   2674:         }
                   2675:     }
1.269     raeburn  2676:     my @selected_groups =
                   2677:         &Apache::loncommon::get_env_multiple('form.Group');
1.211     www      2678: 
                   2679:     my $pssymb='';
                   2680:     my $parmlev='';
                   2681:  
                   2682:     unless ($env{'form.parmlev'}) {
                   2683:         $parmlev = 'map';
                   2684:     } else {
                   2685:         $parmlev = $env{'form.parmlev'};
                   2686:     }
                   2687: 
                   2688:     &extractResourceInformation(\@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allmaps, 
                   2689: 				\%mapp, \%symbp,\%maptitles,\%uris,
                   2690: 				\%keyorder,\%defkeytype);
                   2691: 
                   2692: # Menu to select levels, etc
                   2693: 
                   2694:     $r->print('<table border="1"><tr><td>');
                   2695:     &levelmenu($r,\%alllevs,$parmlev);
                   2696:     if ($parmlev ne 'general') {
                   2697: 	$r->print('<td>');
                   2698: 	&mapmenu($r,\%allmaps,$pschp,\%maptitles);
                   2699: 	$r->print('</td>');
                   2700:     }
                   2701:     $r->print('</td></tr></table>');
                   2702: 
                   2703:     $r->print('<table border="1"><tr><td>');  
                   2704:     &parmmenu($r,\%allparms,\@pscat,\%keyorder);
1.269     raeburn  2705:     $r->print('</td><td><table border="0" cellspacing="0" cellpadding="0">'.
                   2706:               '<tr><td>'.&mt('Parts').'</td><td></td><td>'.&mt('Section(s)').
                   2707:               '</td><td></td><td>'.&mt('Group(s)').'</td></tr><tr><td>');
1.211     www      2708:     &partmenu($r,\%allparts,\@psprt);
1.269     raeburn  2709:     $r->print('</td><td>&nbsp;</td><td>');
1.211     www      2710:     &sectionmenu($r,\@selected_sections);
1.269     raeburn  2711:     $r->print('</td><td>&nbsp;</td><td>');
                   2712:     &groupmenu($r,\@selected_groups);
                   2713:     $r->print('</td></tr></table>');
1.214     www      2714:     $r->print('</td></tr></table>');
                   2715:  
                   2716:     my $sortorder=$env{'form.sortorder'};
                   2717:     unless ($sortorder) { $sortorder='realmstudent'; }
                   2718:     &sortmenu($r,$sortorder);
                   2719: 
                   2720:     $r->print('<p><input type="submit" name="dis" value="'.&mt('Display').'" /></p>');
1.211     www      2721: 
                   2722: # Build the list data hash from the specified parms
                   2723: 
                   2724:     my $listdata;
                   2725:     %{$listdata}=();
                   2726: 
                   2727:     foreach my $cat (@pscat) {
1.269     raeburn  2728:         &secgroup_lister($cat,$pschp,$parmlev,$listdata,\@psprt,\@selected_sections,\%defkeytype,\%allmaps,\@ids,\%symbp);
                   2729:         &secgroup_lister($cat,$pschp,$parmlev,$listdata,\@psprt,\@selected_groups,\%defkeytype,\%allmaps,\@ids,\%symbp);
1.211     www      2730:     }
                   2731: 
1.212     www      2732:     if (($env{'form.store'}) || ($env{'form.dis'})) {
1.211     www      2733: 
1.212     www      2734: 	if ($env{'form.store'}) { &storedata($r,$crs,$dom); }
1.211     www      2735: 
                   2736: # Read modified data
                   2737: 
                   2738: 	my $resourcedata=&readdata($crs,$dom);
                   2739: 
                   2740: # List data
                   2741: 
1.214     www      2742: 	&listdata($r,$resourcedata,$listdata,$sortorder);
1.211     www      2743:     }
                   2744:     $r->print(&tableend().
1.212     www      2745: 	     ((($env{'form.store'}) || ($env{'form.dis'}))?'<p><input type="submit" name="store" value="'.&mt('Store').'" /></p>':'').
1.280     albertel 2746: 	      '</form>'.&Apache::loncommon::end_page());
1.208     www      2747: }
                   2748: 
1.269     raeburn  2749: sub secgroup_lister {
                   2750:     my ($cat,$pschp,$parmlev,$listdata,$psprt,$selections,$defkeytype,$allmaps,$ids,$symbp) = @_;
                   2751:     foreach my $item (@{$selections}) {
                   2752:         foreach my $part (@{$psprt}) {
                   2753:             my $rootparmkey=$env{'request.course.id'};
                   2754:             if (($item ne 'all') && ($item ne 'none') && ($item)) {
                   2755:                 $rootparmkey.='.['.$item.']';
                   2756:             }
                   2757:             if ($parmlev eq 'general') {
                   2758: # course-level parameter
                   2759:                 my $newparmkey=$rootparmkey.'.'.$part.'.'.$cat;
                   2760:                 $$listdata{$newparmkey}=1;
                   2761:                 $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
                   2762:             } elsif ($parmlev eq 'map') {
                   2763: # map-level parameter
                   2764:                 foreach my $mapid (keys %{$allmaps}) {
                   2765:                     if (($pschp ne 'all') && ($pschp ne $mapid)) { next; }
                   2766:                     my $newparmkey=$rootparmkey.'.'.$$allmaps{$mapid}.'___(all).'.$part.'.'.$cat;
                   2767:                     $$listdata{$newparmkey}=1;
                   2768:                     $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
                   2769:                 }
                   2770:             } else {
                   2771: # resource-level parameter
                   2772:                 foreach my $rid (@{$ids}) {
                   2773:                     my ($map,$resid,$url)=&Apache::lonnet::decode_symb($$symbp{$rid});
                   2774:                     if (($pschp ne 'all') && ($$allmaps{$pschp} ne $map)) { next; }
                   2775:                     my $newparmkey=$rootparmkey.'.'.$$symbp{$rid}.'.'.$part.'.'.$cat;
                   2776:                     $$listdata{$newparmkey}=1;
                   2777:                     $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
                   2778:                 }
                   2779:             }
                   2780:         }
                   2781:     }
                   2782: }
                   2783: 
1.208     www      2784: sub overview {
1.280     albertel 2785:     my ($r) = @_;
1.208     www      2786:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   2787:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.280     albertel 2788: 
                   2789:     my $start_page=&Apache::loncommon::start_page('Modify Parameters');
1.298     albertel 2790:     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview');
1.208     www      2791:     $r->print(<<ENDOVER);
1.280     albertel 2792: $start_page
1.208     www      2793: $breadcrumbs
1.232     albertel 2794: <form method="post" action="/adm/parmset?action=setoverview" name="parmform">
1.208     www      2795: ENDOVER
                   2796: # Store modified
                   2797: 
                   2798:     &storedata($r,$crs,$dom);
                   2799: 
                   2800: # Read modified data
                   2801: 
                   2802:     my $resourcedata=&readdata($crs,$dom);
                   2803: 
1.214     www      2804: 
                   2805:     my $sortorder=$env{'form.sortorder'};
                   2806:     unless ($sortorder) { $sortorder='realmstudent'; }
                   2807:     &sortmenu($r,$sortorder);
                   2808: 
1.208     www      2809: # List data
                   2810: 
1.214     www      2811:     my $foundkeys=&listdata($r,$resourcedata,$resourcedata,$sortorder);
1.208     www      2812: 
1.145     www      2813:     $r->print(&tableend().'<p>'.
1.280     albertel 2814: 	($foundkeys?'<input type="submit" value="'.&mt('Modify Parameters').'" />':&mt('There are no parameters.')).'</p></form>'.
                   2815: 	      &Apache::loncommon::end_page());
1.120     www      2816: }
1.121     www      2817: 
1.59      matthew  2818: ##################################################
                   2819: ##################################################
1.178     raeburn  2820:                                                                                             
                   2821: =pod
1.239     raeburn  2822: 
                   2823: =item check_cloners
                   2824: 
                   2825: Checks if new users included in list of allowed cloners
                   2826: are valid users.  Replaces supplied list with 
                   2827: cleaned list containing only users with valid usernames
                   2828: and domains.
                   2829: 
                   2830: Inputs: $clonelist, $oldcloner 
                   2831: where $clonelist is ref to array of requested cloners,
                   2832: and $oldcloner is ref to array of currently allowed
                   2833: cloners.
                   2834: 
                   2835: Returns: string - comma separated list of requested
                   2836: cloners (username:domain) who do not exist in system.
                   2837: 
                   2838: =item change_clone
                   2839: 
1.178     raeburn  2840: Modifies the list of courses a user can clone (stored
1.239     raeburn  2841: in the user's environment.db file), called when a
1.178     raeburn  2842: change is made to the list of users allowed to clone
                   2843: a course.
1.239     raeburn  2844: 
1.178     raeburn  2845: Inputs: $action,$cloner
                   2846: where $action is add or drop, and $cloner is identity of 
                   2847: user for whom cloning ability is to be changed in course. 
                   2848: 
                   2849: =cut
                   2850:                                                                                             
                   2851: ##################################################
                   2852: ##################################################
                   2853: 
1.239     raeburn  2854: sub extract_cloners {
                   2855:     my ($clonelist,$allowclone) = @_;
                   2856:     if ($clonelist =~ /,/) {
                   2857:         @{$allowclone} = split/,/,$clonelist;
                   2858:     } else {
                   2859:         $$allowclone[0] = $clonelist;
                   2860:     }
                   2861: }
                   2862: 
                   2863: 
                   2864: sub check_cloners {
                   2865:     my ($clonelist,$oldcloner) = @_;
                   2866:     my ($clean_clonelist,$disallowed);
                   2867:     my @allowclone = ();
                   2868:     &extract_cloners($$clonelist,\@allowclone);
                   2869:     foreach my $currclone (@allowclone) {
                   2870:         if (!grep/^$currclone$/,@$oldcloner) {
                   2871:             my ($uname,$udom) = split/:/,$currclone;
                   2872:             if ($uname && $udom) {
                   2873:                 if (&Apache::lonnet::homeserver($uname,$udom) eq 'no_host') {
                   2874:                     $disallowed .= $currclone.',';   
                   2875:                 } else {
                   2876:                     $clean_clonelist .= $currclone.',';
                   2877:                 }
                   2878:             }
                   2879:         } else {
                   2880:             $clean_clonelist .= $currclone.',';
                   2881:         }
                   2882:     }
                   2883:     if ($disallowed) {
                   2884:         $disallowed =~ s/,$//;
                   2885:     }
                   2886:     if ($clean_clonelist) {
                   2887:         $clean_clonelist =~ s/,$//;
                   2888:     }
                   2889:     $$clonelist = $clean_clonelist;
                   2890:     return $disallowed;
                   2891: }  
1.178     raeburn  2892: 
                   2893: sub change_clone {
                   2894:     my ($clonelist,$oldcloner) = @_;
                   2895:     my ($uname,$udom);
1.190     albertel 2896:     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                   2897:     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
1.178     raeburn  2898:     my $clone_crs = $cnum.':'.$cdom;
                   2899:     
                   2900:     if ($cnum && $cdom) {
1.239     raeburn  2901:         my @allowclone;
                   2902:         &extract_cloners($clonelist,\@allowclone);
1.178     raeburn  2903:         foreach my $currclone (@allowclone) {
                   2904:             if (!grep/^$currclone$/,@$oldcloner) {
                   2905:                 ($uname,$udom) = split/:/,$currclone;
                   2906:                 if ($uname && $udom) {
                   2907:                     unless (&Apache::lonnet::homeserver($uname,$udom) eq 'no_host') {
                   2908:                         my %currclonecrs = &Apache::lonnet::dump('environment',$udom,$uname,'cloneable');
                   2909:                         if ($currclonecrs{'cloneable'} !~ /\Q$clone_crs\E/) {
                   2910:                             if ($currclonecrs{'cloneable'} eq '') {
                   2911:                                 $currclonecrs{'cloneable'} = $clone_crs;
                   2912:                             } else {
                   2913:                                 $currclonecrs{'cloneable'} .= ','.$clone_crs;
                   2914:                             }
                   2915:                             &Apache::lonnet::put('environment',\%currclonecrs,$udom,$uname);
                   2916:                         }
                   2917:                     }
                   2918:                 }
                   2919:             }
                   2920:         }
                   2921:         foreach my $oldclone (@$oldcloner) {
                   2922:             if (!grep/^$oldclone$/,@allowclone) {
                   2923:                 ($uname,$udom) = split/:/,$oldclone;
                   2924:                 if ($uname && $udom) {
                   2925:                     unless (&Apache::lonnet::homeserver($uname,$udom) eq 'no_host') {
                   2926:                         my %currclonecrs = &Apache::lonnet::dump('environment',$udom,$uname,'cloneable');
                   2927:                         my %newclonecrs = ();
                   2928:                         if ($currclonecrs{'cloneable'} =~ /\Q$clone_crs\E/) {
                   2929:                             if ($currclonecrs{'cloneable'} =~ /,/) {
                   2930:                                 my @currclonecrs = split/,/,$currclonecrs{'cloneable'};
                   2931:                                 foreach (@currclonecrs) {
                   2932:                                     unless ($_ eq $clone_crs) {
                   2933:                                         $newclonecrs{'cloneable'} .= $_.',';
                   2934:                                     }
                   2935:                                 }
                   2936:                                 $newclonecrs{'cloneable'} =~ s/,$//;
                   2937:                             } else {
                   2938:                                 $newclonecrs{'cloneable'} = '';
                   2939:                             }
                   2940:                             &Apache::lonnet::put('environment',\%newclonecrs,$udom,$uname);
                   2941:                         }
                   2942:                     }
                   2943:                 }
                   2944:             }
                   2945:         }
                   2946:     }
                   2947: }
                   2948: 
1.193     albertel 2949: 
                   2950: ##################################################
                   2951: ##################################################
                   2952: 
                   2953: =pod
                   2954: 
                   2955: =item * header
                   2956: 
                   2957: Output html header for page
                   2958: 
                   2959: =cut
                   2960: 
                   2961: ##################################################
                   2962: ##################################################
                   2963: sub header {
1.280     albertel 2964:     return &Apache::loncommon::start_page('Parameter Manager');
1.193     albertel 2965: }
                   2966: ##################################################
                   2967: ##################################################
                   2968: sub print_main_menu {
                   2969:     my ($r,$parm_permission)=@_;
                   2970:     #
                   2971:     $r->print(<<ENDMAINFORMHEAD);
                   2972: <form method="post" enctype="multipart/form-data"
                   2973:       action="/adm/parmset" name="studentform">
                   2974: ENDMAINFORMHEAD
                   2975: #
1.195     albertel 2976:     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                   2977:     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
1.268     albertel 2978:     my $vgr  = &Apache::lonnet::allowed('vgr',$env{'request.course.id'});
                   2979: 
1.193     albertel 2980:     my @menu =
                   2981:         (
                   2982:           { text => 'Set Course Environment Parameters',
1.204     www      2983: 	    action => 'crsenv',
1.193     albertel 2984:             permission => $parm_permission,
                   2985:             },
1.255     banghart 2986:           { text => 'Set Portfolio Metadata',
1.259     banghart 2987: 	    action => 'setrestrictmeta',
1.240     banghart 2988:             permission => $parm_permission,
                   2989:             },
1.271     www      2990: 	  { text => 'Manage Course Slots',
1.268     albertel 2991: 	    url => '/adm/slotrequest?command=showslots',
                   2992: 	    permission => $vgr,
                   2993:             },
                   2994: 	  { divider => 1,
                   2995: 	    },
1.216     www      2996:           { text => 'Set/Modify Resource Parameters - Helper Mode',
1.193     albertel 2997:             url => '/adm/helper/parameter.helper',
                   2998:             permission => $parm_permission,
                   2999:             },
1.216     www      3000:           { text => 'Modify Resource Parameters - Overview Mode',
1.193     albertel 3001:             action => 'setoverview',
                   3002:             permission => $parm_permission,
1.208     www      3003:             },          
1.216     www      3004: 	  { text => 'Set Resource Parameters - Overview Mode',
1.208     www      3005:             action => 'newoverview',
                   3006:             permission => $parm_permission,
1.193     albertel 3007:             },
1.216     www      3008:           { text => 'Set/Modify Resource Parameters - Table Mode',
1.193     albertel 3009:             action => 'settable',
                   3010:             permission => $parm_permission,
1.204     www      3011:             help => 'Cascading_Parameters',
1.193     albertel 3012:             },
1.220     www      3013:           { text => 'Set Parameter Setting Default Actions',
                   3014:             action => 'setdefaults',
                   3015:             permission => $parm_permission,
1.284     www      3016:             },          
1.292     www      3017: 	  { text => 'Parameter Change Log and Course Blog Posting/User Notification',
1.284     www      3018:             action => 'parameterchangelog',
                   3019:             permission => $parm_permission,
1.220     www      3020:             },
1.193     albertel 3021:           );
                   3022:     my $menu_html = '';
                   3023:     foreach my $menu_item (@menu) {
1.268     albertel 3024: 	if ($menu_item->{'divider'}) {
                   3025: 	    $menu_html .= '<hr />';
                   3026: 	    next;
                   3027: 	}
1.193     albertel 3028:         next if (! $menu_item->{'permission'});
                   3029:         $menu_html.='<p>';
                   3030:         $menu_html.='<font size="+1">';
                   3031:         if (exists($menu_item->{'url'})) {
                   3032:             $menu_html.=qq{<a href="$menu_item->{'url'}">};
                   3033:         } else {
                   3034:             $menu_html.=
                   3035:                 qq{<a href="/adm/parmset?action=$menu_item->{'action'}">};
                   3036:         }
                   3037:         $menu_html.= &mt($menu_item->{'text'}).'</a></font>';
                   3038:         if (exists($menu_item->{'help'})) {
                   3039:             $menu_html.=
                   3040:                 &Apache::loncommon::help_open_topic($menu_item->{'help'});
                   3041:         }
                   3042:         $menu_html.='</p>'.$/;
                   3043:     }
                   3044:     $r->print($menu_html);
                   3045:     return;
                   3046: }
1.255     banghart 3047: ### Set portfolio metadata
1.252     banghart 3048: sub output_row {
1.255     banghart 3049:     my ($r, $field_name, $field_text) = @_;
1.252     banghart 3050:     my $output;
1.263     banghart 3051:     my $options=$env{'course.'.$env{'request.course.id'}.'.metadata.'.$field_name.'.options'};
                   3052:     my $values=$env{'course.'.$env{'request.course.id'}.'.metadata.'.$field_name.'.values'};
1.254     banghart 3053:     unless (defined($options)) {
                   3054:         $options = 'active,stuadd';
1.261     banghart 3055:         $values = '';
1.252     banghart 3056:     }
1.260     banghart 3057:     $output.='<strong>'.$field_text.':</strong>';
1.264     albertel 3058:     $output.='<input name="'.$field_name.'_values" type="text" value="'.$values.'" size="80" /><br />';
                   3059: 
                   3060:     my @options= ( ['active', 'Show to student'],
                   3061: 		   ['onlyone','Student may select only one choice'],
                   3062: 		   ['stuadd', 'Student may type choices']);
                   3063:     foreach my $opt (@options) {
                   3064: 	my $checked = ($options =~ m/$opt->[0]/) ? ' checked="checked" ' : '' ;
                   3065: 	$output.=('&nbsp;'x5).'<label><input type="checkbox" name="'.
                   3066: 	    $field_name.'_'.$opt->[0].'" value="yes"'.$checked.' />'.
                   3067: 	    &mt($opt->[1]).'</label> <br />';
1.252     banghart 3068:     }
                   3069:     return ($output);
                   3070: }
1.259     banghart 3071: 
                   3072: sub setrestrictmeta {
1.240     banghart 3073:     my ($r)=@_;
1.242     banghart 3074:     my $next_meta;
1.244     banghart 3075:     my $output;
1.245     banghart 3076:     my $item_num;
1.246     banghart 3077:     my $put_result;
1.280     albertel 3078:     
                   3079:     $r->print(&Apache::loncommon::start_page('Restrict Metadata'));
1.298     albertel 3080:     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Restrict Metadata'));
1.240     banghart 3081:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   3082:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.259     banghart 3083:     my $key_base = $env{'course.'.$env{'request.course.id'}.'.'};
1.252     banghart 3084:     my $save_field = '';
1.259     banghart 3085:     if ($env{'form.restrictmeta'}) {
1.254     banghart 3086:         foreach my $field (sort(keys(%env))) {
1.252     banghart 3087:             if ($field=~m/^form.(.+)_(.+)$/) {
1.254     banghart 3088:                 my $options;
1.252     banghart 3089:                 my $meta_field = $1;
                   3090:                 my $meta_key = $2;
1.253     banghart 3091:                 if ($save_field ne $meta_field) {
1.252     banghart 3092:                     $save_field = $meta_field;
1.253     banghart 3093:             	    if ($env{'form.'.$meta_field.'_stuadd'}) {
1.254     banghart 3094:             	        $options.='stuadd,';
                   3095:             	    } 
1.253     banghart 3096:             	    if ($env{'form.'.$meta_field.'_onlyone'}) {
1.254     banghart 3097:             	        $options.='onlyone,';
                   3098:             	    } 
                   3099:             	    if ($env{'form.'.$meta_field.'_active'}) {
                   3100:             	        $options.='active,';
1.253     banghart 3101:             	    }
1.259     banghart 3102:                     my $name = $save_field;
1.253     banghart 3103:                      $put_result = &Apache::lonnet::put('environment',
1.262     banghart 3104:                                                   {'metadata.'.$meta_field.'.options'=>$options,
                   3105:                                                    'metadata.'.$meta_field.'.values'=>$env{'form.'.$meta_field.'_values'},
1.253     banghart 3106:                                                    },$dom,$crs);
1.252     banghart 3107:                 }
                   3108:             }
                   3109:         }
                   3110:     }
1.296     albertel 3111:     &Apache::lonnet::coursedescription($env{'request.course.id'},
                   3112: 				       {'freshen_cache' => 1});
1.258     albertel 3113:     my %metadata_fields = &Apache::lonmeta::fieldnames('portfolio');
                   3114:     foreach my $field (sort(keys(%metadata_fields))) {
1.265     banghart 3115:         &Apache::lonnet::logthis ($field);
                   3116:         if ($field ne 'courserestricted') {
                   3117: 	    $output.= &output_row($r, $field, $metadata_fields{$field});
                   3118: 	}
1.255     banghart 3119:     }
1.244     banghart 3120:     $r->print(<<ENDenv);       
1.259     banghart 3121:         <form method="post" action="/adm/parmset?action=setrestrictmeta" name="form">
1.244     banghart 3122:         <p>
                   3123:         $output
1.259     banghart 3124:         <input type="submit" name="restrictmeta" value="Update Metadata Restrictions">
1.244     banghart 3125:         </form>
                   3126: ENDenv
1.280     albertel 3127:     $r->print(&Apache::loncommon::end_page());
1.240     banghart 3128:     return 'ok';
                   3129: }
1.220     www      3130: ##################################################
1.193     albertel 3131: 
1.220     www      3132: sub defaultsetter {
1.280     albertel 3133:     my ($r) = @_;
                   3134: 
                   3135:     my $start_page = 
                   3136: 	&Apache::loncommon::start_page('Parameter Setting Default Actions');
1.298     albertel 3137:     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Defaults');
1.220     www      3138:     $r->print(<<ENDDEFHEAD);
1.280     albertel 3139: $start_page
1.220     www      3140: $breadcrumbs
                   3141: <form method="post" action="/adm/parmset?action=setdefaults" name="defaultform">
                   3142: ENDDEFHEAD
1.280     albertel 3143: 
                   3144:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   3145:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.221     www      3146:     my @ids=();
                   3147:     my %typep=();
                   3148:     my %keyp=();
                   3149:     my %allparms=();
                   3150:     my %allparts=();
                   3151:     my %allmaps=();
                   3152:     my %mapp=();
                   3153:     my %symbp=();
                   3154:     my %maptitles=();
                   3155:     my %uris=();
                   3156:     my %keyorder=&standardkeyorder();
                   3157:     my %defkeytype=();
                   3158: 
                   3159:     &extractResourceInformation(\@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allmaps, 
                   3160: 				\%mapp, \%symbp,\%maptitles,\%uris,
                   3161: 				\%keyorder,\%defkeytype);
1.224     www      3162:     if ($env{'form.storerules'}) {
                   3163: 	my %newrules=();
                   3164: 	my @delrules=();
1.226     www      3165: 	my %triggers=();
1.225     albertel 3166: 	foreach my $key (keys(%env)) {
                   3167:             if ($key=~/^form\.(\w+)\_action$/) {
1.224     www      3168: 		my $tempkey=$1;
1.226     www      3169: 		my $action=$env{$key};
                   3170:                 if ($action) {
                   3171: 		    $newrules{$tempkey.'_action'}=$action;
                   3172: 		    if ($action ne 'default') {
                   3173: 			my ($whichaction,$whichparm)=($action=~/^(.*\_)([^\_]+)$/);
                   3174: 			$triggers{$whichparm}.=$tempkey.':';
                   3175: 		    }
                   3176: 		    $newrules{$tempkey.'_type'}=$defkeytype{$tempkey};
1.224     www      3177: 		    if (&isdateparm($defkeytype{$tempkey})) {
1.227     www      3178: 			$newrules{$tempkey.'_days'}=$env{'form.'.$tempkey.'_days'};
1.224     www      3179: 			$newrules{$tempkey.'_hours'}=$env{'form.'.$tempkey.'_hours'};
                   3180: 			$newrules{$tempkey.'_min'}=$env{'form.'.$tempkey.'_min'};
                   3181: 			$newrules{$tempkey.'_sec'}=$env{'form.'.$tempkey.'_sec'};
                   3182: 		    } else {
                   3183: 			$newrules{$tempkey.'_value'}=$env{'form.'.$tempkey.'_value'};
1.227     www      3184: 			$newrules{$tempkey.'_triggervalue'}=$env{'form.'.$tempkey.'_triggervalue'};
1.224     www      3185: 		    }
                   3186: 		} else {
1.225     albertel 3187: 		    push(@delrules,$tempkey.'_action');
1.226     www      3188: 		    push(@delrules,$tempkey.'_type');
1.225     albertel 3189: 		    push(@delrules,$tempkey.'_hours');
                   3190: 		    push(@delrules,$tempkey.'_min');
                   3191: 		    push(@delrules,$tempkey.'_sec');
                   3192: 		    push(@delrules,$tempkey.'_value');
1.224     www      3193: 		}
                   3194: 	    }
                   3195: 	}
1.226     www      3196: 	foreach my $key (keys %allparms) {
                   3197: 	    $newrules{$key.'_triggers'}=$triggers{$key};
                   3198: 	}
1.224     www      3199: 	&Apache::lonnet::put('parmdefactions',\%newrules,$dom,$crs);
                   3200: 	&Apache::lonnet::del('parmdefactions',\@delrules,$dom,$crs);
                   3201: 	&resetrulescache();
                   3202:     }
1.227     www      3203:     my %lt=&Apache::lonlocal::texthash('days' => 'Days',
                   3204: 				       'hours' => 'Hours',
1.221     www      3205: 				       'min' => 'Minutes',
                   3206: 				       'sec' => 'Seconds',
                   3207: 				       'yes' => 'Yes',
                   3208: 				       'no' => 'No');
1.222     www      3209:     my @standardoptions=('','default');
                   3210:     my @standarddisplay=('',&mt('Default value when manually setting'));
                   3211:     my @dateoptions=('','default');
                   3212:     my @datedisplay=('',&mt('Default value when manually setting'));
                   3213:     foreach my $tempkey (&keysindisplayorder(\%allparms,\%keyorder)) {
                   3214: 	unless ($tempkey) { next; }
                   3215: 	push @standardoptions,'when_setting_'.$tempkey;
                   3216: 	push @standarddisplay,&mt('Automatically set when setting ').$tempkey;
                   3217: 	if (&isdateparm($defkeytype{$tempkey})) {
                   3218: 	    push @dateoptions,'later_than_'.$tempkey;
                   3219: 	    push @datedisplay,&mt('Automatically set later than ').$tempkey;
                   3220: 	    push @dateoptions,'earlier_than_'.$tempkey;
                   3221: 	    push @datedisplay,&mt('Automatically set earlier than ').$tempkey;
                   3222: 	} 
                   3223:     }
1.231     www      3224: $r->print(&mt('Manual setting rules apply to all interfaces.').'<br />'.
                   3225: 	  &mt('Automatic setting rules apply to table mode interfaces only.'));
1.221     www      3226:     $r->print("\n<table border='1'><tr><th>".&mt('Rule for parameter').'</th><th>'.
1.222     www      3227: 	      &mt('Action').'</th><th>'.&mt('Value').'</th></tr>');
1.221     www      3228:     foreach my $tempkey (&keysindisplayorder(\%allparms,\%keyorder)) {
1.222     www      3229: 	unless ($tempkey) { next; }
1.221     www      3230: 	$r->print("\n<tr><td>".$allparms{$tempkey}."\n<br />(".$tempkey.')</td><td>');
1.222     www      3231: 	my $action=&rulescache($tempkey.'_action');
                   3232: 	$r->print('<select name="'.$tempkey.'_action">');
                   3233: 	if (&isdateparm($defkeytype{$tempkey})) {
                   3234: 	    for (my $i=0;$i<=$#dateoptions;$i++) {
                   3235: 		if ($dateoptions[$i]=~/\_$tempkey$/) { next; }
                   3236: 		$r->print("\n<option value='$dateoptions[$i]'".
                   3237: 			  ($dateoptions[$i] eq $action?' selected="selected"':'').
                   3238: 			  ">$datedisplay[$i]</option>");
                   3239: 	    }
                   3240: 	} else {
                   3241: 	    for (my $i=0;$i<=$#standardoptions;$i++) {
                   3242: 		if ($standardoptions[$i]=~/\_$tempkey$/) { next; }
                   3243: 		$r->print("\n<option value='$standardoptions[$i]'".
                   3244: 			  ($standardoptions[$i] eq $action?' selected="selected"':'').
                   3245: 			  ">$standarddisplay[$i]</option>");
                   3246: 	    }
                   3247: 	}
                   3248: 	$r->print('</select>');
1.227     www      3249: 	unless (&isdateparm($defkeytype{$tempkey})) {
                   3250: 	    $r->print("\n<br />".&mt('Triggering value(s) of other parameter (optional, comma-separated):').
                   3251: 		      '<input type="text" size="20" name="'.$tempkey.'_triggervalue" value="'.&rulescache($tempkey.'_triggervalue').'" />');
                   3252: 	}
1.222     www      3253: 	$r->print("\n</td><td>\n");
                   3254: 
1.221     www      3255:         if (&isdateparm($defkeytype{$tempkey})) {
1.227     www      3256: 	    my $days=&rulescache($tempkey.'_days');
1.222     www      3257: 	    my $hours=&rulescache($tempkey.'_hours');
                   3258: 	    my $min=&rulescache($tempkey.'_min');
                   3259: 	    my $sec=&rulescache($tempkey.'_sec');
1.221     www      3260: 	    $r->print(<<ENDINPUTDATE);
1.227     www      3261: <input name="$tempkey\_days" type="text" size="4" value="$days" />$lt{'days'}<br />
1.222     www      3262: <input name="$tempkey\_hours" type="text" size="4" value="$hours" />$lt{'hours'}<br />
                   3263: <input name="$tempkey\_min" type="text" size="4" value="$min" />$lt{'min'}<br />
                   3264: <input name="$tempkey\_sec" type="text" size="4" value="$sec" />$lt{'sec'}
1.221     www      3265: ENDINPUTDATE
                   3266: 	} elsif ($defkeytype{$tempkey} eq 'string_yesno') {
1.222     www      3267:             my $yeschecked='';
                   3268:             my $nochecked='';
                   3269:             if (&rulescache($tempkey.'_value') eq 'yes') { $yeschecked='checked="checked"'; }
                   3270:             if (&rulescache($tempkey.'_value') eq 'no') { $nochecked='checked="checked"'; }
                   3271: 
1.221     www      3272: 	    $r->print(<<ENDYESNO);
1.224     www      3273: <label><input type="radio" name="$tempkey\_value" value="yes" $yeschecked /> $lt{'yes'}</label><br />
                   3274: <label><input type="radio" name="$tempkey\_value" value="no" $nochecked /> $lt{'no'}</label>
1.221     www      3275: ENDYESNO
                   3276:         } else {
1.224     www      3277: 	    $r->print('<input type="text" size="20" name="'.$tempkey.'_value" value="'.&rulescache($tempkey.'_value').'" />');
1.221     www      3278: 	}
                   3279:         $r->print('</td></tr>');
                   3280:     }
1.224     www      3281:     $r->print("</table>\n<input type='submit' name='storerules' value='".
1.280     albertel 3282: 	      &mt('Store Rules')."' /></form>\n".
                   3283: 	      &Apache::loncommon::end_page());
1.220     www      3284:     return;
                   3285: }
1.193     albertel 3286: 
1.290     www      3287: sub components {
1.291     www      3288:     my ($key,$uname,$udom,$exeuser,$exedomain)=@_;
1.290     www      3289:     my $typeflag=0;
                   3290:     if ($key=~/\.type$/) {
                   3291: 	$key=~s/\.type$//;
                   3292:         $typeflag=1;
                   3293:     }
1.291     www      3294:     my $issection;
1.290     www      3295:     my ($middle,$part,$name)=($key=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s]+)\.(\w+)$/);
                   3296:     my $section=&mt('All Students');
                   3297:     if ($middle=~/^\[(.*)\]/) {
1.291     www      3298: 	$issection=$1;
                   3299: 	$section=&mt('Group/Section').': '.$issection;
1.290     www      3300: 	$middle=~s/^\[(.*)\]//;
                   3301:     }
                   3302:     $middle=~s/\.+$//;
                   3303:     $middle=~s/^\.+//;
1.291     www      3304:     if ($uname) {
                   3305: 	$section=&mt('User').": ".&Apache::loncommon::plainname($uname,$udom);
                   3306: 	$issection='';
                   3307:     }
1.290     www      3308:     my $realm='<font color="red">'.&mt('All Resources').'</font>';
1.304   ! www      3309:     my $realmdescription=&mt('all resources'); 
1.290     www      3310:     if ($middle=~/^(.+)\_\_\_\(all\)$/) {
                   3311: 	$realm='<font color="green">'.&mt('Folder/Map').': '.&Apache::lonnet::gettitle($1).' <br /><font color="#aaaaaa" size="-2">('.$1.')</font></font>';
1.304   ! www      3312:  	$realmdescription=&mt('folder').' '.&Apache::lonnet::gettitle($1);
        !          3313:    } elsif ($middle) {
1.290     www      3314: 	my ($map,$id,$url)=&Apache::lonnet::decode_symb($middle);
                   3315: 	$realm='<font color="orange">'.&mt('Resource').': '.&Apache::lonnet::gettitle($middle).' <br /><font color="#aaaaaa" size="-2">('.$url.' in '.$map.' id: '.$id.')</font></font>';
1.304   ! www      3316: 	$realmdescription=&mt('resource').' '.&Apache::lonnet::gettitle($middle);
1.290     www      3317:     }
1.291     www      3318:     my $what=$part.'.'.$name;
                   3319:     return ($realm,$section,$name,$part,$typeflag,
1.304   ! www      3320: 	    $what,$middle,$uname,$udom,$issection,$realmdescription);
1.290     www      3321: }
1.293     www      3322: 
1.292     www      3323: sub standard_parameter_names {
                   3324:     my ($name)=@_;
                   3325:     my %standard_parms=&Apache::lonlocal::texthash('duedate' => 'Due Date',
                   3326: 						   'answerdate' => 'Answer Date',
                   3327: 						   'opendate' => 'Open Date',
                   3328: 						   'maxtries' => 'Max. Number of Tries',
                   3329: 						   'weight' => 'Weight',
                   3330: 						   'date_start' => 'Starting Date',
1.293     www      3331: 						   'date_end' => 'Ending Date',
                   3332: 						   'int_pos' => 'Positive Integer',
                   3333: 						   'int_zero_pos' => 'Positive Integer or Zero',
                   3334: 						   'hinttries' => 'Number of Tries till Hints appear');
1.292     www      3335:     if ($standard_parms{$name}) {
                   3336: 	return $standard_parms{$name}; 
                   3337:     } else { 
                   3338: 	return $name; 
                   3339:     }
                   3340: }
1.290     www      3341: 
1.285     albertel 3342: sub parm_change_log {
1.284     www      3343:     my ($r)=@_;
                   3344:     &startpage($r);
1.286     www      3345:     my %parmlog=&Apache::lonnet::dump('nohist_parameterlog',
                   3346: 				      $env{'course.'.$env{'request.course.id'}.'.domain'},
                   3347: 				      $env{'course.'.$env{'request.course.id'}.'.num'});
1.301     www      3348:     if ((keys(%parmlog))[0]=~/^error\:/) { undef(%parmlog); }
                   3349: 
1.291     www      3350:     my $courseopt=&Apache::lonnet::get_courseresdata($env{'course.'.$env{'request.course.id'}.'.num'},
                   3351: 						     $env{'course.'.$env{'request.course.id'}.'.domain'});
1.301     www      3352:     $r->print(&Apache::loncommon::start_data_table().&Apache::loncommon::start_data_table_header_row().
                   3353: 	      '<th>'.&mt('Time').'</th><th>'.&mt('User').'</th><th>'.&mt('Extent').'</th><th>'.&mt('Users').'</th><th>'.
                   3354: 	      &mt('Parameter').'</th><th>'.&mt('Part').'</th><th>'.&mt('New Value').'</th><th>'.&mt('Announce').'</th>'.
                   3355: 	      &Apache::loncommon::end_data_table_header_row());
1.294     www      3356:     foreach my $id (sort { $parmlog{$b}{'exe_time'}<=>$parmlog{$a}{'exe_time'} } (keys(%parmlog))) {
                   3357:         my @changes=keys(%{$parmlog{$id}{'logentry'}});
1.290     www      3358: 	my $count=$#changes+1;
1.288     albertel 3359: 	my $time =
1.294     www      3360: 	    &Apache::lonlocal::locallocaltime($parmlog{$id}{'exe_time'});
1.289     www      3361: 	my $plainname = 
1.294     www      3362: 	    &Apache::loncommon::plainname($parmlog{$id}{'exe_uname'},
                   3363: 					  $parmlog{$id}{'exe_udom'});
1.288     albertel 3364: 	my $about_me_link = 
1.289     www      3365: 	    &Apache::loncommon::aboutmewrapper($plainname,
1.294     www      3366: 					       $parmlog{$id}{'exe_uname'},
                   3367: 					       $parmlog{$id}{'exe_udom'});
1.293     www      3368: 	my $send_msg_link='';
1.294     www      3369: 	if ((($parmlog{$id}{'exe_uname'} ne $env{'user.name'}) 
                   3370: 	     || ($parmlog{$id}{'exe_udom'} ne $env{'user.domain'}))) {
1.293     www      3371: 	    $send_msg_link ='<br />'.
1.288     albertel 3372: 		&Apache::loncommon::messagewrapper(&mt('Send message'),
1.294     www      3373: 						   $parmlog{$id}{'exe_uname'},
                   3374: 						   $parmlog{$id}{'exe_udom'});
1.288     albertel 3375: 	}
1.301     www      3376: 	my $row_start=&Apache::loncommon::start_data_table_row();
                   3377: 	$r->print($row_start.'<td rowspan="'.$count.'">'.$time.'</td>
1.290     www      3378:                        <td rowspan="'.$count.'">'.$about_me_link.
1.294     www      3379: 		  '<br /><tt>'.$parmlog{$id}{'exe_uname'}.
                   3380: 			          ':'.$parmlog{$id}{'exe_udom'}.'</tt>'.
1.290     www      3381: 		  $send_msg_link.'</td>');
                   3382: 	my $makenewrow=0;
                   3383: 	my %istype=();
1.293     www      3384: 	foreach my $changed (reverse(sort(@changes))) {
1.294     www      3385:             my $value=$parmlog{$id}{'logentry'}->{$changed};
1.304   ! www      3386:             my ($realm,$section,$parmname,$part,$typeflag,$what,$middle,$uname,$udom,$issection,$realmdescription)=
1.294     www      3387: 		&components($changed,$parmlog{$id}{'uname'},$parmlog{$id}{'udom'});
1.290     www      3388: 	    if ($typeflag) { $istype{$parmname}=$value; }
1.301     www      3389: 	    if ($makenewrow) { $r->print($row_start); } else { $makenewrow=1; }
1.290     www      3390: 	    $r->print('<td>'.$realm.'</td><td>'.$section.'</td><td>'.
1.292     www      3391: 		      &standard_parameter_names($parmname).'</td><td>'.
                   3392: 		      ($part?&mt('Part: [_1]',$part):&mt('All Parts')).'</td><td>');
1.291     www      3393: 	    my $stillactive=0;
1.294     www      3394: 	    if ($parmlog{$id}{'deleteflag'}) {
1.290     www      3395: 		$r->print(&mt('Deleted'));
1.288     albertel 3396: 	    } else {
1.290     www      3397: 		if ($typeflag) {
1.292     www      3398: 		    $r->print(&mt('Type: [_1]',&standard_parameter_names($value)));
1.290     www      3399: 		} else {
1.291     www      3400: 		    my ($level,@all)=&parmval_by_symb($what,$middle,&Apache::lonnet::metadata($middle,$what),
                   3401: 						      $uname,$udom,$issection,$issection,$courseopt);
                   3402: 		    if (&isdateparm($istype{$parmname})) {
                   3403: 			$r->print(&Apache::lonlocal::locallocaltime($value));
                   3404: 		    } else {
                   3405: 			$r->print($value);
                   3406: 		    }
                   3407: 		    if ($value ne $all[$level]) {
                   3408: 			$r->print('<br /><font color="red">'.&mt('Not active anymore').'</font>');
                   3409: 		    } else {
                   3410: 			$stillactive=1;
                   3411: 		    }
1.290     www      3412: 		}
1.288     albertel 3413: 	    }
1.291     www      3414: 	    $r->print('</td>');
                   3415: 	    if ($stillactive) {
1.304   ! www      3416: 		my $title=&mt('Changed [_1]',&standard_parameter_names($parmname));
        !          3417:                 my $description=&mt('Changed [_1] for [_2] to [_3]',&standard_parameter_names($parmname),$realmdescription,
        !          3418: 				    (&isdateparm($istype{$parmname})?&Apache::lonlocal::locallocaltime($value):$value));
1.292     www      3419: 		if (($uname) && ($udom)) {
1.304   ! www      3420: 		    $r->print('<td>'.
        !          3421: 			      &Apache::loncommon::messagewrapper('Notify User',$uname,$udom,$title,$description).
        !          3422: 			      '</td>');
1.292     www      3423: 		} else {
1.303     www      3424: 		    $r->print('<td>'.
1.304   ! www      3425: 			      &Apache::lonrss::course_blog_link($id,$title,$description).
        !          3426: 			      '</td>');
1.292     www      3427: 		}
1.291     www      3428: 	    } else {
                   3429: 		$r->print('<td>&nbsp;</td>');
                   3430: 	    }
1.301     www      3431: 	    $r->print(&Apache::loncommon::end_data_table_row());
1.288     albertel 3432: 	}
1.286     www      3433:     }
1.301     www      3434:     $r->print(&Apache::loncommon::end_data_table());
1.284     www      3435:     $r->print(&Apache::loncommon::end_page());
                   3436: }
                   3437: 
1.178     raeburn  3438: ##################################################
                   3439: ##################################################
1.30      www      3440: 
1.59      matthew  3441: =pod
                   3442: 
1.83      bowersj2 3443: =item * handler
1.59      matthew  3444: 
                   3445: Main handler.  Calls &assessparms and &crsenv subroutines.
                   3446: 
                   3447: =cut
                   3448: ##################################################
                   3449: ##################################################
1.220     www      3450: #    use Data::Dumper;
                   3451: 
1.259     banghart 3452: 
1.30      www      3453: sub handler {
1.43      albertel 3454:     my $r=shift;
1.30      www      3455: 
1.43      albertel 3456:     if ($r->header_only) {
1.126     www      3457: 	&Apache::loncommon::content_type($r,'text/html');
1.43      albertel 3458: 	$r->send_http_header;
                   3459: 	return OK;
                   3460:     }
1.193     albertel 3461:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.205     www      3462: 					    ['action','state',
                   3463:                                              'pres_marker',
                   3464:                                              'pres_value',
1.206     www      3465:                                              'pres_type',
1.243     banghart 3466:                                              'udom','uname','symb','serial']);
1.131     www      3467: 
1.83      bowersj2 3468: 
1.193     albertel 3469:     &Apache::lonhtmlcommon::clear_breadcrumbs();
1.194     albertel 3470:     &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/parmset",
                   3471: 					    text=>"Parameter Manager",
1.204     www      3472: 					    faq=>10,
1.194     albertel 3473: 					    bug=>'Instructor Interface'});
1.203     www      3474: 
1.30      www      3475: # ----------------------------------------------------- Needs to be in a course
1.194     albertel 3476:     my $parm_permission =
                   3477: 	(&Apache::lonnet::allowed('opa',$env{'request.course.id'}) ||
1.190     albertel 3478: 	 &Apache::lonnet::allowed('opa',$env{'request.course.id'}.'/'.
1.193     albertel 3479: 				  $env{'request.course.sec'}));
1.194     albertel 3480:     if ($env{'request.course.id'} &&  $parm_permission) {
1.193     albertel 3481: 
                   3482:         # Start Page
1.126     www      3483:         &Apache::loncommon::content_type($r,'text/html');
1.106     www      3484:         $r->send_http_header;
1.30      www      3485: 
1.203     www      3486: 
                   3487:         # id numbers can change on re-ordering of folders
                   3488: 
                   3489:         &resetsymbcache();
                   3490: 
1.193     albertel 3491:         #
                   3492:         # Main switch on form.action and form.state, as appropriate
                   3493:         #
                   3494:         # Check first if coming from someone else headed directly for
                   3495:         #  the table mode
                   3496:         if ((($env{'form.command'} eq 'set') && ($env{'form.url'})
                   3497: 	     && (!$env{'form.dis'})) || ($env{'form.symb'})) {
                   3498: 	    &assessparms($r);
                   3499: 
                   3500:         } elsif (! exists($env{'form.action'})) {
                   3501:             $r->print(&header());
1.298     albertel 3502:             $r->print(&Apache::lonhtmlcommon::breadcrumbs('Parameter Manager'));
1.193     albertel 3503:             &print_main_menu($r,$parm_permission);
                   3504:         } elsif ($env{'form.action'} eq 'crsenv' && $parm_permission) {
1.194     albertel 3505:             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=crsenv',
                   3506: 						    text=>"Course Environment"});
1.193     albertel 3507:             &crsenv($r); 
                   3508:         } elsif ($env{'form.action'} eq 'setoverview' && $parm_permission) {
1.194     albertel 3509:             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview',
                   3510: 						    text=>"Overview Mode"});
1.121     www      3511: 	    &overview($r);
1.259     banghart 3512:         } elsif ($env{'form.action'} eq 'setrestrictmeta' && $parm_permission) {
                   3513:             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setrestrictmeta',
                   3514: 						    text=>"Restrict Metadata"});
                   3515: 	    &setrestrictmeta($r);
1.208     www      3516:         } elsif ($env{'form.action'} eq 'newoverview' && $parm_permission) {
                   3517:             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview',
                   3518: 						    text=>"Overview Mode"});
                   3519: 	    &newoverview($r);
1.220     www      3520:         }  elsif ($env{'form.action'} eq 'setdefaults' && $parm_permission) {
                   3521:             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setdefaults',
                   3522: 						    text=>"Set Defaults"});
                   3523: 	    &defaultsetter($r);
                   3524: 	} elsif ($env{'form.action'} eq 'settable' && $parm_permission) {
1.194     albertel 3525:             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=settable',
1.204     www      3526: 						    text=>"Table Mode",
                   3527: 						    help => 'Course_Setting_Parameters'});
1.121     www      3528: 	    &assessparms($r);
1.284     www      3529:         } elsif ($env{'form.action'} eq 'parameterchangelog' && $parm_permission) {
                   3530:             &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=settable',
1.292     www      3531: 						    text=>"Parameter Change Log"});
1.285     albertel 3532: 	    &parm_change_log($r);
1.284     www      3533: 	}       
1.43      albertel 3534:     } else {
1.1       www      3535: # ----------------------------- Not in a course, or not allowed to modify parms
1.190     albertel 3536: 	$env{'user.error.msg'}=
1.43      albertel 3537: 	    "/adm/parmset:opa:0:0:Cannot modify assessment parameters";
                   3538: 	return HTTP_NOT_ACCEPTABLE;
                   3539:     }
                   3540:     return OK;
1.1       www      3541: }
                   3542: 
                   3543: 1;
                   3544: __END__
                   3545: 
1.59      matthew  3546: =pod
1.38      harris41 3547: 
                   3548: =back
                   3549: 
                   3550: =cut
1.1       www      3551: 
                   3552: 
                   3553: 

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