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

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

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