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

1.1       www         1: # The LearningOnline Network with CAPA
                      2: # Handler to set parameters for assessments
                      3: #
1.561   ! damieng     4: # $Id: lonparmset.pm,v 1.560 2016/07/12 20:30:20 damieng 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: 
1.560     damieng    39: lonparmset provides an interface to setting course parameters.
                     40: 
                     41: It contains all the code for the "Content and Problem Settings" UI, except
                     42: for the helpers parameter.helper and resettimes.helper, and lonhelper.pm,
                     43: and lonblockingmenu.pm.
1.59      matthew    44: 
                     45: =head1 DESCRIPTION
                     46: 
                     47: This module sets coursewide and assessment parameters.
                     48: 
                     49: =head1 INTERNAL SUBROUTINES
                     50: 
1.416     jms        51: =over
1.59      matthew    52: 
1.416     jms        53: =item parmval()
1.59      matthew    54: 
                     55: Figure out a cascading parameter.
                     56: 
1.71      albertel   57: Inputs:  $what - a parameter spec (incluse part info and name I.E. 0.weight)
1.162     albertel   58:          $id   - a bighash Id number
1.71      albertel   59:          $def  - the resource's default value   'stupid emacs
                     60: 
1.556     raeburn    61: Returns:  A list, the first item is the index into the remaining list of items of parm values that is the active one, the list consists of parm values at the 18 possible levels
1.71      albertel   62: 
1.556     raeburn    63: 18 - General Course
                     64: 17 - Map or Folder level in course (recursive) 
                     65: 16 - Map or Folder level in course (non-recursive)
                     66: 15 - resource default
                     67: 14 - map default
                     68: 13 - resource level in course
                     69: 12 - General for section
                     70: 11 - Map or Folder level for section (recursive)
                     71: 10 - Map or Folder level for section (non-recursive)
                     72: 9 - resource level in section
                     73: 8 - General for group
                     74: 7 - Map or Folder level for group (recursive)
                     75: 6 - Map or Folder level for group (non-recursive)
                     76: 5 - resource level in group
                     77: 4 - General for specific student
                     78: 3 - Map or Folder level for specific student (recursive)
                     79: 2 - Map or Folder level for specific student (non-recursive)
1.71      albertel   80: 1 - resource level for specific student
1.2       www        81: 
1.416     jms        82: =item parmval_by_symb()
                     83: 
                     84: =item reset_caches()
                     85: 
                     86: =item cacheparmhash() 
                     87: 
                     88: =item parmhash()
                     89: 
                     90: =item symbcache()
                     91: 
                     92: =item preset_defaults()
                     93: 
                     94: =item date_sanity_info()
                     95: 
                     96: =item storeparm()
                     97: 
                     98: Store a parameter by symb
                     99: 
                    100:     Takes
                    101:     - symb
                    102:     - name of parameter
                    103:     - level
                    104:     - new value
                    105:     - new type
                    106:     - username
                    107:     - userdomain
                    108: 
                    109: =item log_parmset()
                    110: 
                    111: =item storeparm_by_symb_inner()
                    112: 
                    113: =item valout()
                    114: 
                    115: Format a value for output.
                    116: 
                    117: Inputs:  $value, $type, $editable
                    118: 
                    119: Returns: $value, formatted for output.  If $type indicates it is a date,
                    120: localtime($value) is returned.
                    121: $editable will return an icon to click on
                    122: 
                    123: =item plink()
                    124: 
                    125: Produces a link anchor.
                    126: 
                    127: Inputs: $type,$dis,$value,$marker,$return,$call
                    128: 
                    129: Returns: scalar with html code for a link which will envoke the 
                    130: javascript function 'pjump'.
                    131: 
                    132: =item page_js()
                    133: 
                    134: =item startpage()
                    135: 
                    136: =item print_row()
                    137: 
                    138: =item print_td()
                    139: 
                    140: =item print_usergroups()
                    141: 
                    142: =item parm_control_group()
                    143: 
                    144: =item extractResourceInformation() : 
                    145: 
1.512     foxr      146:  extractResourceInformation extracts lots of information about all of the the course's resources into a variety of hashes.
1.416     jms       147: 
1.542     raeburn   148: Input: See list below
                    149: 
                    150: =over 4
1.416     jms       151: 
1.512     foxr      152: =item * B<env{'user.name'}> : Current username
1.416     jms       153: 
1.512     foxr      154: =item * B<env{'user.domain'}> : Domain of current user.
1.416     jms       155: 
1.542     raeburn   156: =item * B<env{"request.course.fn"}> : Course
                    157: 
                    158: =back
1.416     jms       159: 
1.512     foxr      160: Outputs: See list below:
1.416     jms       161: 
1.542     raeburn   162: =over 4
                    163: 
1.512     foxr      164: =item * B<ids> (out) : An array that will contain all of the ids in the course.
1.416     jms       165: 
1.512     foxr      166: =item * B<typep>(out) : hash, id->type, where "type" contains the extension of the file, thus, I<problem exam quiz assess survey form>.
1.416     jms       167: 
1.512     foxr      168: =item * B<keyp> (out) : hash, id->key list, will contain a comma separated list of the meta-data keys available for the given id
1.416     jms       169: 
1.512     foxr      170: =item * B<allparms> (out) : hash, name of parameter->display value (what is the display value?)
1.416     jms       171: 
1.512     foxr      172: =item * B<allparts> (out) : hash, part identification->text representation of part, where the text representation is "[Part $part]"
                    173: 
                    174: =item * B<allmaps> (out) : hash, ???
1.416     jms       175: 
                    176: =item * B<mapp> : ??
                    177: 
                    178: =item * B<symbp> : hash, id->full sym?
                    179: 
1.512     foxr      180: =item * B<maptitles>
                    181: 
                    182: =item * B<uris>
1.416     jms       183: 
1.512     foxr      184: =item * B<keyorder>
                    185: 
                    186: =item * B<defkeytype>
1.416     jms       187: 
1.542     raeburn   188: =back
                    189: 
1.416     jms       190: =item isdateparm()
                    191: 
                    192: =item parmmenu()
                    193: 
                    194: =item partmenu()
                    195: 
                    196: =item usermenu()
                    197: 
                    198: =item displaymenu()
                    199: 
                    200: =item mapmenu()
                    201: 
                    202: =item levelmenu()
                    203: 
                    204: =item sectionmenu()
                    205: 
                    206: =item keysplit()
                    207: 
                    208: =item keysinorder()
                    209: 
                    210: =item keysinorder_bytype()
                    211: 
                    212: =item keysindisplayorder()
                    213: 
                    214: =item standardkeyorder()
                    215: 
                    216: =item assessparms() : 
                    217: 
                    218: Show assessment data and parameters.  This is a large routine that should
                    219: be simplified and shortened... someday.
                    220: 
1.513     foxr      221: Inputs: $r - the Apache request object.
                    222:   
1.416     jms       223: Returns: nothing
                    224: 
                    225: Variables used (guessed by Jeremy):
                    226: 
1.542     raeburn   227: =over
                    228: 
1.416     jms       229: =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.
                    230: 
                    231: =item * B<psprt>: ParameterS PaRTs? a list of the parts of a problem that we are displaying? Used to display only selected parts?
                    232: 
                    233: =item * B<@catmarker> contains list of all possible parameters including part #s
                    234: 
                    235: =item * B<$fullkeyp> contains the full part/id # for the extraction of proper parameters
                    236: 
                    237: =item * B<$tempkeyp> contains part 0 only (no ids - ie, subparts)
                    238:         When storing information, store as part 0
                    239:         When requesting information, request from full part
                    240: 
1.542     raeburn   241: =back
                    242: 
1.416     jms       243: =item tablestart()
                    244: 
                    245: =item tableend()
                    246: 
                    247: =item extractuser()
                    248: 
                    249: =item parse_listdata_key()
                    250: 
                    251: =item listdata()
                    252: 
                    253: =item date_interval_selector()
                    254: 
                    255: =item get_date_interval_from_form()
                    256: 
                    257: =item default_selector()
                    258: 
                    259: =item string_selector()
                    260: 
                    261: =item dateshift()
                    262: 
                    263: =item newoverview()
                    264: 
                    265: =item secgroup_lister()
                    266: 
                    267: =item overview()
                    268: 
                    269: =item clean_parameters()
                    270: 
                    271: =item date_shift_one()
                    272: 
                    273: =item date_shift_two()
                    274: 
                    275: =item parse_key()
                    276: 
                    277: =item header()
                    278: 
                    279: Output html header for page
                    280: 
                    281: =item print_main_menu()
                    282: 
                    283: =item output_row()
                    284: 
                    285: Set portfolio metadata
                    286: 
                    287: =item order_meta_fields()
                    288: 
                    289: =item addmetafield()
                    290: 
                    291: =item setrestrictmeta()
                    292: 
                    293: =item get_added_meta_fieldnames()
                    294: 
                    295: =item get_deleted_meta_fieldnames()
                    296: 
                    297: =item defaultsetter()
                    298: 
                    299: =item components()
                    300: 
                    301: =item load_parameter_names()
                    302: 
                    303: =item parm_change_log()
                    304: 
                    305: =item handler() : 
                    306: 
1.450     raeburn   307: Main handler.  Calls &assessparms subroutine.
1.416     jms       308: 
                    309: =back
                    310: 
1.59      matthew   311: =cut
                    312: 
1.416     jms       313: ###################################################################
                    314: ###################################################################
                    315: 
                    316: package Apache::lonparmset;
                    317: 
                    318: use strict;
                    319: use Apache::lonnet;
                    320: use Apache::Constants qw(:common :http REDIRECT);
                    321: use Apache::lonhtmlcommon();
                    322: use Apache::loncommon;
                    323: use GDBM_File;
                    324: use Apache::lonhomework;
                    325: use Apache::lonxml;
                    326: use Apache::lonlocal;
                    327: use Apache::lonnavmaps;
                    328: use Apache::longroup;
                    329: use Apache::lonrss;
1.506     www       330: use HTML::Entities;
1.416     jms       331: use LONCAPA qw(:DEFAULT :match);
                    332: 
                    333: 
1.560     damieng   334: ##################################################
                    335: # CONTENT AND PROBLEM SETTINGS HTML PAGE HEADER/FOOTER
                    336: ##################################################
                    337: 
                    338: # Page header
1.561   ! damieng   339: #
        !           340: # @param {Apache2::RequestRec} $r - Apache request object
        !           341: # @param {string} $mode - selected tab, 'parmset' for course and problem settings, or 'coursepref' for course settings
        !           342: # @param {string} $crstype - course type ('Community' for community settings)
1.507     www       343: sub startSettingsScreen {
1.531     raeburn   344:     my ($r,$mode,$crstype)=@_;
1.507     www       345: 
1.531     raeburn   346:     my $tabtext = &mt('Course Settings');
                    347:     if ($crstype eq 'Community') {
                    348:         $tabtext = &mt('Community Settings');
                    349:     } 
1.507     www       350:     $r->print("\n".'<ul class="LC_TabContentBigger" id="main">');
                    351:     $r->print("\n".'<li'.($mode eq 'coursepref'?' class="active"':'').'><a href="/adm/courseprefs"><b>&nbsp;&nbsp;&nbsp;&nbsp;'.
1.531     raeburn   352:                                           $tabtext.
1.507     www       353:                                           '&nbsp;&nbsp;&nbsp;&nbsp;</b></a></li>');
                    354: 
1.523     raeburn   355:     $r->print("\n".'<li'.($mode eq 'parmset'?' class="active"':'').' id="tabbededitor"><a href="/adm/parmset"><b>'.
1.507     www       356:                                                                  &mt('Content and Problem Settings').'</b></a></li>');
                    357:     $r->print("\n".'</ul>'."\n");
1.523     raeburn   358:     $r->print('<div class="LC_Box" style="clear:both;margin:0;" id="parameditor"><div id="maincoursedoc" style="margin:0 0;padding:0 0;"><div class="LC_ContentBox" id="mainCourseDocuments" style="display: block;">');
1.507     www       359: }
                    360: 
1.560     damieng   361: # Page footer
1.507     www       362: sub endSettingsScreen {
                    363:    my ($r)=@_;
                    364:    $r->print('</div></div></div>');
                    365: }
                    366: 
                    367: 
                    368: 
1.560     damieng   369: ##################################################
                    370: # TABLE MODE
                    371: # (parmval is also used for the log of parameter changes)
                    372: ##################################################
                    373: 
1.561   ! damieng   374: # Calls parmval_by_symb, getting the symb from $id (the big hash resource id) with &symbcache.
        !           375: #
        !           376: # @param {string} $what - part info and parameter name separated by a dot, e.g. '0.weight'
        !           377: # @param {string} $id - big hash resource id
        !           378: # @param {string} $def - the resource's default value for this parameter
        !           379: # @param {string} $uname - user name
        !           380: # @param {string} $udom - user domain
        !           381: # @param {string} $csec - section name
        !           382: # @param {string} $cgroup - group name
        !           383: # @param {hash reference} $courseopt - course parameters hash (result of lonnet::get_courseresdata, dump of course's resourcedata.db)
        !           384: # @returns {Array}
1.2       www       385: sub parmval {
1.275     raeburn   386:     my ($what,$id,$def,$uname,$udom,$csec,$cgroup,$courseopt)=@_;
                    387:     return &parmval_by_symb($what,&symbcache($id),$def,$uname,$udom,$csec,
                    388:                                                            $cgroup,$courseopt);
1.201     www       389: }
                    390: 
1.561   ! damieng   391: # Returns an array containing
        !           392: # - the most specific level that is defined for that parameter (integer)
        !           393: # - an array with the level as index and the parameter value as value (when defined)
        !           394: #   (level 1 is the most specific and will have precedence)
        !           395: #
        !           396: # @param {string} $what - part info and parameter name separated by a dot, e.g. '0.weight'
        !           397: # @param {string} $symb - resource symb
        !           398: # @param {string} $def - the resource's default value for this parameter
        !           399: # @param {string} $uname - user name
        !           400: # @param {string} $udom - user domain
        !           401: # @param {string} $csec - section name
        !           402: # @param {string} $cgroup - group name
        !           403: # @param {hash reference} $courseopt - course parameters hash (result of lonnet::get_courseresdata, dump of course's resourcedata.db)
        !           404: # @returns {Array}
1.201     www       405: sub parmval_by_symb {
1.275     raeburn   406:     my ($what,$symb,$def,$uname,$udom,$csec,$cgroup,$courseopt)=@_;
1.200     www       407: 
1.352     albertel  408:     my $useropt;
                    409:     if ($uname ne '' && $udom ne '') {
1.561   ! damieng   410:         $useropt = &Apache::lonnet::get_userresdata($uname,$udom);
1.352     albertel  411:     }
1.200     www       412: 
1.8       www       413:     my $result='';
1.44      albertel  414:     my @outpar=();
1.2       www       415: # ----------------------------------------------------- Cascading lookup scheme
1.446     bisitz    416:     my $map=(&Apache::lonnet::decode_symb($symb))[0];
1.305     albertel  417:     $map = &Apache::lonnet::deversion($map);
1.561   ! damieng   418:     
        !           419:     # NOTE: some of that code looks redondant with code in lonnavmaps::parmval_real,
        !           420:     # any change should be reflected there.
        !           421:     
1.201     www       422:     my $symbparm=$symb.'.'.$what;
1.556     raeburn   423:     my $recurseparm=$map.'___(rec).'.$what; 
1.201     www       424:     my $mapparm=$map.'___(all).'.$what;
1.10      www       425: 
1.269     raeburn   426:     my $grplevel=$env{'request.course.id'}.'.['.$cgroup.'].'.$what;
                    427:     my $grplevelr=$env{'request.course.id'}.'.['.$cgroup.'].'.$symbparm;
1.556     raeburn   428:     my $grpleveli=$env{'request.course.id'}.'.['.$cgroup.'].'.$recurseparm;
1.269     raeburn   429:     my $grplevelm=$env{'request.course.id'}.'.['.$cgroup.'].'.$mapparm;
                    430: 
1.190     albertel  431:     my $seclevel=$env{'request.course.id'}.'.['.$csec.'].'.$what;
                    432:     my $seclevelr=$env{'request.course.id'}.'.['.$csec.'].'.$symbparm;
1.556     raeburn   433:     my $secleveli=$env{'request.course.id'}.'.['.$csec.'].'.$recurseparm;
1.190     albertel  434:     my $seclevelm=$env{'request.course.id'}.'.['.$csec.'].'.$mapparm;
                    435: 
                    436:     my $courselevel=$env{'request.course.id'}.'.'.$what;
                    437:     my $courselevelr=$env{'request.course.id'}.'.'.$symbparm;
1.556     raeburn   438:     my $courseleveli=$env{'request.course.id'}.'.'.$recurseparm;
1.190     albertel  439:     my $courselevelm=$env{'request.course.id'}.'.'.$mapparm;
1.2       www       440: 
1.11      www       441: 
1.182     albertel  442: # --------------------------------------------------------- first, check course
1.11      www       443: 
1.561   ! damieng   444: # 18 - General Course
1.200     www       445:     if (defined($$courseopt{$courselevel})) {
1.556     raeburn   446:         $outpar[18]=$$courseopt{$courselevel};
                    447:         $result=18;
                    448:     }
                    449: 
1.561   ! damieng   450: # 17 - Map or Folder level in course (recursive) 
1.556     raeburn   451:     if (defined($$courseopt{$courseleveli})) {
                    452:         $outpar[17]=$$courseopt{$courseleveli};
                    453:         $result=17;
1.43      albertel  454:     }
1.11      www       455: 
1.561   ! damieng   456: # 16 - Map or Folder level in course (non-recursive)
1.200     www       457:     if (defined($$courseopt{$courselevelm})) {
1.556     raeburn   458:         $outpar[16]=$$courseopt{$courselevelm};
                    459:         $result=16;
1.43      albertel  460:     }
1.11      www       461: 
1.182     albertel  462: # ------------------------------------------------------- second, check default
                    463: 
1.561   ! damieng   464: # 15 - resource default
1.556     raeburn   465:     if (defined($def)) { $outpar[15]=$def; $result=15; }
1.182     albertel  466: 
                    467: # ------------------------------------------------------ third, check map parms
                    468: 
1.556     raeburn   469:     
1.561   ! damieng   470: # 14 - map default
1.376     albertel  471:     my $thisparm=&parmhash($symbparm);
1.556     raeburn   472:     if (defined($thisparm)) { $outpar[14]=$thisparm; $result=14; }
1.182     albertel  473: 
1.561   ! damieng   474: # 13 - resource level in course
1.200     www       475:     if (defined($$courseopt{$courselevelr})) {
1.556     raeburn   476:         $outpar[13]=$$courseopt{$courselevelr};
                    477:         $result=13;
1.43      albertel  478:     }
1.11      www       479: 
1.182     albertel  480: # ------------------------------------------------------ fourth, back to course
1.352     albertel  481:     if ($csec ne '') {
1.561   ! damieng   482: # 12 - General for section
1.200     www       483:         if (defined($$courseopt{$seclevel})) {
1.556     raeburn   484:             $outpar[12]=$$courseopt{$seclevel};
                    485:             $result=12;
                    486:         }
1.561   ! damieng   487: # 11 - Map or Folder level for section (recursive)
1.556     raeburn   488:         if (defined($$courseopt{$secleveli})) {
                    489:             $outpar[11]=$$courseopt{$secleveli};
                    490:             $result=11;
                    491:         }
1.561   ! damieng   492: # 10 - Map or Folder level for section (non-recursive)
1.200     www       493:         if (defined($$courseopt{$seclevelm})) {
1.556     raeburn   494:             $outpar[10]=$$courseopt{$seclevelm};
                    495:             $result=10;
                    496:         }
1.561   ! damieng   497: # 9 - resource level in section
1.200     www       498:         if (defined($$courseopt{$seclevelr})) {
1.556     raeburn   499:             $outpar[9]=$$courseopt{$seclevelr};
                    500:             $result=9;
                    501:         }
1.43      albertel  502:     }
1.275     raeburn   503: # ------------------------------------------------------ fifth, check course group
1.352     albertel  504:     if ($cgroup ne '') {
1.561   ! damieng   505: # 8 - General for group
1.269     raeburn   506:         if (defined($$courseopt{$grplevel})) {
1.556     raeburn   507:             $outpar[8]=$$courseopt{$grplevel};
                    508:             $result=8;
                    509:         }
1.561   ! damieng   510: # 7 - Map or Folder level for group (recursive)
1.556     raeburn   511:         if (defined($$courseopt{$grpleveli})) {
                    512:             $outpar[7]=$$courseopt{$grpleveli};
                    513:             $result=7;
1.269     raeburn   514:         }
1.561   ! damieng   515: # 6 - Map or Folder level for group (non-recursive)
1.269     raeburn   516:         if (defined($$courseopt{$grplevelm})) {
1.556     raeburn   517:             $outpar[6]=$$courseopt{$grplevelm};
                    518:             $result=6;
1.269     raeburn   519:         }
1.561   ! damieng   520: # 5 - resource level in group
1.269     raeburn   521:         if (defined($$courseopt{$grplevelr})) {
1.556     raeburn   522:             $outpar[5]=$$courseopt{$grplevelr};
                    523:             $result=5;
1.269     raeburn   524:         }
                    525:     }
1.11      www       526: 
1.556     raeburn   527: # ---------------------------------------------------------- sixth, check user
1.11      www       528: 
1.352     albertel  529:     if ($uname ne '') {
1.561   ! damieng   530: # 4 - General for specific student
        !           531:         if (defined($$useropt{$courselevel})) {
        !           532:             $outpar[4]=$$useropt{$courselevel};
        !           533:             $result=4;
        !           534:         }
1.556     raeburn   535: 
1.561   ! damieng   536: # 3 - Map or Folder level for specific student (recursive)
        !           537:         if (defined($$useropt{$courseleveli})) {
        !           538:             $outpar[3]=$$useropt{$courseleveli};
        !           539:             $result=3;
        !           540:         }
1.473     amueller  541: 
1.561   ! damieng   542: # 2 - Map or Folder level for specific student (non-recursive)
        !           543:         if (defined($$useropt{$courselevelm})) {
        !           544:             $outpar[2]=$$useropt{$courselevelm};
        !           545:             $result=2;
        !           546:         }
1.473     amueller  547: 
1.561   ! damieng   548: # 1 - resource level for specific student
        !           549:         if (defined($$useropt{$courselevelr})) {
        !           550:             $outpar[1]=$$useropt{$courselevelr};
        !           551:             $result=1;
        !           552:         }
1.43      albertel  553:     }
1.44      albertel  554:     return ($result,@outpar);
1.2       www       555: }
                    556: 
1.198     www       557: 
                    558: 
1.376     albertel  559: # --- Caches local to lonparmset
                    560: 
1.446     bisitz    561: 
1.561   ! damieng   562: # Reset lonparmset caches (called at the beginning and end of the handler).
1.376     albertel  563: sub reset_caches {
                    564:     &resetparmhash();
                    565:     &resetsymbcache();
                    566:     &resetrulescache();
1.203     www       567: }
                    568: 
1.561   ! damieng   569: # cache for map parameters, stored temporarily in $env{'request.course.fn'}_parms.db
        !           570: # (these parameters come from param elements in .sequence files created with the advanced RAT)
1.376     albertel  571: {
1.561   ! damieng   572:     my $parmhashid; # course identifier, to initialize the cache only once for a course
        !           573:     my %parmhash; # the parameter cache
        !           574:     # reset map parameter hash
1.376     albertel  575:     sub resetparmhash {
1.560     damieng   576:         undef($parmhashid);
                    577:         undef(%parmhash);
1.376     albertel  578:     }
1.446     bisitz    579: 
1.561   ! damieng   580:     # dump the _parms.db database into %parmhash
1.376     albertel  581:     sub cacheparmhash {
1.560     damieng   582:         if ($parmhashid eq  $env{'request.course.fn'}) { return; }
                    583:         my %parmhashfile;
                    584:         if (tie(%parmhashfile,'GDBM_File',
                    585:             $env{'request.course.fn'}.'_parms.db',&GDBM_READER(),0640)) {
                    586:             %parmhash=%parmhashfile;
                    587:             untie(%parmhashfile);
                    588:             $parmhashid=$env{'request.course.fn'};
                    589:         }
1.201     www       590:     }
1.446     bisitz    591: 
1.561   ! damieng   592:     # returns a parameter value for an identifier symb.parts.parameter, using the map parameter cache
1.376     albertel  593:     sub parmhash {
1.560     damieng   594:         my ($id) = @_;
                    595:         &cacheparmhash();
                    596:         return $parmhash{$id};
1.376     albertel  597:     }
1.560     damieng   598: }
1.376     albertel  599: 
1.561   ! damieng   600: # cache big hash id -> symb, using lonnavmaps to find association
1.446     bisitz    601: {
1.561   ! damieng   602:     my $symbsid; # course identifier, to initialize the cache only once for a course
        !           603:     my %symbs; # hash id->symb
        !           604:     # reset the id->symb cache
1.376     albertel  605:     sub resetsymbcache {
1.560     damieng   606:         undef($symbsid);
                    607:         undef(%symbs);
1.376     albertel  608:     }
1.446     bisitz    609: 
1.561   ! damieng   610:     # returns the symb corresponding to a big hash id (using lonnavmaps and a cache)
1.376     albertel  611:     sub symbcache {
1.560     damieng   612:         my $id=shift;
                    613:         if ($symbsid ne $env{'request.course.id'}) {
                    614:             undef(%symbs);
                    615:         }
                    616:         if (!$symbs{$id}) {
                    617:             my $navmap = Apache::lonnavmaps::navmap->new();
                    618:             if ($id=~/\./) {
                    619:                 my $resource=$navmap->getById($id);
                    620:                 $symbs{$id}=$resource->symb();
                    621:             } else {
                    622:                 my $resource=$navmap->getByMapPc($id);
                    623:                 $symbs{$id}=&Apache::lonnet::declutter($resource->src());
                    624:             }
                    625:             $symbsid=$env{'request.course.id'};
1.473     amueller  626:         }
1.560     damieng   627:         return $symbs{$id};
1.473     amueller  628:     }
1.560     damieng   629: }
1.201     www       630: 
1.561   ! damieng   631: # cache for parameter default actions (stored in parmdefactions.db)
1.446     bisitz    632: {
1.561   ! damieng   633:     my $rulesid; # course identifier, to initialize the cache only once for a course
        !           634:     my %rules; # parameter default actions hash
1.376     albertel  635:     sub resetrulescache {
1.560     damieng   636:         undef($rulesid);
                    637:         undef(%rules);
1.376     albertel  638:     }
1.446     bisitz    639: 
1.561   ! damieng   640:     # returns the value for a given key in the parameter default action hash
1.376     albertel  641:     sub rulescache {
1.560     damieng   642:         my $id=shift;
                    643:         if ($rulesid ne $env{'request.course.id'}
                    644:             && !defined($rules{$id})) {
                    645:             my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                    646:             my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
                    647:             %rules=&Apache::lonnet::dump('parmdefactions',$dom,$crs);
                    648:             $rulesid=$env{'request.course.id'};
                    649:         }
                    650:         return $rules{$id};
1.221     www       651:     }
                    652: }
                    653: 
1.416     jms       654: 
1.561   ! damieng   655: # Returns the values of the parameter type default action
        !           656: # "default value when manually setting".
        !           657: # If none is defined, ('','','','','') is returned.
        !           658: #
        !           659: # @param {string} $type - parameter type
        !           660: # @returns {Array<string>} - (hours, min, sec, value)
1.229     www       661: sub preset_defaults {
                    662:     my $type=shift;
                    663:     if (&rulescache($type.'_action') eq 'default') {
1.560     damieng   664:         # yes, there is something
                    665:         return (&rulescache($type.'_hours'),
                    666:             &rulescache($type.'_min'),
                    667:             &rulescache($type.'_sec'),
                    668:             &rulescache($type.'_value'));
1.229     www       669:     } else {
1.560     damieng   670:         # nothing there or something else
                    671:         return ('','','','','');
1.229     www       672:     }
                    673: }
                    674: 
1.416     jms       675: 
1.561   ! damieng   676: # Checks that a date is after enrollment start date and before
        !           677: # enrollment end date.
        !           678: # Returns HTML with a warning if it is not, or the empty string otherwise.
        !           679: # This is used by both overview and table modes.
        !           680: #
        !           681: # @param {integer} $checkdate - the date to check.
        !           682: # @returns {string} - HTML possibly containing a localized warning message.
1.277     www       683: sub date_sanity_info {
                    684:    my $checkdate=shift;
                    685:    unless ($checkdate) { return ''; }
                    686:    my $result='';
                    687:    my $crsprefix='course.'.$env{'request.course.id'}.'.';
                    688:    if ($env{$crsprefix.'default_enrollment_end_date'}) {
                    689:       if ($checkdate>$env{$crsprefix.'default_enrollment_end_date'}) {
1.413     bisitz    690:          $result.='<div class="LC_warning">'
                    691:                  .&mt('After course enrollment end!')
                    692:                  .'</div>';
1.277     www       693:       }
                    694:    }
                    695:    if ($env{$crsprefix.'default_enrollment_start_date'}) {
                    696:       if ($checkdate<$env{$crsprefix.'default_enrollment_start_date'}) {
1.413     bisitz    697:          $result.='<div class="LC_warning">'
                    698:                  .&mt('Before course enrollment start!')
                    699:                  .'</div>';
1.277     www       700:       }
                    701:    }
1.413     bisitz    702: # Preparation for additional warnings about dates in the past/future.
                    703: # An improved, more context sensitive version is recommended,
                    704: # e.g. warn for due and answer dates which are defined before the corresponding open date, etc.
                    705: #   if ($checkdate<time) {
                    706: #      $result.='<div class="LC_info">'
                    707: #              .'('.&mt('in the past').')'
                    708: #              .'</div>';
                    709: #      }
                    710: #   if ($checkdate>time) {
                    711: #      $result.='<div class="LC_info">'
                    712: #              .'('.&mt('in the future').')'
                    713: #              .'</div>';
                    714: #      }
1.277     www       715:    return $result;
                    716: }
1.561   ! damieng   717: 
        !           718: 
        !           719: # Store a parameter value and type by ID, also triggering more parameter changes based on parameter default actions.
1.186     www       720: #
1.561   ! damieng   721: # @param {string} $sresid - resource big hash id
        !           722: # @param {string} $spnam - part info and parameter name separated by a dot, e.g. '0.weight'
        !           723: # @param {integer} $snum - level
        !           724: # @param {string} $nval - new value
        !           725: # @param {string} $ntype - new type
        !           726: # @param {string} $uname - username
        !           727: # @param {string} $udom - userdomain
        !           728: # @param {string} $csec - section name
        !           729: # @param {string} $cgroup - group name
1.186     www       730: sub storeparm {
1.269     raeburn   731:     my ($sresid,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$cgroup)=@_;
1.275     raeburn   732:     &storeparm_by_symb(&symbcache($sresid),$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,'',$cgroup);
1.197     www       733: }
                    734: 
1.561   ! damieng   735: my %recstack; # hash parameter name -> 1 when a parameter was used before in a recursive call to storeparm_by_symb
        !           736: 
        !           737: # Store a parameter value and type by symb, also triggering more parameter changes based on parameter default actions.
        !           738: # Uses storeparm_by_symb_inner to actually store the parameter, ignoring any returned error.
        !           739: #
        !           740: # @param {string} $symb - resource symb
        !           741: # @param {string} $spnam - part info and parameter name separated by a dot, e.g. '0.weight'
        !           742: # @param {integer} $snum - level
        !           743: # @param {string} $nval - new value
        !           744: # @param {string} $ntype - new type
        !           745: # @param {string} $uname - username
        !           746: # @param {string} $udom - userdomain
        !           747: # @param {string} $csec - section name
        !           748: # @param {boolean} $recflag - should be true for recursive calls to storeparm_by_symb, false otherwise
        !           749: # @param {string} $cgroup - group name
1.197     www       750: sub storeparm_by_symb {
1.275     raeburn   751:     my ($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$recflag,$cgroup)=@_;
1.226     www       752:     unless ($recflag) {
1.560     damieng   753:         # first time call
                    754:         %recstack=();
                    755:         $recflag=1;
1.226     www       756:     }
1.560     damieng   757:     # store parameter
1.226     www       758:     &storeparm_by_symb_inner
1.473     amueller  759:     ($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$cgroup);
1.560     damieng   760:     # don't do anything if parameter was reset
1.266     www       761:     unless ($nval) { return; }
1.226     www       762:     my ($prefix,$parm)=($spnam=~/^(.*[\_\.])([^\_\.]+)$/);
1.560     damieng   763:     # remember that this was set
1.226     www       764:     $recstack{$parm}=1;
1.560     damieng   765:     # what does this trigger?
1.226     www       766:     foreach my $triggered (split(/\:/,&rulescache($parm.'_triggers'))) {
1.560     damieng   767:         # don't backfire
                    768:         unless ((!$triggered) || ($recstack{$triggered})) {
                    769:             my $action=&rulescache($triggered.'_action');
                    770:             my ($whichaction,$whichparm)=($action=~/^(.*\_)([^\_]+)$/);
                    771:             # set triggered parameter on same level
                    772:             my $newspnam=$prefix.$triggered;
                    773:             my $newvalue='';
                    774:             my $active=1;
                    775:             if ($action=~/^when\_setting/) {
                    776:             # are there restrictions?
                    777:                 if (&rulescache($triggered.'_triggervalue')=~/\w/) {
                    778:                     $active=0;
                    779:                     foreach my $possiblevalue (split(/\s*\,
                    780:                             \s*/,&rulescache($triggered.'_triggervalue'))) {
                    781:                         if (lc($possiblevalue) eq lc($nval)) { $active=1; }
                    782:                     }
                    783:                 }
                    784:                 $newvalue=&rulescache($triggered.'_value');
                    785:             } else {
                    786:                 my $totalsecs=((&rulescache($triggered.'_days')*24+&rulescache($triggered.'_hours'))*60+&rulescache($triggered.'_min'))*60+&rulescache($triggered.'_sec');
                    787:                 if ($action=~/^later\_than/) {
                    788:                     $newvalue=$nval+$totalsecs;
                    789:                 } else {
                    790:                     $newvalue=$nval-$totalsecs;
                    791:                 }
                    792:             }
                    793:             if ($active) {
                    794:                 &storeparm_by_symb($symb,$newspnam,$snum,$newvalue,&rulescache($triggered.'_type'),
                    795:                         $uname,$udom,$csec,$recflag,$cgroup);
                    796:             }
                    797:         }
1.226     www       798:     }
                    799:     return '';
                    800: }
                    801: 
1.561   ! damieng   802: # Adds all given arguments to the course parameter log.
        !           803: # @returns {string} - the answer to the lonnet query.
1.293     www       804: sub log_parmset {
1.525     raeburn   805:     return &Apache::lonnet::write_log('course','parameterlog',@_);
1.284     www       806: }
                    807: 
1.561   ! damieng   808: # Store a parameter value and type by symb, without using the parameter default actions.
        !           809: # Expire related sheets.
        !           810: #
        !           811: # @param {string} $symb - resource symb
        !           812: # @param {string} $spnam - part info and parameter name separated by a dot, e.g. '0.weight'
        !           813: # @param {integer} $snum - level
        !           814: # @param {string} $nval - new value
        !           815: # @param {string} $ntype - new type
        !           816: # @param {string} $uname - username
        !           817: # @param {string} $udom - userdomain
        !           818: # @param {string} $csec - section name
        !           819: # @param {string} $cgroup - group name
        !           820: # @returns {string} - HTML code with an error message if the parameter could not be stored.
1.226     www       821: sub storeparm_by_symb_inner {
1.197     www       822: # ---------------------------------------------------------- Get symb, map, etc
1.269     raeburn   823:     my ($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$cgroup)=@_;
1.197     www       824: # ---------------------------------------------------------- Construct prefixes
1.186     www       825:     $spnam=~s/\_([^\_]+)$/\.$1/;
1.446     bisitz    826:     my $map=(&Apache::lonnet::decode_symb($symb))[0];
1.305     albertel  827:     $map = &Apache::lonnet::deversion($map);
                    828: 
1.197     www       829:     my $symbparm=$symb.'.'.$spnam;
1.556     raeburn   830:     my $recurseparm=$map.'___(rec).'.$spnam;
1.197     www       831:     my $mapparm=$map.'___(all).'.$spnam;
                    832: 
1.269     raeburn   833:     my $grplevel=$env{'request.course.id'}.'.['.$cgroup.'].'.$spnam;
                    834:     my $grplevelr=$env{'request.course.id'}.'.['.$cgroup.'].'.$symbparm;
1.556     raeburn   835:     my $grpleveli=$env{'request.course.id'}.'.['.$cgroup.'].'.$recurseparm;
1.269     raeburn   836:     my $grplevelm=$env{'request.course.id'}.'.['.$cgroup.'].'.$mapparm;
                    837: 
1.190     albertel  838:     my $seclevel=$env{'request.course.id'}.'.['.$csec.'].'.$spnam;
                    839:     my $seclevelr=$env{'request.course.id'}.'.['.$csec.'].'.$symbparm;
1.556     raeburn   840:     my $secleveli=$env{'request.course.id'}.'.['.$csec.'].'.$recurseparm;
1.190     albertel  841:     my $seclevelm=$env{'request.course.id'}.'.['.$csec.'].'.$mapparm;
1.446     bisitz    842: 
1.190     albertel  843:     my $courselevel=$env{'request.course.id'}.'.'.$spnam;
                    844:     my $courselevelr=$env{'request.course.id'}.'.'.$symbparm;
1.556     raeburn   845:     my $courseleveli=$env{'request.course.id'}.'.'.$recurseparm;
1.190     albertel  846:     my $courselevelm=$env{'request.course.id'}.'.'.$mapparm;
1.446     bisitz    847: 
1.186     www       848:     my $storeunder='';
1.556     raeburn   849:     if (($snum==18) || ($snum==4)) { $storeunder=$courselevel; }
                    850:     if (($snum==17) || ($snum==3)) { $storeunder=$courseleveli; } 
                    851:     if (($snum==16) || ($snum==2)) { $storeunder=$courselevelm; }
                    852:     if (($snum==13) || ($snum==1)) { $storeunder=$courselevelr; }
                    853:     if ($snum==12) { $storeunder=$seclevel; }
                    854:     if ($snum==11) { $storeunder=$secleveli; }
                    855:     if ($snum==10) { $storeunder=$seclevelm; }
                    856:     if ($snum==9) { $storeunder=$seclevelr; }
                    857:     if ($snum==8) { $storeunder=$grplevel; }
                    858:     if ($snum==7) { $storeunder=$grpleveli; }
                    859:     if ($snum==6) { $storeunder=$grplevelm; }
                    860:     if ($snum==5) { $storeunder=$grplevelr; }
1.269     raeburn   861: 
1.446     bisitz    862: 
1.186     www       863:     my $delete;
                    864:     if ($nval eq '') { $delete=1;}
                    865:     my %storecontent = ($storeunder         => $nval,
1.473     amueller  866:             $storeunder.'.type' => $ntype);
1.186     www       867:     my $reply='';
1.560     damieng   868:     
1.556     raeburn   869:     if ($snum>4) {
1.186     www       870: # ---------------------------------------------------------------- Store Course
                    871: #
1.560     damieng   872:         my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                    873:         my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                    874:         # Expire sheets
                    875:         &Apache::lonnet::expirespread('','','studentcalc');
                    876:         if (($snum==13) || ($snum==9) || ($snum==5)) {
                    877:             &Apache::lonnet::expirespread('','','assesscalc',$symb);
                    878:         } elsif (($snum==14) || ($snum==10) || ($snum==6)) {
                    879:             &Apache::lonnet::expirespread('','','assesscalc',$map);
                    880:         } else {
                    881:             &Apache::lonnet::expirespread('','','assesscalc');
                    882:         }
                    883:         # Store parameter
                    884:         if ($delete) {
                    885:             $reply=&Apache::lonnet::del
                    886:             ('resourcedata',[keys(%storecontent)],$cdom,$cnum);
                    887:                 &log_parmset(\%storecontent,1);
                    888:         } else {
                    889:             $reply=&Apache::lonnet::cput
                    890:             ('resourcedata',\%storecontent,$cdom,$cnum);
                    891:             &log_parmset(\%storecontent);
                    892:         }
                    893:         &Apache::lonnet::devalidatecourseresdata($cnum,$cdom);
1.186     www       894:     } else {
                    895: # ------------------------------------------------------------------ Store User
                    896: #
1.560     damieng   897:         # Expire sheets
                    898:         &Apache::lonnet::expirespread($uname,$udom,'studentcalc');
                    899:         if ($snum==1) {
                    900:             &Apache::lonnet::expirespread
                    901:             ($uname,$udom,'assesscalc',$symb);
                    902:         } elsif ($snum==2) {
                    903:             &Apache::lonnet::expirespread
                    904:             ($uname,$udom,'assesscalc',$map);
                    905:         } else {
                    906:             &Apache::lonnet::expirespread($uname,$udom,'assesscalc');
                    907:         }
                    908:         # Store parameter
                    909:         if ($delete) {
                    910:             $reply=&Apache::lonnet::del
                    911:             ('resourcedata',[keys(%storecontent)],$udom,$uname);
                    912:             &log_parmset(\%storecontent,1,$uname,$udom);
                    913:         } else {
                    914:             $reply=&Apache::lonnet::cput
                    915:             ('resourcedata',\%storecontent,$udom,$uname);
                    916:             &log_parmset(\%storecontent,0,$uname,$udom);
                    917:         }
                    918:         &Apache::lonnet::devalidateuserresdata($uname,$udom);
1.186     www       919:     }
1.446     bisitz    920: 
1.186     www       921:     if ($reply=~/^error\:(.*)/) {
1.560     damieng   922:         return "<span class=\"LC_error\">Write Error: $1</span>";
1.186     www       923:     }
                    924:     return '';
                    925: }
                    926: 
1.9       www       927: 
1.561   ! damieng   928: # Returns HTML with the value of the given parameter,
        !           929: # using a readable format for dates, and
        !           930: # a warning if there is a problem with a date.
        !           931: # Used by table mode.
        !           932: # Returns HTML for the editmap.png image if no value is defined and $editable is true.
        !           933: #
        !           934: # @param {string} $value - the parameter value
        !           935: # @param {string} $type - the parameter type
        !           936: # @param {string} $name - the parameter name (unused)
        !           937: # @param {boolean} $editable - Set to true to get an icon when no value is defined.
1.9       www       938: sub valout {
1.554     raeburn   939:     my ($value,$type,$name,$editable)=@_;
1.59      matthew   940:     my $result = '';
                    941:     # Values of zero are valid.
                    942:     if (! $value && $value ne '0') {
1.528     bisitz    943:         if ($editable) {
                    944:             $result =
                    945:                 '<img src="/res/adm/pages/editmap.png"'
                    946:                .' alt="'.&mt('Change').'"'
1.539     raeburn   947:                .' title="'.&mt('Change').'" style="border:0;" />';
1.528     bisitz    948:         } else {
                    949:             $result='&nbsp;';
                    950:         }
1.59      matthew   951:     } else {
1.66      www       952:         if ($type eq 'date_interval') {
1.559     raeburn   953:             my ($totalsecs,$donesuffix) = split(/_/,$value,2);
                    954:             my ($usesdone,$donebuttontext,$proctor,$secretkey);
                    955:             if ($donesuffix =~ /^done\:([^\:]+)\:(.*)$/) {
                    956:                 $donebuttontext = $1;
                    957:                 (undef,$proctor,$secretkey) = split(/_/,$2);
                    958:                 $usesdone = 'done';
                    959:             } elsif ($donesuffix =~ /^done(|_.+)$/) {
                    960:                 $donebuttontext = &mt('Done');
                    961:                 ($usesdone,$proctor,$secretkey) = split(/_/,$donesuffix);
                    962:             }
1.554     raeburn   963:             my ($sec,$min,$hour,$mday,$mon,$year)=gmtime($totalsecs);
1.413     bisitz    964:             my @timer;
1.66      www       965:             $year=$year-70;
                    966:             $mday--;
                    967:             if ($year) {
1.413     bisitz    968: #               $result.=&mt('[quant,_1,yr]',$year).' ';
                    969:                 push(@timer,&mt('[quant,_1,yr]',$year));
1.66      www       970:             }
                    971:             if ($mon) {
1.413     bisitz    972: #               $result.=&mt('[quant,_1,mth]',$mon).' ';
                    973:                 push(@timer,&mt('[quant,_1,mth]',$mon));
1.66      www       974:             }
                    975:             if ($mday) {
1.413     bisitz    976: #               $result.=&mt('[quant,_1,day]',$mday).' ';
                    977:                 push(@timer,&mt('[quant,_1,day]',$mday));
1.66      www       978:             }
                    979:             if ($hour) {
1.413     bisitz    980: #               $result.=&mt('[quant,_1,hr]',$hour).' ';
                    981:                 push(@timer,&mt('[quant,_1,hr]',$hour));
1.66      www       982:             }
                    983:             if ($min) {
1.413     bisitz    984: #               $result.=&mt('[quant,_1,min]',$min).' ';
                    985:                 push(@timer,&mt('[quant,_1,min]',$min));
1.66      www       986:             }
                    987:             if ($sec) {
1.413     bisitz    988: #               $result.=&mt('[quant,_1,sec]',$sec).' ';
                    989:                 push(@timer,&mt('[quant,_1,sec]',$sec));
1.66      www       990:             }
1.413     bisitz    991: #           $result=~s/\s+$//;
                    992:             if (!@timer) { # Special case: all entries 0 -> display "0 secs" intead of empty field to keep this field editable
                    993:                 push(@timer,&mt('[quant,_1,sec]',0));
                    994:             }
                    995:             $result.=join(", ",@timer);
1.559     raeburn   996:             if ($usesdone eq 'done') {
1.558     raeburn   997:                 if ($secretkey) {
1.559     raeburn   998:                     $result .= ' '.&mt('+ "[_1]" with proctor key: [_2]',$donebuttontext,$secretkey);  
1.558     raeburn   999:                 } else {
1.559     raeburn  1000:                     $result .= ' + "'.$donebuttontext.'"';
                   1001:                 }
1.554     raeburn  1002:             }
1.213     www      1003:         } elsif (&isdateparm($type)) {
1.361     albertel 1004:             $result = &Apache::lonlocal::locallocaltime($value).
1.560     damieng  1005:                 &date_sanity_info($value);
1.59      matthew  1006:         } else {
                   1007:             $result = $value;
1.517     www      1008:             $result=~s/\,/\, /gs;
1.560     damieng  1009:             $result = &HTML::Entities::encode($result,'"<>&');
1.59      matthew  1010:         }
                   1011:     }
                   1012:     return $result;
1.9       www      1013: }
                   1014: 
1.59      matthew  1015: 
1.561   ! damieng  1016: # Returns HTML containing a link on a parameter value, for table mode.
        !          1017: # The link uses the javascript function 'pjump'.
        !          1018: #
        !          1019: # @param {string} $type - parameter type
        !          1020: # @param {string} $dis - dialog title for editing the parameter value and type
        !          1021: # @param {string} $value - parameter value
        !          1022: # @param {string} $marker - identifier for the parameter, "resource id&part_parameter name&level", will be passed as pres_marker when the user submits a change.
        !          1023: # @param {string} $return - prefix for the name of the form and field names that will be used to submit the form ('parmform.pres')
        !          1024: # @param {string} $call - javascript function to call to submit the form ('psub')
1.5       www      1025: sub plink {
                   1026:     my ($type,$dis,$value,$marker,$return,$call)=@_;
1.23      www      1027:     my $winvalue=$value;
                   1028:     unless ($winvalue) {
1.560     damieng  1029:         if (&isdateparm($type)) {
1.190     albertel 1030:             $winvalue=$env{'form.recent_'.$type};
1.23      www      1031:         } else {
1.190     albertel 1032:             $winvalue=$env{'form.recent_'.(split(/\_/,$type))[0]};
1.23      www      1033:         }
                   1034:     }
1.229     www      1035:     my ($parmname)=((split(/\&/,$marker))[1]=~/\_([^\_]+)$/);
                   1036:     my ($hour,$min,$sec,$val)=&preset_defaults($parmname);
                   1037:     unless (defined($winvalue)) { $winvalue=$val; }
1.554     raeburn  1038:     my $valout = &valout($value,$type,$parmname,1);
1.429     raeburn  1039:     my $unencmarker = $marker;
1.378     albertel 1040:     foreach my $item (\$type, \$dis, \$winvalue, \$marker, \$return, \$call,
1.473     amueller 1041:               \$hour, \$min, \$sec) {
1.560     damieng  1042:         $$item = &HTML::Entities::encode($$item,'"<>&');
                   1043:         $$item =~ s/\'/\\\'/g;
1.378     albertel 1044:     }
1.429     raeburn  1045:     return '<table width="100%"><tr valign="top" align="right"><td><a name="'.$unencmarker.'" /></td></tr><tr><td align="center">'.
1.473     amueller 1046:     '<a href="javascript:pjump('."'".$type."','".$dis."','".$winvalue."','"
                   1047:         .$marker."','".$return."','".$call."','".$hour."','".$min."','".$sec."'".');">'.
                   1048:         $valout.'</a></td></tr></table>';
1.5       www      1049: }
                   1050: 
1.561   ! damieng  1051: # Javascript for table mode.
1.280     albertel 1052: sub page_js {
                   1053: 
1.81      www      1054:     my $selscript=&Apache::loncommon::studentbrowser_javascript();
1.88      matthew  1055:     my $pjump_def = &Apache::lonhtmlcommon::pjump_javascript_definition();
1.280     albertel 1056: 
                   1057:     return(<<ENDJS);
                   1058: <script type="text/javascript">
1.454     bisitz   1059: // <![CDATA[
1.44      albertel 1060: 
1.88      matthew  1061:     $pjump_def
1.44      albertel 1062: 
                   1063:     function psub() {
                   1064:         if (document.parmform.pres_marker.value!='') {
                   1065:             document.parmform.action+='#'+document.parmform.pres_marker.value;
                   1066:             var typedef=new Array();
                   1067:             typedef=document.parmform.pres_type.value.split('_');
                   1068:            if (document.parmform.pres_type.value!='') {
                   1069:             if (typedef[0]=='date') {
                   1070:                 eval('document.parmform.recent_'+
                   1071:                      document.parmform.pres_type.value+
1.473     amueller 1072:              '.value=document.parmform.pres_value.value;');
1.44      albertel 1073:             } else {
                   1074:                 eval('document.parmform.recent_'+typedef[0]+
1.473     amueller 1075:              '.value=document.parmform.pres_value.value;');
1.44      albertel 1076:             }
1.473     amueller 1077:        }
1.44      albertel 1078:             document.parmform.submit();
                   1079:         } else {
                   1080:             document.parmform.pres_value.value='';
                   1081:             document.parmform.pres_marker.value='';
                   1082:         }
                   1083:     }
                   1084: 
1.57      albertel 1085:     function openWindow(url, wdwName, w, h, toolbar,scrollbar) {
                   1086:         var options = "width=" + w + ",height=" + h + ",";
                   1087:         options += "resizable=yes,scrollbars="+scrollbar+",status=no,";
                   1088:         options += "menubar=no,toolbar="+toolbar+",location=no,directories=no";
                   1089:         var newWin = window.open(url, wdwName, options);
                   1090:         newWin.focus();
                   1091:     }
1.523     raeburn  1092: 
1.454     bisitz   1093: // ]]>
1.523     raeburn  1094: 
1.44      albertel 1095: </script>
1.81      www      1096: $selscript
1.280     albertel 1097: ENDJS
                   1098: 
                   1099: }
1.507     www      1100: 
1.561   ! damieng  1101: # Javascript to show or hide the map selection (function showHide_courseContent),
        !          1102: # for table and overview modes.
1.523     raeburn  1103: sub showhide_js {
                   1104:     return <<"COURSECONTENTSCRIPT";
                   1105: 
                   1106: function showHide_courseContent() {
                   1107:     var parmlevValue=document.getElementById("parmlev").value;
                   1108:     if (parmlevValue == 'general') {
                   1109:         document.getElementById('mapmenu').style.display="none";
                   1110:     } else {
                   1111:         if ((parmlevValue == "full") || (parmlevValue == "map")) {
                   1112:             document.getElementById('mapmenu').style.display ="";
                   1113:         } else {
                   1114:             document.getElementById('mapmenu').style.display="none";
                   1115:         }
                   1116:     }
                   1117:     return;
                   1118: }
                   1119: 
                   1120: COURSECONTENTSCRIPT
                   1121: }
                   1122: 
1.561   ! damieng  1123: # Javascript functions showHideLenient and toggleParmTextbox, for overview mode
1.549     raeburn  1124: sub toggleparmtextbox_js {
                   1125:     return <<"ENDSCRIPT";
                   1126: 
                   1127: if (!document.getElementsByClassName) {
                   1128:     function getElementsByClassName(node, classname) {
                   1129:         var a = [];
                   1130:         var re = new RegExp('(^| )'+classname+'( |$)');
                   1131:         var els = node.getElementsByTagName("*");
                   1132:         for(var i=0,j=els.length; i<j; i++)
                   1133:             if(re.test(els[i].className))a.push(els[i]);
                   1134:         return a;
                   1135:     }
                   1136: }
                   1137: 
                   1138: function showHideLenient() {
                   1139:     var lenients;
                   1140:     var setRegExp = /^set_/;
                   1141:     if (document.getElementsByClassName) {
                   1142:         lenients = document.getElementsByClassName('LC_lenient_radio');
                   1143:     } else {
                   1144:         lenients = getElementsByClassName(document.body,'LC_lenient_radio');
                   1145:     }
                   1146:     if (lenients != 'undefined') {
                   1147:         for (var i=0; i<lenients.length; i++) {
                   1148:             if (lenients[i].checked) {
                   1149:                 if (lenients[i].value == 'weighted') {
                   1150:                     if (setRegExp.test(lenients[i].name)) {
                   1151:                         var identifier = lenients[i].name.replace(setRegExp,'');
                   1152:                         toggleParmTextbox(document.parmform,identifier);
                   1153:                     }
                   1154:                 }
                   1155:             }
                   1156:         }
                   1157:     }
                   1158:     return;
                   1159: }
                   1160: 
                   1161: function toggleParmTextbox(form,key) {
                   1162:     var divfortext = document.getElementById('LC_parmtext_'+key);
                   1163:     if (divfortext) {
                   1164:         var caller = form.elements['set_'+key];
                   1165:         if (caller.length) {
                   1166:             for (i=0; i<caller.length; i++) {
                   1167:                 if (caller[i].checked) {
                   1168:                     if (caller[i].value == 'weighted') {
                   1169:                         divfortext.style.display = 'inline';
                   1170:                     } else {
                   1171:                         divfortext.style.display = 'none';
                   1172:                     }
                   1173:                 }
                   1174:             }
                   1175:         }
                   1176:     }
                   1177:     return;
                   1178: }
                   1179: 
                   1180: ENDSCRIPT
                   1181: }
                   1182: 
1.561   ! damieng  1183: # Javascript function validateParms, for overview mode
1.549     raeburn  1184: sub validateparms_js {
                   1185:     return <<'ENDSCRIPT';
                   1186: 
                   1187: function validateParms() {
                   1188:     var textRegExp = /^settext_/;
                   1189:     var tailLenient = /\.lenient$/;
                   1190:     var patternRelWeight = /^\-?[\d.]+$/;
                   1191:     var patternLenientStd = /^(yes|no|default)$/;
                   1192:     var ipallowRegExp = /^setipallow_/;
                   1193:     var ipdenyRegExp = /^setipdeny_/; 
                   1194:     var patternIP = /[\[\]\*\.a-zA-Z\d\-]+/;
                   1195:     if ((document.parmform.elements.length != 'undefined')  && (document.parmform.elements.length) != 'null') {
                   1196:         if (document.parmform.elements.length) {
                   1197:             for (i=0; i<document.parmform.elements.length; i++) {
                   1198:                 var name=document.parmform.elements[i].name;
                   1199:                 if (textRegExp.test(name)) { 
                   1200:                     var identifier = name.replace(textRegExp,'');
                   1201:                     if (tailLenient.test(identifier)) {
                   1202:                         if (document.parmform.elements['set_'+identifier].length) {
                   1203:                             for (var j=0; j<document.parmform.elements['set_'+identifier].length; j++) {
                   1204:                                 if (document.parmform.elements['set_'+identifier][j].checked) {
                   1205:                                     if (!(patternLenientStd.test(document.parmform.elements['set_'+identifier][j].value))) {
                   1206:                                         var relweight = document.parmform.elements[i].value;
                   1207:                                         relweight = relweight.replace(/^\s+|\s+$/g,'');
                   1208:                                         if (!patternRelWeight.test(relweight)) {
                   1209:                                             relweight = '0.0';
                   1210:                                         }
                   1211:                                         if (document.parmform.elements['set_'+identifier][j].value == 'weighted') {
                   1212:                                             document.parmform.elements['set_'+identifier][j].value = relweight;
                   1213:                                         } else {
                   1214:                                             document.parmform.elements['set_'+identifier][j].value += ','+relweight;
                   1215:                                         }
                   1216:                                     }
                   1217:                                     break;
                   1218:                                 }
                   1219:                             }
                   1220:                         }
                   1221:                     }
                   1222:                 } else {
                   1223:                     if (ipallowRegExp.test(name)) {
                   1224:                         var identifier = name.replace(ipallowRegExp,'');
                   1225:                         var possallow = document.parmform.elements[i].value;
                   1226:                         possallow = possallow.replace(/^\s+|\s+$/g,'');
                   1227:                         if (patternIP.test(possallow)) {
                   1228:                             if (document.parmform.elements['set_'+identifier].value) {
                   1229:                                 possallow = ','+possallow;
                   1230:                             }
                   1231:                             document.parmform.elements['set_'+identifier].value += possallow; 
                   1232:                         }
                   1233:                     } else {
                   1234:                         if (ipdenyRegExp.test(name)) {
                   1235:                             var identifier = name.replace(ipdenyRegExp,'');
                   1236:                             var possdeny = document.parmform.elements[i].value;
                   1237:                             possdeny = possdeny.replace(/^\s+|\s+$/g,'');
                   1238:                             if (patternIP.test(possdeny)) {
                   1239:                                 possdeny = '!'+possdeny;
                   1240:                                 if (document.parmform.elements['set_'+identifier].value) {
                   1241:                                     possdeny = ','+possdeny;
                   1242:                                 }
                   1243:                                 document.parmform.elements['set_'+identifier].value += possdeny;
                   1244:                             }
                   1245:                         }
                   1246:                     }
                   1247:                 }
                   1248:             }
                   1249:         }
                   1250:     }
                   1251:     return true;
                   1252: }
                   1253: 
                   1254: ENDSCRIPT
                   1255: }
                   1256: 
1.561   ! damieng  1257: # Javascript initialization, for overview mode
1.549     raeburn  1258: sub ipacc_boxes_js  {
                   1259:     my $remove = &mt('Remove');
                   1260:     return <<"END";
                   1261: \$(document).ready(function() {
                   1262:     var wrapper         = \$(".LC_string_ipacc_wrap");
                   1263:     var add_button      = \$(".LC_add_ipacc_button");
                   1264:     var ipaccRegExp     = /^LC_string_ipacc_/;
                   1265: 
                   1266:     \$(add_button).click(function(e){
                   1267:         e.preventDefault();
                   1268:         var identifier = \$(this).closest("div").attr("id");
                   1269:         identifier = identifier.replace(ipaccRegExp,'');
1.551     raeburn  1270:         \$(this).closest('div').find('.LC_string_ipacc_inner').append('<div><input type="text" name="setip'+identifier+'" /><a href="#" class="LC_remove_ipacc">$remove</a></div>');
1.549     raeburn  1271:     });
                   1272: 
                   1273:     \$(wrapper).delegate(".LC_remove_ipacc","click", function(e){
                   1274:         e.preventDefault(); \$(this).closest("div").remove();
                   1275:     })
                   1276: });
                   1277: 
                   1278: 
                   1279: END
                   1280: }
                   1281: 
1.561   ! damieng  1282: # Javascript function toggleSecret, for overview mode.
1.558     raeburn  1283: sub done_proctor_js {
                   1284:     return <<"END";
                   1285: function toggleSecret(form,radio,key) {
                   1286:     var radios = form[radio+key];
                   1287:     if (radios.length) {
                   1288:         for (var i=0; i<radios.length; i++) {
                   1289:             if (radios[i].checked) {
                   1290:                 if (radios[i].value == '_done_proctor') {
                   1291:                     if (document.getElementById('done_'+key+'_proctorkey')) {
                   1292:                         document.getElementById('done_'+key+'_proctorkey').type='text';
                   1293:                     }
                   1294:                 } else {
                   1295:                     if (document.getElementById('done_'+key+'_proctorkey')) {
                   1296:                         document.getElementById('done_'+key+'_proctorkey').type='hidden';
                   1297:                         document.getElementById('done_'+key+'_proctorkey').value='';
                   1298:                     }
                   1299:                 }
                   1300:             }
                   1301:         }
                   1302:     }
                   1303: }
                   1304: END
                   1305: 
                   1306: }
                   1307: 
1.561   ! damieng  1308: # Prints HTML page start for table mode.
        !          1309: # @param {Apache2::RequestRec} $r - the Apache request
        !          1310: # @param {string} $psymb - resource symb
        !          1311: # @param {string} $crstype - course type (Community / Course / Placement Test)
1.280     albertel 1312: sub startpage {
1.531     raeburn  1313:     my ($r,$psymb,$crstype) = @_;
1.281     albertel 1314: 
1.515     raeburn  1315:     my %loaditems = (
                   1316:                       'onload'   => "group_or_section('cgroup')",
                   1317:                     );
                   1318:     if (!$psymb) {
1.523     raeburn  1319:         $loaditems{'onload'} = "showHide_courseContent(); group_or_section('cgroup'); resize_scrollbox('mapmenuscroll','1','1');";
1.515     raeburn  1320:     }
1.280     albertel 1321: 
1.560     damieng  1322:     if ((($env{'form.command'} eq 'set') && ($env{'form.url'}) &&
                   1323:             (!$env{'form.dis'})) || ($env{'form.symb'})) {
                   1324:         &Apache::lonhtmlcommon::add_breadcrumb({help=>'Problem_Parameters',
                   1325:             text=>"Problem Parameters"});
1.414     droeschl 1326:     } else {
1.560     damieng  1327:         &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=settable',
                   1328:             text=>"Table Mode",
                   1329:             help => 'Course_Setting_Parameters'});
1.414     droeschl 1330:     }
1.523     raeburn  1331:     my $js = &page_js().'
                   1332: <script type="text/javascript">
                   1333: // <![CDATA[
                   1334: '.
                   1335:             &Apache::lonhtmlcommon::resize_scrollbox_js('params').'
                   1336: // ]]>
                   1337: </script>
                   1338: ';
1.446     bisitz   1339:     my $start_page =
1.523     raeburn  1340:         &Apache::loncommon::start_page('Set/Modify Course Parameters',$js,
                   1341:                                        {'add_entries' => \%loaditems,});
1.446     bisitz   1342:     my $breadcrumbs =
1.473     amueller 1343:     &Apache::lonhtmlcommon::breadcrumbs('Table Mode Parameter Setting','Table_Mode');
1.506     www      1344:     my $escfilter=&Apache::lonhtmlcommon::entity_encode($env{'form.filter'});
                   1345:     my $escpart=&Apache::lonhtmlcommon::entity_encode($env{'form.part'});
1.507     www      1346:     $r->print($start_page.$breadcrumbs);
1.531     raeburn  1347:     &startSettingsScreen($r,'parmset',$crstype);
1.280     albertel 1348:     $r->print(<<ENDHEAD);
1.193     albertel 1349: <form method="post" action="/adm/parmset?action=settable" name="parmform">
1.419     bisitz   1350: <input type="hidden" value="" name="pres_value" />
                   1351: <input type="hidden" value="" name="pres_type" />
                   1352: <input type="hidden" value="" name="pres_marker" />
                   1353: <input type="hidden" value="1" name="prevvisit" />
1.506     www      1354: <input type="hidden" value="$escfilter" name="filter" />
                   1355: <input type="hidden" value="$escpart" name="part" />
1.44      albertel 1356: ENDHEAD
                   1357: }
                   1358: 
1.209     www      1359: 
1.561   ! damieng  1360: # Prints a row for table mode (except for the tr start).
        !          1361: # Every time a hash reference is passed, a single entry is used, so print_row
        !          1362: # could just use these values, but why make it simple when it can be complicated ?
        !          1363: #
        !          1364: # @param {Apache2::RequestRec} $r - the Apache request
        !          1365: # @param {string} $which - parameter key ('parameter_'.part.'_'.name)
        !          1366: # @param {hash reference} $part - parameter key -> parameter part (can be problem part.'_'.response id for response parameters)
        !          1367: # @param {hash reference} $name - parameter key -> parameter name
        !          1368: # @param {hash reference} $symbp - resource id -> symb
        !          1369: # @param {string} $rid - resource id
        !          1370: # @param {hash reference} $default - parameter key -> resource parameter default value
        !          1371: # @param {hash reference} $defaulttype - parameter key -> resource parameter default type
        !          1372: # @param {hash reference} $display - parameter key -> full title for the parameter
        !          1373: # @param {string} $defbgone - user level and other levels background color
        !          1374: # @param {string} $defbgtwo - section level background color, also used for part number
        !          1375: # @param {string} $defbgthree - group level background color
        !          1376: # @param {string} $parmlev - parameter level (Resource:'full', Map:'map', Course:'general')
        !          1377: # @param {string} $uname - user name
        !          1378: # @param {string} $udom - user domain
        !          1379: # @param {string} $csec - section name
        !          1380: # @param {string} $cgroup - group name
        !          1381: # @param {array reference} $usersgroups - list of groups the user belongs to, if any
        !          1382: # @param {boolean} $noeditgrp - true if no edit is allowed for group level parameters
1.44      albertel 1383: sub print_row {
1.201     www      1384:     my ($r,$which,$part,$name,$symbp,$rid,$default,$defaulttype,$display,$defbgone,
1.553     raeburn  1385:     $defbgtwo,$defbgthree,$parmlev,$uname,$udom,$csec,$cgroup,$usersgroups,$noeditgrp)=@_;
1.275     raeburn  1386:     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                   1387:     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   1388:     my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom);
1.553     raeburn  1389: 
1.560     damieng  1390:     # get the values for the parameter in cascading order
                   1391:     # empty levels will remain empty
1.44      albertel 1392:     my ($result,@outpar)=&parmval($$part{$which}.'.'.$$name{$which},
1.473     amueller 1393:       $rid,$$default{$which},$uname,$udom,$csec,$cgroup,$courseopt);
1.560     damieng  1394:     # get the type for the parameters
                   1395:     # problem: these may not be set for all levels
1.66      www      1396:     my ($typeresult,@typeoutpar)=&parmval($$part{$which}.'.'.
1.275     raeburn  1397:                                           $$name{$which}.'.type',$rid,
1.473     amueller 1398:          $$defaulttype{$which},$uname,$udom,$csec,$cgroup,$courseopt);
1.560     damieng  1399:     # cascade down manually
1.182     albertel 1400:     my $cascadetype=$$defaulttype{$which};
1.556     raeburn  1401:     for (my $i=18;$i>0;$i--) {
1.560     damieng  1402:         if ($typeoutpar[$i]) {
1.66      www      1403:             $cascadetype=$typeoutpar[$i];
1.560     damieng  1404:         } else {
1.66      www      1405:             $typeoutpar[$i]=$cascadetype;
                   1406:         }
                   1407:     }
1.57      albertel 1408:     my $parm=$$display{$which};
                   1409: 
1.203     www      1410:     if ($parmlev eq 'full') {
1.419     bisitz   1411:         $r->print('<td style="background-color:'.$defbgtwo.';" align="center">'
1.506     www      1412:                   .($$part{$which} eq '0'?'0 ('.&mt('default').')':$$part{$which}).'</td>');
1.433     raeburn  1413:     } else {
1.57      albertel 1414:         $parm=~s|\[.*\]\s||g;
                   1415:     }
1.231     www      1416:     my $automatic=&rulescache(($which=~/\_([^\_]+)$/)[0].'_triggers');
                   1417:     if ($automatic) {
1.560     damieng  1418:         $parm.='<span class="LC_warning"><br />'.&mt('Automatically sets').' '.join(', ',split(/\:/,$automatic)).'</span>';
1.231     www      1419:     }
1.427     bisitz   1420:     $r->print('<td>'.$parm.'</td>');
1.446     bisitz   1421: 
1.44      albertel 1422:     my $thismarker=$which;
                   1423:     $thismarker=~s/^parameter\_//;
                   1424:     my $mprefix=$rid.'&'.$thismarker.'&';
1.554     raeburn  1425:     my $effective_parm = &valout($outpar[$result],$typeoutpar[$result],$thismarker);
1.275     raeburn  1426:     my ($othergrp,$grp_parm,$controlgrp);
1.44      albertel 1427: 
1.57      albertel 1428:     if ($parmlev eq 'general') {
                   1429:         if ($uname) {
1.556     raeburn  1430:             &print_td($r,4,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
1.269     raeburn  1431:         } elsif ($cgroup) {
1.556     raeburn  1432:             &print_td($r,8,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
1.57      albertel 1433:         } elsif ($csec) {
1.556     raeburn  1434:             &print_td($r,12,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
1.57      albertel 1435:         } else {
1.556     raeburn  1436:             &print_td($r,18,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
1.57      albertel 1437:         }
                   1438:     } elsif ($parmlev eq 'map') {
                   1439:         if ($uname) {
1.556     raeburn  1440:             &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
                   1441:             &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display); 
1.269     raeburn  1442:         } elsif ($cgroup) {
1.556     raeburn  1443:             &print_td($r,7,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
                   1444:             &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
1.57      albertel 1445:         } elsif ($csec) {
1.556     raeburn  1446:             &print_td($r,11,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
                   1447:             &print_td($r,10,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
1.57      albertel 1448:         } else {
1.556     raeburn  1449:             &print_td($r,17,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
                   1450:             &print_td($r,16,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
1.57      albertel 1451:         }
                   1452:     } else {
1.275     raeburn  1453:         if ($uname) {
                   1454:             if (@{$usersgroups} > 1) {
                   1455:                 my ($coursereply,$grp_parm,$controlgrp);
                   1456:                 ($coursereply,$othergrp,$grp_parm,$controlgrp) =
                   1457:                     &print_usergroups($r,$$part{$which}.'.'.$$name{$which},
                   1458:                        $rid,$cgroup,$defbgone,$usersgroups,$result,$courseopt);
1.556     raeburn  1459:                 if ($coursereply && $result > 4) {
1.275     raeburn  1460:                     if (defined($controlgrp)) {
                   1461:                         if ($cgroup ne $controlgrp) {
                   1462:                             $effective_parm = $grp_parm;
                   1463:                             $result = 0;
                   1464:                         }
                   1465:                     }
                   1466:                 }
                   1467:             }
                   1468:         }
1.57      albertel 1469: 
1.556     raeburn  1470:         &print_td($r,18,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
                   1471:         &print_td($r,17,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
                   1472:         &print_td($r,16,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
                   1473:         &print_td($r,15,'#FFDDDD',$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
                   1474:         &print_td($r,14,'#FFDDDD',$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
1.548     raeburn  1475:         &print_td($r,13,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
                   1476: 
                   1477:         if ($csec) {
1.556     raeburn  1478:             &print_td($r,12,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
                   1479:             &print_td($r,11,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
                   1480:             &print_td($r,10,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
1.548     raeburn  1481:             &print_td($r,9,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
                   1482:         }
1.269     raeburn  1483: 
                   1484:         if ($cgroup) {
1.556     raeburn  1485:             &print_td($r,8,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
                   1486:             &print_td($r,7,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
1.553     raeburn  1487:             &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
                   1488:             &print_td($r,5,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
1.269     raeburn  1489:         }
1.446     bisitz   1490: 
1.548     raeburn  1491:         if ($uname) {
1.275     raeburn  1492:             if ($othergrp) {
                   1493:                 $r->print($othergrp);
                   1494:             }
1.556     raeburn  1495:             &print_td($r,4,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
1.548     raeburn  1496:             &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
                   1497:             &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
                   1498:             &print_td($r,1,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
                   1499:         }
1.57      albertel 1500: 
                   1501:     } # end of $parmlev if/else
1.419     bisitz   1502:     $r->print('<td style="background-color:#CCCCFF;" align="center">'.$effective_parm.'</td>');
1.136     albertel 1503: 
1.203     www      1504:     if ($parmlev eq 'full') {
1.136     albertel 1505:         my $sessionval=&Apache::lonnet::EXT('resource.'.$$part{$which}.
1.201     www      1506:                                         '.'.$$name{$which},$$symbp{$rid});
1.136     albertel 1507:         my $sessionvaltype=$typeoutpar[$result];
1.560     damieng  1508:         if (!defined($sessionvaltype)) {
                   1509:             $sessionvaltype=$$defaulttype{$which};
                   1510:         }
1.419     bisitz   1511:         $r->print('<td style="background-color:#999999;" align="center"><font color="#FFFFFF">'.
1.554     raeburn  1512:                   &valout($sessionval,$sessionvaltype,$$name{$which}).'&nbsp;'.
1.57      albertel 1513:                   '</font></td>');
1.136     albertel 1514:     }
1.44      albertel 1515:     $r->print('</tr>');
1.57      albertel 1516:     $r->print("\n");
1.44      albertel 1517: }
1.59      matthew  1518: 
1.561   ! damieng  1519: # Prints a cell for table mode.
        !          1520: #
        !          1521: # FIXME: some of these parameter names are uninspired ($which and $value)
        !          1522: # Also, it would make more sense to pass the display for this cell rather
        !          1523: # than the full display hash and the key to use.
        !          1524: #
        !          1525: # @param {Apache2::RequestRec} $r - the Apache request
        !          1526: # @param {integer} $which - level
        !          1527: # @param {string} $defbg - cell background color
        !          1528: # @param {integer} $result - the most specific level that is defined for that parameter
        !          1529: # @param {array reference} $outpar - array level -> parameter value (when defined)
        !          1530: # @param {string} $mprefix - resource id.'&'.part.'_'.parameter name.'&'
        !          1531: # @param {string} $value - parameter key ('parameter_'.part.'_'.name)
        !          1532: # @param {array reference} $typeoutpar - array level -> parameter type (when defined)
        !          1533: # @param {hash reference} $display - parameter key -> full title for the parameter
        !          1534: # @param {boolean} $noeditgrp - true if no edit is allowed for group level parameters
1.44      albertel 1535: sub print_td {
1.553     raeburn  1536:     my ($r,$which,$defbg,$result,$outpar,$mprefix,$value,$typeoutpar,$display,$noeditgrp)=@_;
1.419     bisitz   1537:     $r->print('<td style="background-color:'.(($result==$which)?'#AAFFAA':$defbg).
                   1538:               ';" align="center">');
1.437     raeburn  1539:     my $nolink = 0;
1.556     raeburn  1540:     if ($which == 14 || $which == 15) {
1.437     raeburn  1541:         $nolink = 1;
1.556     raeburn  1542:     } elsif (($env{'request.course.sec'} ne '') && ($which > 12)) {
1.552     raeburn  1543:         $nolink = 1;
1.556     raeburn  1544:     } elsif ($which == 5 || $which ==  6 || $which == 7 || $which == 8) {
1.553     raeburn  1545:         if ($noeditgrp) {
                   1546:             $nolink = 1;
                   1547:         }
1.437     raeburn  1548:     } elsif ($mprefix =~ /availablestudent\&$/) {
1.556     raeburn  1549:         if ($which > 4) {
1.437     raeburn  1550:             $nolink = 1;
                   1551:         }
1.533     raeburn  1552:     } elsif ($mprefix =~ /examcode\&$/) {
                   1553:         unless ($which == 2) {
                   1554:             $nolink = 1;
                   1555:         }
1.437     raeburn  1556:     }
                   1557:     if ($nolink) {
1.554     raeburn  1558:         $r->print(&valout($$outpar[$which],$$typeoutpar[$which],$mprefix));
1.561   ! damieng  1559: # FIXME: probably a good thing that mprefix is not used in valout, because it does not look like a parameter name !
1.114     www      1560:     } else {
1.437     raeburn  1561:         $r->print(&plink($$typeoutpar[$which],
                   1562:                          $$display{$value},$$outpar[$which],
                   1563:                          $mprefix."$which",'parmform.pres','psub'));
1.114     www      1564:     }
                   1565:     $r->print('</td>'."\n");
1.57      albertel 1566: }
                   1567: 
1.561   ! damieng  1568: # FIXME: Despite the name, this does not print anything, the $r parameter is unused.
        !          1569: # Returns HTML and other info for the cell added when a user is selected
        !          1570: # and that user is in several groups. This is the cell with the title "Control by other group".
        !          1571: #
        !          1572: # @param {Apache2::RequestRec} $r - the Apache request (unused)
        !          1573: # @param {string} $what - parameter part.'.'.parameter name
        !          1574: # @param {string} $rid - resource id
        !          1575: # @param {string} $cgroup - group name
        !          1576: # @param {string} $defbg - cell background color
        !          1577: # @param {array reference} $usersgroups - list of groups the user belongs to, if any
        !          1578: # @param {integer} $result - level
        !          1579: # @param {hash reference} $courseopt - course parameters hash (result of lonnet::get_courseresdata, dump of course's resourcedata.db)
        !          1580: # @returns {Array} - array (parameter value for the other group, HTML for the cell, HTML with the value, name of the other group)
1.275     raeburn  1581: sub print_usergroups {
                   1582:     my ($r,$what,$rid,$cgroup,$defbg,$usersgroups,$result,$courseopt) = @_;
                   1583:     my $courseid = $env{'request.course.id'};
                   1584:     my $output;
                   1585:     my $symb = &symbcache($rid);
                   1586:     my $symbparm=$symb.'.'.$what;
                   1587:     my $map=(&Apache::lonnet::decode_symb($symb))[0];
1.556     raeburn  1588:     my $recurseparm=$map.'___(rec).'.$what; 
1.275     raeburn  1589:     my $mapparm=$map.'___(all).'.$what;
                   1590:     my ($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype) =
1.556     raeburn  1591:           &parm_control_group($courseid,$usersgroups,$symbparm,$mapparm,
                   1592:                               $recurseparm,$what,$courseopt);
1.275     raeburn  1593:     my $bgcolor = $defbg;
                   1594:     my $grp_parm;
1.446     bisitz   1595:     if (($coursereply) && ($cgroup ne $resultgroup)) {
1.275     raeburn  1596:         if ($result > 3) {
1.419     bisitz   1597:             $bgcolor = '#AAFFAA';
1.554     raeburn  1598:             $grp_parm = &valout($coursereply,$resulttype,$what);
1.275     raeburn  1599:         }
1.554     raeburn  1600:         $grp_parm = &valout($coursereply,$resulttype,$what);
1.419     bisitz   1601:         $output = '<td style="background-color:'.$bgcolor.';" align="center">';
1.275     raeburn  1602:         if ($resultgroup && $resultlevel) {
                   1603:             $output .= '<small><b>'.$resultgroup.'</b> ('.$resultlevel.'): </small>'.$grp_parm;
                   1604:         } else {
                   1605:             $output .= '&nbsp;';
                   1606:         }
                   1607:         $output .= '</td>';
                   1608:     } else {
1.419     bisitz   1609:         $output .= '<td style="background-color:'.$bgcolor.';">&nbsp;</td>';
1.275     raeburn  1610:     }
                   1611:     return ($coursereply,$output,$grp_parm,$resultgroup);
                   1612: }
                   1613: 
1.561   ! damieng  1614: # Looks for a group with a defined parameter for given user and parameter.
        !          1615: # Used by print_usergroups.
        !          1616: #
        !          1617: # @param {string} $courseid - the course id
        !          1618: # @param {array reference} $usersgroups - list of groups the user belongs to, if any
        !          1619: # @param {string} $symbparm - end of the course parameter hash key for the group resource level
        !          1620: # @param {string} $mapparm - end of the course parameter hash key for the group map/folder level
        !          1621: # @param {string} $recurseparm - end of the course parameter hash key for the group recursive level
        !          1622: # @param {string} $what - parameter part.'.'.parameter name
        !          1623: # @param {hash reference} $courseopt - course parameters hash
        !          1624: # @returns {Array} - (parameter value for the group, course parameter hash key for the parameter, name of the group, level name, parameter type)
1.275     raeburn  1625: sub parm_control_group {
1.556     raeburn  1626:     my ($courseid,$usersgroups,$symbparm,$mapparm,$recurseparm,$what,$courseopt) = @_;
1.275     raeburn  1627:     my ($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype);
                   1628:     my $grpfound = 0;
1.556     raeburn  1629:     my @levels = ($symbparm,$mapparm,$recurseparm,$what);
                   1630:     my @levelnames = ('resource','map/folder','recursive','general');
1.275     raeburn  1631:     foreach my $group (@{$usersgroups}) {
                   1632:         if ($grpfound) { last; }
                   1633:         for (my $i=0; $i<@levels; $i++) {
                   1634:             my $item = $courseid.'.['.$group.'].'.$levels[$i];
                   1635:             if (defined($$courseopt{$item})) {
                   1636:                 $coursereply = $$courseopt{$item};
                   1637:                 $resultitem = $item;
                   1638:                 $resultgroup = $group;
                   1639:                 $resultlevel = $levelnames[$i];
                   1640:                 $resulttype = $$courseopt{$item.'.type'};
                   1641:                 $grpfound = 1;
                   1642:                 last;
                   1643:             }
                   1644:         }
                   1645:     }
                   1646:     return($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype);
                   1647: }
1.201     www      1648: 
1.63      bowersj2 1649: 
                   1650: 
1.561   ! damieng  1651: # extracts lots of information about all of the the course's resources into a variety of hashes.
1.63      bowersj2 1652: sub extractResourceInformation {
                   1653:     my $ids = shift;
                   1654:     my $typep = shift;
                   1655:     my $keyp = shift;
                   1656:     my $allparms = shift;
                   1657:     my $allparts = shift;
                   1658:     my $allmaps = shift;
                   1659:     my $mapp = shift;
                   1660:     my $symbp = shift;
1.82      www      1661:     my $maptitles=shift;
1.196     www      1662:     my $uris=shift;
1.210     www      1663:     my $keyorder=shift;
1.211     www      1664:     my $defkeytype=shift;
1.196     www      1665: 
1.210     www      1666:     my $keyordercnt=100;
1.63      bowersj2 1667: 
1.196     www      1668:     my $navmap = Apache::lonnavmaps::navmap->new();
                   1669:     my @allres=$navmap->retrieveResources(undef,undef,1,undef,1);
                   1670:     foreach my $resource (@allres) {
1.480     amueller 1671:         my $id=$resource->id();
1.196     www      1672:         my ($mapid,$resid)=split(/\./,$id);
1.480     amueller 1673:         if ($mapid eq '0') { next; }
                   1674:         $$ids[$#$ids+1]=$id;
                   1675:         my $srcf=$resource->src();
                   1676:         $srcf=~/\.(\w+)$/;
                   1677:         $$typep{$id}=$1;
                   1678:         $$keyp{$id}='';
1.196     www      1679:         $$uris{$id}=$srcf;
1.512     foxr     1680: 
1.480     amueller 1681:         foreach my $key (split(/\,/,&Apache::lonnet::metadata($srcf,'allpossiblekeys'))) {
                   1682:             next if ($key!~/^parameter_/);
1.363     albertel 1683: 
1.209     www      1684: # Hidden parameters
1.480     amueller 1685:             next if (&Apache::lonnet::metadata($srcf,$key.'.hidden') eq 'parm');
1.209     www      1686: #
                   1687: # allparms is a hash of parameter names
                   1688: #
1.480     amueller 1689:             my $name=&Apache::lonnet::metadata($srcf,$key.'.name');
                   1690:             if (!exists($$allparms{$name}) || $$allparms{$name} =~ m/^\s*$/ ) {
                   1691:                 my ($display,$parmdis);
                   1692:                 $display = &standard_parameter_names($name);
                   1693:                 if ($display eq '') {
                   1694:                     $display= &Apache::lonnet::metadata($srcf,$key.'.display');
                   1695:                     $parmdis = $display;
                   1696:                     $parmdis =~ s/\s*\[Part.*$//g;
                   1697:                 } else {
                   1698:                     $parmdis = &mt($display);
                   1699:                 }
                   1700:                 $$allparms{$name}=$parmdis;
                   1701:                 if (ref($defkeytype)) {
                   1702:                     $$defkeytype{$name}=
                   1703:                     &Apache::lonnet::metadata($srcf,$key.'.type');
                   1704:                 }
                   1705:             }
1.363     albertel 1706: 
1.209     www      1707: #
                   1708: # allparts is a hash of all parts
                   1709: #
1.480     amueller 1710:             my $part= &Apache::lonnet::metadata($srcf,$key.'.part');
                   1711:             $$allparts{$part} = &mt('Part: [_1]',$part);
1.209     www      1712: #
                   1713: # Remember all keys going with this resource
                   1714: #
1.480     amueller 1715:             if ($$keyp{$id}) {
                   1716:                 $$keyp{$id}.=','.$key;
                   1717:             } else {
                   1718:                 $$keyp{$id}=$key;
                   1719:             }   
1.210     www      1720: #
                   1721: # Put in order
1.446     bisitz   1722: #
1.480     amueller 1723:             unless ($$keyorder{$key}) {
                   1724:                 $$keyorder{$key}=$keyordercnt;
                   1725:                 $keyordercnt++;
                   1726:             }
1.473     amueller 1727:         }
                   1728: 
                   1729: 
1.480     amueller 1730:         if (!exists($$mapp{$mapid})) {
                   1731:             $$mapp{$id}=
                   1732:             &Apache::lonnet::declutter($resource->enclosing_map_src());
                   1733:             $$mapp{$mapid}=$$mapp{$id};
                   1734:             $$allmaps{$mapid}=$$mapp{$id};
                   1735:             if ($mapid eq '1') {
1.532     raeburn  1736:                 $$maptitles{$mapid}=&mt('Main Content');
1.480     amueller 1737:             } else {
                   1738:                 $$maptitles{$mapid}=&Apache::lonnet::gettitle($$mapp{$id});
                   1739:             }
                   1740:             $$maptitles{$$mapp{$id}}=$$maptitles{$mapid};
1.556     raeburn  1741:             $$symbp{$mapid}=$$mapp{$id}.'___(all)';  # Added in rev. 1.57, but seems not to be used.
                   1742:                                                      # Lines 1038 and 1114 which use $symbp{$mapid}
                   1743:                                                      # are commented out in rev. 1.57
1.473     amueller 1744:         } else {
1.480     amueller 1745:             $$mapp{$id} = $$mapp{$mapid};
1.473     amueller 1746:         }
1.480     amueller 1747:         $$symbp{$id}=&Apache::lonnet::encode_symb($$mapp{$id},$resid,$srcf);
1.63      bowersj2 1748:     }
                   1749: }
                   1750: 
1.208     www      1751: 
                   1752: 
1.213     www      1753: sub isdateparm {
                   1754:     my $type=shift;
                   1755:     return (($type=~/^date/) && (!($type eq 'date_interval')));
                   1756: }
                   1757: 
1.468     amueller 1758: #
1.501     bisitz   1759: # parmmenu displays a list of the selected parameters.
                   1760: # It also offers a link to show/hide the complete parameter list
                   1761: # from which you can select all desired parameters.
1.468     amueller 1762: #
1.208     www      1763: sub parmmenu {
1.211     www      1764:     my ($r,$allparms,$pscat,$keyorder)=@_;
1.208     www      1765:     my $tempkey;
                   1766:     $r->print(<<ENDSCRIPT);
                   1767: <script type="text/javascript">
1.454     bisitz   1768: // <![CDATA[
1.208     www      1769:     function checkall(value, checkName) {
1.453     schualex 1770: 
                   1771:         var li = "_li";
                   1772:         var displayOverview = "";
                   1773:         
                   1774:         if (value == false) {
                   1775:             displayOverview = "none"
                   1776:         }
                   1777: 
1.473     amueller 1778:     for (i=0; i<document.forms.parmform.elements.length; i++) {
1.208     www      1779:             ele = document.forms.parmform.elements[i];
                   1780:             if (ele.name == checkName) {
                   1781:                 document.forms.parmform.elements[i].checked=value;
                   1782:             }
                   1783:         }
                   1784:     }
1.210     www      1785: 
                   1786:     function checkthis(thisvalue, checkName) {
1.458     schualex 1787: 
                   1788: 
1.473     amueller 1789:     for (i=0; i<document.forms.parmform.elements.length; i++) {
1.210     www      1790:             ele = document.forms.parmform.elements[i];
                   1791:             if (ele.name == checkName) {
1.473     amueller 1792:         if (ele.value == thisvalue) {
                   1793:             document.forms.parmform.elements[i].checked=true;
                   1794:         }
1.210     www      1795:             }
                   1796:         }
                   1797:     }
                   1798: 
                   1799:     function checkdates() {
1.473     amueller 1800:     checkthis('duedate','pscat');
                   1801:      checkthis('opendate','pscat');
                   1802:     checkthis('answerdate','pscat');
1.218     www      1803:     }
                   1804: 
                   1805:     function checkdisset() {
1.521     raeburn  1806:      checkthis('discussend','pscat');
1.473     amueller 1807:      checkthis('discusshide','pscat');
1.521     raeburn  1808:      checkthis('discussvote','pscat');
1.218     www      1809:     }
                   1810: 
                   1811:     function checkcontdates() {
1.473     amueller 1812:     checkthis('contentopen','pscat');
                   1813:      checkthis('contentclose','pscat');
1.218     www      1814:     }
1.446     bisitz   1815: 
1.210     www      1816:     function checkvisi() {
1.473     amueller 1817:     checkthis('hiddenresource','pscat');
                   1818:      checkthis('encrypturl','pscat');
                   1819:     checkthis('problemstatus','pscat');
                   1820:     checkthis('contentopen','pscat');
                   1821:     checkthis('opendate','pscat');
1.210     www      1822:     }
                   1823: 
                   1824:     function checkparts() {
1.473     amueller 1825:     checkthis('hiddenparts','pscat');
                   1826:     checkthis('display','pscat');
                   1827:     checkthis('ordered','pscat');
1.210     www      1828:     }
                   1829: 
                   1830:     function checkstandard() {
                   1831:         checkall(false,'pscat');
1.473     amueller 1832:     checkdates();
                   1833:     checkthis('weight','pscat');
                   1834:     checkthis('maxtries','pscat');
1.501     bisitz   1835:     checkthis('type','pscat');
                   1836:     checkthis('problemstatus','pscat');
1.210     www      1837:     }
                   1838: 
1.454     bisitz   1839: // ]]>
1.208     www      1840: </script>
                   1841: ENDSCRIPT
1.453     schualex 1842: 
1.491     bisitz   1843:     $r->print('<hr />');
1.453     schualex 1844:     &shortCuts($r,$allparms,$pscat,$keyorder);
1.491     bisitz   1845:     $r->print('<hr />');
1.453     schualex 1846: }
1.465     amueller 1847: # return a hash
                   1848: sub categories {
                   1849:     return ('time_settings' => 'Time Settings',
                   1850:     'grading' => 'Grading',
                   1851:     'tries' => 'Tries',
                   1852:     'problem_appearance' => 'Problem Appearance',
                   1853:     'behaviour_of_input_fields' => 'Behaviour of Input Fields',
                   1854:     'hiding' => 'Hiding',
                   1855:     'high_level_randomization' => 'High Level Randomization',
                   1856:     'slots' => 'Slots',
                   1857:     'file_submission' => 'File Submission',
                   1858:     'misc' => 'Miscellaneous' ); 
                   1859: }
                   1860: 
                   1861: # return a hash. Like a look-up table
                   1862: sub lookUpTableParameter {
                   1863:  
                   1864:     return ( 
                   1865:         'opendate' => 'time_settings',
                   1866:         'duedate' => 'time_settings',
                   1867:         'answerdate' => 'time_settings',
                   1868:         'interval' => 'time_settings',
                   1869:         'contentopen' => 'time_settings',
                   1870:         'contentclose' => 'time_settings',
                   1871:         'discussend' => 'time_settings',
1.560     damieng  1872:         'printstartdate' => 'time_settings',
                   1873:         'printenddate' => 'time_settings',
1.465     amueller 1874:         'weight' => 'grading',
                   1875:         'handgrade' => 'grading',
                   1876:         'maxtries' => 'tries',
                   1877:         'hinttries' => 'tries',
1.503     raeburn  1878:         'randomizeontries' => 'tries',
1.465     amueller 1879:         'type' => 'problem_appearance',
                   1880:         'problemstatus' => 'problem_appearance',
                   1881:         'display' => 'problem_appearance',
                   1882:         'ordered' => 'problem_appearance',
                   1883:         'numbubbles' => 'problem_appearance',
                   1884:         'tol' => 'behaviour_of_input_fields',
                   1885:         'sig' => 'behaviour_of_input_fields',
                   1886:         'turnoffunit' => 'behaviour_of_input_fields',
                   1887:         'hiddenresource' => 'hiding',
                   1888:         'hiddenparts' => 'hiding',
                   1889:         'discusshide' => 'hiding',
                   1890:         'buttonshide' => 'hiding',
                   1891:         'turnoffeditor' => 'hiding',
                   1892:         'encrypturl' => 'hiding',
                   1893:         'randomorder' => 'high_level_randomization',
                   1894:         'randompick' => 'high_level_randomization',
                   1895:         'available' => 'slots',
                   1896:         'useslots' => 'slots',
                   1897:         'availablestudent' => 'slots',
                   1898:         'uploadedfiletypes' => 'file_submission',
                   1899:         'maxfilesize' => 'file_submission',
                   1900:         'cssfile' => 'misc',
                   1901:         'mapalias' => 'misc',
                   1902:         'acc' => 'misc',
                   1903:         'maxcollaborators' => 'misc',
                   1904:         'scoreformat' => 'misc',
1.514     raeburn  1905:         'lenient' => 'grading',
1.519     raeburn  1906:         'retrypartial' => 'tries',
1.521     raeburn  1907:         'discussvote'  => 'misc',
1.533     raeburn  1908:         'examcode' => 'high_level_randomization', 
1.465     amueller 1909:     );    
                   1910: }
                   1911: 
                   1912: sub whatIsMyCategory {
                   1913:     my $name = shift;
                   1914:     my $catList = shift;
                   1915:     my @list;
                   1916:     my %lookUpList = &lookUpTableParameter; #Initilize the lookupList
                   1917:     my $cat = $lookUpList{$name};
                   1918:     if (defined($cat)) {
                   1919:         if (!defined($$catList{$cat})){
                   1920:             push @list, ($name);
                   1921:             $$catList{$cat} = \@list;
                   1922:         } else {
                   1923:             push @{${$catList}{$cat}}, ($name);     
                   1924:         }
                   1925:     } else {
                   1926:         if (!defined($$catList{'misc'})){
                   1927:             push @list, ($name);
                   1928:             $$catList{'misc'} = \@list;
                   1929:         } else {
                   1930:             push @{${$catList}{'misc'}}, ($name);     
                   1931:         }
                   1932:     }        
                   1933: }
                   1934: 
                   1935: sub keysindisplayorderCategory {
                   1936:     my ($name,$keyorder)=@_;
                   1937:     return sort {
1.473     amueller 1938:         $$keyorder{'parameter_0_'.$a} <=> $$keyorder{'parameter_0_'.$b}; 
1.465     amueller 1939:     } ( @{$name});
                   1940: }
                   1941: 
1.467     amueller 1942: sub category_order {
                   1943:     return (
                   1944:         'time_settings' => 1,
                   1945:         'grading' => 2,
                   1946:         'tries' => 3,
                   1947:         'problem_appearance' => 4,
                   1948:         'hiding' => 5,
                   1949:         'behaviour_of_input_fields' => 6,
                   1950:         'high_level_randomization'  => 7,
                   1951:         'slots' => 8,
                   1952:         'file_submission' => 9,
                   1953:         'misc' => 10
                   1954:     );
                   1955: 
                   1956: }
1.453     schualex 1957: 
                   1958: sub parmboxes {
                   1959:     my ($r,$allparms,$pscat,$keyorder)=@_;
1.548     raeburn  1960:     my %categories = &categories();
1.467     amueller 1961:     my %category_order = &category_order();
1.465     amueller 1962:     my %categoryList = (
                   1963:         'time_settings' => [],
                   1964:         'grading' => [],
                   1965:         'tries' => [],
                   1966:         'problem_appearance' => [],
                   1967:         'behaviour_of_input_fields' => [],
                   1968:         'hiding' => [],
                   1969:         'high_level_randomization' => [],
                   1970:         'slots' => [],
                   1971:         'file_submission' => [],
                   1972:         'misc' => [],
1.489     bisitz   1973:     );
1.510     www      1974: 
1.548     raeburn  1975:     foreach my $tempparameter (keys(%$allparms)) {
1.465     amueller 1976:         &whatIsMyCategory($tempparameter, \%categoryList);
                   1977:     }
1.453     schualex 1978:     #part to print the parm-list
1.536     raeburn  1979:     foreach my $key (sort { $category_order{$a} <=> $category_order{$b} } keys(%categoryList)) {
                   1980:         next if (@{$categoryList{$key}} == 0);
                   1981:         next if ($key eq '');
                   1982:         $r->print('<div class="LC_Box LC_400Box">'
                   1983:                  .'<h4 class="LC_hcell">'.&mt($categories{$key}).'</h4>'."\n");
                   1984:         foreach my $tempkey (&keysindisplayorderCategory($categoryList{$key},$keyorder)) {
                   1985:             $r->print('<span class="LC_nobreak">'
                   1986:                      .'<label><input type="checkbox" name="pscat" '
                   1987:                      .'value="'.$tempkey.'" ');
                   1988:             if ($$pscat[0] eq "all" || grep $_ eq $tempkey, @{$pscat}) {
                   1989:                 $r->print( ' checked="checked"');
                   1990:             }
                   1991:             $r->print(' />'.($$allparms{$tempkey}=~/\S/ ? $$allparms{$tempkey}
1.465     amueller 1992:                                                       : $tempkey)
1.536     raeburn  1993:                      .'</label></span><br />'."\n");
1.465     amueller 1994:         }
1.536     raeburn  1995:         $r->print('</div>');
1.465     amueller 1996:     }
1.536     raeburn  1997:     $r->print("\n");
1.453     schualex 1998: }
1.468     amueller 1999: #
                   2000: # This function offers some links on the parameter section to get with one click a group a parameters
                   2001: #
1.453     schualex 2002: sub shortCuts {
                   2003:     my ($r,$allparms,$pscat,$keyorder)=@_;
                   2004: 
1.491     bisitz   2005:     # Parameter Selection
                   2006:     $r->print(
                   2007:         &Apache::lonhtmlcommon::start_funclist(&mt('Parameter Selection'))
                   2008:        .&Apache::lonhtmlcommon::add_item_funclist(
                   2009:             '<a href="javascript:checkall(true, \'pscat\')">'.&mt('Select All').'</a>')
                   2010:        .&Apache::lonhtmlcommon::add_item_funclist(
                   2011:             '<a href="javascript:checkstandard()">'.&mt('Select Common Only').'</a>')
                   2012:        .&Apache::lonhtmlcommon::add_item_funclist(
                   2013:             '<a href="javascript:checkall(false, \'pscat\')">'.&mt('Unselect All').'</a>')
                   2014:        .&Apache::lonhtmlcommon::end_funclist()
                   2015:     );
                   2016: 
                   2017:     # Add Selection for...
                   2018:     $r->print(
                   2019:         &Apache::lonhtmlcommon::start_funclist(&mt('Add Selection for...'))
                   2020:        .&Apache::lonhtmlcommon::add_item_funclist(
                   2021:             '<a href="javascript:checkdates()">'.&mt('Problem Dates').'</a>')
                   2022:        .&Apache::lonhtmlcommon::add_item_funclist(
                   2023:             '<a href="javascript:checkcontdates()">'.&mt('Content Dates').'</a>')
                   2024:        .&Apache::lonhtmlcommon::add_item_funclist(
                   2025:             '<a href="javascript:checkdisset()">'.&mt('Discussion Settings').'</a>')
                   2026:        .&Apache::lonhtmlcommon::add_item_funclist(
                   2027:             '<a href="javascript:checkvisi()">'.&mt('Visibilities').'</a>')
                   2028:        .&Apache::lonhtmlcommon::add_item_funclist(
                   2029:             '<a href="javascript:checkparts()">'.&mt('Part Parameters').'</a>')
                   2030:        .&Apache::lonhtmlcommon::end_funclist()
                   2031:     );
1.208     www      2032: }
                   2033: 
1.209     www      2034: sub partmenu {
1.446     bisitz   2035:     my ($r,$allparts,$psprt)=@_;
1.523     raeburn  2036:     my $selsize = 1+scalar(keys(%{$allparts}));
                   2037:     if ($selsize > 8) {
                   2038:         $selsize = 8;
                   2039:     }
1.446     bisitz   2040: 
1.523     raeburn  2041:     $r->print('<select multiple="multiple" name="psprt" size="'.$selsize.'">');
1.208     www      2042:     $r->print('<option value="all"');
1.401     bisitz   2043:     $r->print(' selected="selected"') unless (@{$psprt});
1.208     www      2044:     $r->print('>'.&mt('All Parts').'</option>');
                   2045:     my %temphash=();
                   2046:     foreach (@{$psprt}) { $temphash{$_}=1; }
1.234     albertel 2047:     foreach my $tempkey (sort {
1.560     damieng  2048:                 if ($a==$b) { return ($a cmp $b) } else { return ($a <=> $b); }
                   2049:             } keys(%{$allparts})) {
                   2050:         unless ($tempkey =~ /\./) {
                   2051:             $r->print('<option value="'.$tempkey.'"');
                   2052:             if ($$psprt[0] eq "all" ||  $temphash{$tempkey}) {
                   2053:                 $r->print(' selected="selected"');
                   2054:             }
                   2055:             $r->print('>'.$$allparts{$tempkey}.'</option>');
1.473     amueller 2056:         }
1.208     www      2057:     }
1.446     bisitz   2058:     $r->print('</select>');
1.209     www      2059: }
                   2060: 
                   2061: sub usermenu {
1.553     raeburn  2062:     my ($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,$usersgroups,$pssymb)=@_;
1.209     www      2063:     my $chooseopt=&Apache::loncommon::select_dom_form($udom,'udom').' '.
                   2064:         &Apache::loncommon::selectstudent_link('parmform','uname','udom');
                   2065:     my $selscript=&Apache::loncommon::studentbrowser_javascript();
1.412     bisitz   2066: 
1.209     www      2067:     my $sections='';
1.300     albertel 2068:     my %sectionhash = &Apache::loncommon::get_sections();
                   2069: 
1.269     raeburn  2070:     my $groups;
1.553     raeburn  2071:     my %grouphash;
                   2072:     if (($pssymb) || &Apache::lonnet::allowed('mdg',$env{'request.course.id'})) {
                   2073:         %grouphash = &Apache::longroup::coursegroups();
                   2074:     } elsif ($env{'request.course.groups'} ne '') {
                   2075:         map { $grouphash{$_} = 1; } split(/,/,$env{'request.course.groups'});
                   2076:     }
1.299     albertel 2077: 
1.412     bisitz   2078:     my $g_s_header='';
                   2079:     my $g_s_footer='';
1.446     bisitz   2080: 
1.552     raeburn  2081:     my $currsec = $env{'request.course.sec'};
                   2082:     if ($currsec) {
                   2083:         $sections=&mt('Section:').' '.$currsec;
                   2084:         if (%grouphash) {
                   2085:             $sections .= ';'.('&nbsp;' x2);
                   2086:         }
                   2087:     } elsif (%sectionhash && $currsec eq '') {
1.412     bisitz   2088:         $sections=&mt('Section:').' <select name="csec"';
1.299     albertel 2089:         if (%grouphash && $parmlev ne 'full') {
1.269     raeburn  2090:             $sections .= qq| onchange="group_or_section('csec')" |;
                   2091:         }
                   2092:         $sections .= '>';
1.548     raeburn  2093:     foreach my $section ('',sort(keys(%sectionhash))) {
1.473     amueller 2094:         $sections.='<option value="'.$section.'" '.
                   2095:         ($section eq $csec?'selected="selected"':'').'>'.$section.
1.275     raeburn  2096:                                                               '</option>';
1.209     www      2097:         }
                   2098:         $sections.='</select>';
1.269     raeburn  2099:     }
1.412     bisitz   2100: 
1.552     raeburn  2101:     if (%sectionhash && %grouphash && $parmlev ne 'full' && $currsec eq '') {
1.412     bisitz   2102:         $sections .= '&nbsp;'.&mt('or').'&nbsp;';
1.269     raeburn  2103:         $sections .= qq|
                   2104: <script type="text/javascript">
1.454     bisitz   2105: // <![CDATA[
1.269     raeburn  2106: function group_or_section(caller) {
                   2107:    if (caller == "cgroup") {
                   2108:        if (document.parmform.cgroup.selectedIndex != 0) {
                   2109:            document.parmform.csec.selectedIndex = 0;
                   2110:        }
                   2111:    } else {
                   2112:        if (document.parmform.csec.selectedIndex != 0) {
                   2113:            document.parmform.cgroup.selectedIndex = 0;
                   2114:        }
                   2115:    }
                   2116: }
1.454     bisitz   2117: // ]]>
1.269     raeburn  2118: </script>
                   2119: |;
1.554     raeburn  2120:     } else {
1.269     raeburn  2121:         $sections .= qq|
                   2122: <script type="text/javascript">
1.454     bisitz   2123: // <![CDATA[
1.269     raeburn  2124: function group_or_section(caller) {
                   2125:     return;
                   2126: }
1.454     bisitz   2127: // ]]>
1.269     raeburn  2128: </script>
                   2129: |;
1.446     bisitz   2130:     }
1.299     albertel 2131: 
                   2132:     if (%grouphash) {
1.412     bisitz   2133:         $groups=&mt('Group:').' <select name="cgroup"';
1.552     raeburn  2134:         if (%sectionhash && $env{'form.action'} eq 'settable' && $currsec eq '') {
1.269     raeburn  2135:             $groups .= qq| onchange="group_or_section('cgroup')" |;
                   2136:         }
                   2137:         $groups .= '>';
1.548     raeburn  2138:         foreach my $grp ('',sort(keys(%grouphash))) {
1.275     raeburn  2139:             $groups.='<option value="'.$grp.'" ';
                   2140:             if ($grp eq $cgroup) {
                   2141:                 unless ((defined($uname)) && ($grp eq '')) {
                   2142:                     $groups .=  'selected="selected" ';
                   2143:                 }
                   2144:             } elsif (!defined($cgroup)) {
                   2145:                 if (@{$usersgroups} == 1) {
                   2146:                     if ($grp eq $$usersgroups[0]) {
                   2147:                         $groups .=  'selected="selected" ';
                   2148:                     }
                   2149:                 }
                   2150:             }
                   2151:             $groups .= '>'.$grp.'</option>';
1.269     raeburn  2152:         }
                   2153:         $groups.='</select>';
                   2154:     }
1.412     bisitz   2155: 
1.445     neumanie 2156:     if (%sectionhash || %grouphash) {
1.446     bisitz   2157:         $r->print(&Apache::lonhtmlcommon::row_title(&mt('Group/Section')));
                   2158:         $r->print($sections.$groups);
1.448     bisitz   2159:         $r->print(&Apache::lonhtmlcommon::row_closure());
1.554     raeburn  2160:     } else {
                   2161:         $r->print($sections); 
1.445     neumanie 2162:     }
1.446     bisitz   2163: 
                   2164:     $r->print(&Apache::lonhtmlcommon::row_title(&mt('User')));
1.443     neumanie 2165:     $r->print(&mt('For User [_1] or Student/Employee ID [_2] at Domain [_3]'
1.412     bisitz   2166:                  ,'<input type="text" value="'.$uname.'" size="12" name="uname" />'
                   2167:                  ,'<input type="text" value="'.$id.'" size="12" name="id" /> '
1.446     bisitz   2168:                  ,$chooseopt));
1.209     www      2169: }
                   2170: 
1.468     amueller 2171: #
                   2172: # This function shows on table Mode the available Parameters for the selected Resources
                   2173: #
1.209     www      2174: sub displaymenu {
1.536     raeburn  2175:     my ($r,$allparms,$pscat,$psprt,$keyorder,$divid)=@_;
1.510     www      2176: 
1.445     neumanie 2177:     $r->print(&Apache::lonhtmlcommon::start_pick_box());
1.510     www      2178:     $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parameters to View')));
                   2179: 
1.448     bisitz   2180:     &parmmenu($r,$allparms,$pscat,$keyorder);
1.536     raeburn  2181:     $r->print(&Apache::loncommon::start_scrollbox('480px','440px','200px',$divid));
1.510     www      2182:     &parmboxes($r,$allparms,$pscat,$keyorder);
                   2183:     $r->print(&Apache::loncommon::end_scrollbox());
                   2184: 
                   2185:     $r->print(&Apache::lonhtmlcommon::row_closure(1));
1.453     schualex 2186:     $r->print(&Apache::lonhtmlcommon::end_pick_box());
1.510     www      2187:  
1.209     www      2188: }
                   2189: 
1.445     neumanie 2190: sub mapmenu {
1.499     raeburn  2191:     my ($r,$allmaps,$pschp,$maptitles,$symbp)=@_;
1.468     amueller 2192:     my %allmaps_inverted = reverse %$allmaps;
1.461     neumanie 2193:     my $navmap = Apache::lonnavmaps::navmap->new();
                   2194:     my $tree=[];
                   2195:     my $treeinfo={};
                   2196:     if (defined($navmap)) {
1.499     raeburn  2197:         my $it=$navmap->getIterator(undef,undef,undef,1,1,undef);
1.461     neumanie 2198:         my $curRes;
                   2199:         my $depth = 0;
1.468     amueller 2200:         my %parent = ();
                   2201:         my $startcount = 5;
                   2202:         my $lastcontainer = $startcount;
                   2203: # preparing what is to show ...
1.461     neumanie 2204:         while ($curRes = $it->next()) {
                   2205:             if ($curRes == $it->BEGIN_MAP()) {
                   2206:                 $depth++;
1.468     amueller 2207:                 $parent{$depth}= $lastcontainer;
1.461     neumanie 2208:             }
                   2209:             if ($curRes == $it->END_MAP()) {
                   2210:                 $depth--;
1.468     amueller 2211:                 $lastcontainer = $parent{$depth};
1.461     neumanie 2212:             }
                   2213:             if (ref($curRes)) {
1.468     amueller 2214:                 my $symb = $curRes->symb();
                   2215:                 my $ressymb = $symb;
1.461     neumanie 2216:                 if (($curRes->is_sequence()) || ($curRes->is_page())) {
                   2217:                     my $type = 'sequence';
                   2218:                     if ($curRes->is_page()) {
                   2219:                         $type = 'page';
                   2220:                     }
                   2221:                     my $id= $curRes->id();
1.468     amueller 2222:                     my $srcf = $curRes->src();
                   2223:                     my $resource_name = &Apache::lonnet::gettitle($srcf);
                   2224:                     if(!exists($treeinfo->{$id})) {
                   2225:                         push(@$tree,$id);
1.473     amueller 2226:                         my $enclosing_map_folder = &Apache::lonnet::declutter($curRes->enclosing_map_src());        
1.468     amueller 2227:                         $treeinfo->{$id} = {
1.461     neumanie 2228:                                     depth => $depth,
                   2229:                                     type  => $type,
1.468     amueller 2230:                                     name  => $resource_name,
                   2231:                                     enclosing_map_folder => $enclosing_map_folder,
1.461     neumanie 2232:                                     };
1.462     neumanie 2233:                     }
1.461     neumanie 2234:                 }
                   2235:             }
                   2236:         }
1.462     neumanie 2237:     }
1.473     amueller 2238: # Show it ...    
1.484     amueller 2239:     $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Enclosing Map or Folder'),'','',' id="mapmenu"'));
1.461     neumanie 2240:     if ((ref($tree) eq 'ARRAY') && (ref($treeinfo) eq 'HASH')) {
                   2241:         my $icon = '<img src="/adm/lonIcons/navmap.folder.open.gif" alt="" />';
1.497     bisitz   2242:         my $whitespace =
                   2243:             '<img src="'
                   2244:            .&Apache::loncommon::lonhttpdurl('/adm/lonIcons/whitespace_21.gif')
                   2245:            .'" alt="" />';
                   2246: 
1.498     bisitz   2247:         # Info about selectable folders/maps
                   2248:         $r->print(
                   2249:             '<div class="LC_info">'
1.508     www      2250:            .&mt('You can only select maps and folders which have modifiable settings.')
                   2251:            .' '.&Apache::loncommon::help_open_topic('Parameter_Set_Folder') 
1.498     bisitz   2252:            .'</div>'
                   2253:         );
                   2254: 
1.536     raeburn  2255:         $r->print(&Apache::loncommon::start_scrollbox('700px','680px','400px','mapmenuscroll'));
1.523     raeburn  2256:         $r->print(&Apache::loncommon::start_data_table(undef,'mapmenuinner'));
1.497     bisitz   2257: 
1.498     bisitz   2258:         # Display row: "All Maps or Folders"
                   2259:         $r->print(
1.523     raeburn  2260:             &Apache::loncommon::start_data_table_row(undef,'picklevel')
1.498     bisitz   2261:            .'<td>'
                   2262:            .'<label>'
                   2263:            .'<input type="radio" name="pschp"'
1.497     bisitz   2264:         );
                   2265:         $r->print(' checked="checked"') if ($pschp eq 'all' || !$pschp);
1.498     bisitz   2266:         $r->print(
                   2267:             ' value="all" />&nbsp;'.$icon.'&nbsp;'
                   2268:            .&mt('All Maps or Folders')
                   2269:            .'</label>'
                   2270:            .'<hr /></td>'
                   2271:            .&Apache::loncommon::end_data_table_row()
1.463     bisitz   2272:         );
1.497     bisitz   2273: 
1.532     raeburn  2274:         # Display row: "Main Content"
1.468     amueller 2275:         if (exists($$allmaps{1})) {
1.498     bisitz   2276:             $r->print(
                   2277:                 &Apache::loncommon::start_data_table_row()
                   2278:                .'<td>'
                   2279:                .'<label>'
                   2280:                .'<input type="radio" name="pschp" value="1"'
1.468     amueller 2281:             );
1.497     bisitz   2282:             $r->print(' checked="checked"') if ($pschp eq '1');
1.498     bisitz   2283:             $r->print(
                   2284:                 '/>&nbsp;'.$icon.'&nbsp;'
                   2285:                .$$maptitles{1}
                   2286:                .($$allmaps{1} !~/^uploaded/?' ['.$$allmaps{1}.']':'')
                   2287:                .'</label>'
                   2288:                .'</td>'
                   2289:                .&Apache::loncommon::end_data_table_row()
1.468     amueller 2290:             );
                   2291:         }
1.497     bisitz   2292: 
                   2293:         # Display rows for all course maps and folders
1.468     amueller 2294:         foreach my $id (@{$tree}) {
                   2295:             my ($mapid,$resid)=split(/\./,$id);
1.464     bisitz   2296:             # Indentation
1.468     amueller 2297:             my $depth = $treeinfo->{$id}->{'depth'};
1.464     bisitz   2298:             my $indent;
                   2299:             for (my $i = 0; $i < $depth; $i++) {
                   2300:                 $indent.= $whitespace;
                   2301:             }
1.461     neumanie 2302:             $icon =  '<img src="/adm/lonIcons/navmap.folder.open.gif" alt="" />';
1.468     amueller 2303:             if ($treeinfo->{$id}->{'type'} eq 'page') {
1.461     neumanie 2304:                 $icon = '<img src="/adm/lonIcons/navmap.page.open.gif" alt="" />';
                   2305:             }
1.468     amueller 2306:             my $symb_name = $$symbp{$id};
                   2307:             my ($front, $tail) = split (/___${resid}___/, $symb_name);
                   2308:             $symb_name = $tail;
1.498     bisitz   2309:             $r->print(
                   2310:                 &Apache::loncommon::start_data_table_row()
                   2311:                .'<td>'
                   2312:                .'<label>'
1.463     bisitz   2313:             );
1.498     bisitz   2314:             # Only offer radio button for folders/maps which can be parameterized
                   2315:             if ($allmaps_inverted{$symb_name}) {
                   2316:                 $r->print(
                   2317:                     '<input type ="radio" name="pschp"'
                   2318:                    .' value="'.$allmaps_inverted{$symb_name}.'"'
                   2319:                 );
                   2320:                 $r->print(' checked="checked"') if ($allmaps_inverted{$symb_name} eq $pschp);
                   2321:                 $r->print('/>');
                   2322:             } else {
                   2323:                 $r->print($whitespace);
1.461     neumanie 2324:             }
1.498     bisitz   2325:             $r->print(
                   2326:                 $indent.$icon.'&nbsp;'
                   2327:                .$treeinfo->{$id}->{name}
                   2328:                .($$allmaps{$mapid}!~/^uploaded/?' ['.$$allmaps{$mapid}.']':'')
                   2329:                .'</label>'
                   2330:                .'</td>'
                   2331:                .&Apache::loncommon::end_data_table_row()
1.463     bisitz   2332:             );
1.461     neumanie 2333:         }
1.497     bisitz   2334: 
1.523     raeburn  2335:         $r->print(&Apache::loncommon::end_data_table().
                   2336:                   '<br style="line-height:2px;" />'.
                   2337:                   &Apache::loncommon::end_scrollbox());
1.209     www      2338:     }
                   2339: }
                   2340: 
1.482     amueller 2341: # Build up the select Box to choose if your parameter specification should work for the resource, map/folder or the course level
                   2342: # 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      2343: sub levelmenu {
1.446     bisitz   2344:     my ($r,$alllevs,$parmlev)=@_;
                   2345: 
1.548     raeburn  2346:     $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parameter Level').
                   2347:                                                 &Apache::loncommon::help_open_topic('Course_Parameter_Levels')));
1.474     amueller 2348:     $r->print('<select id="parmlev" name="parmlev" onchange="showHide_courseContent()">');
1.548     raeburn  2349:     foreach my $lev (reverse(sort(keys(%{$alllevs})))) {
                   2350:         $r->print('<option value="'.$$alllevs{$lev}.'"');
                   2351:         if ($parmlev eq $$alllevs{$lev}) {
                   2352:             $r->print(' selected="selected"');
                   2353:         }
                   2354:         $r->print('>'.&mt($lev).'</option>');
1.208     www      2355:     }
1.446     bisitz   2356:     $r->print("</select>");
1.208     www      2357: }
                   2358: 
1.211     www      2359: 
                   2360: sub sectionmenu {
1.553     raeburn  2361:     my ($selectedsections)=@_;
1.300     albertel 2362:     my %sectionhash = &Apache::loncommon::get_sections();
1.553     raeburn  2363:     return '' if (!%sectionhash);
1.300     albertel 2364: 
1.552     raeburn  2365:     my (@possibles,$disabled);
                   2366:     if ($env{'request.course.sec'} ne '') {
                   2367:         @possibles = ($env{'request.course.sec'});
                   2368:         $selectedsections = [$env{'request.course.sec'}];
                   2369:         $disabled = ' disabled="disabled"';
                   2370:     } else {
                   2371:         @possibles = ('all',sort(keys(%sectionhash)));
                   2372:     }
1.553     raeburn  2373:     my $output = '<select name="Section" multiple="multiple" size="8"'.$disabled.'>';
1.552     raeburn  2374:     foreach my $s (@possibles) {
1.553     raeburn  2375:         $output .= '    <option value="'.$s.'"';
                   2376:         if ((@{$selectedsections}) && (grep(/^\Q$s\E$/,@{$selectedsections}))) {  
                   2377:             $output .= ' selected="selected"';
1.473     amueller 2378:         }
1.553     raeburn  2379:         $output .= '>'."$s</option>\n";
1.300     albertel 2380:     }
1.553     raeburn  2381:     $output .= "</select>\n";
                   2382:     return $output;
1.269     raeburn  2383: }
                   2384: 
                   2385: sub groupmenu {
1.553     raeburn  2386:     my ($selectedgroups)=@_;
                   2387:     my %grouphash;
                   2388:     if (&Apache::lonnet::allowed('mdg',$env{'request.course.id'})) {
                   2389:         %grouphash = &Apache::longroup::coursegroups();
                   2390:     } elsif ($env{'request.course.groups'} ne '') {
                   2391:          map { $grouphash{$_} = 1; } split(/,/,$env{'request.course.groups'});
                   2392:     }
                   2393:     return '' if (!%grouphash);
1.299     albertel 2394: 
1.553     raeburn  2395:     my $output = '<select name="Group" multiple="multiple" size="8">';
1.299     albertel 2396:     foreach my $group (sort(keys(%grouphash))) {
1.553     raeburn  2397:         $output .= '    <option value="'.$group.'"';
                   2398:         if ((@{$selectedgroups}) && (grep(/^\Q$group\E$/,\@{$selectedgroups}))) {
                   2399:             $output .=  ' selected="selected"';
1.473     amueller 2400:         }
1.553     raeburn  2401:         $output .= '>'."$group</option>\n";
1.211     www      2402:     }
1.553     raeburn  2403:     $output .= "</select>\n";
                   2404:     return $output;
1.211     www      2405: }
                   2406: 
1.210     www      2407: sub keysplit {
                   2408:     my $keyp=shift;
                   2409:     return (split(/\,/,$keyp));
                   2410: }
                   2411: 
                   2412: sub keysinorder {
                   2413:     my ($name,$keyorder)=@_;
                   2414:     return sort {
1.560     damieng  2415:         $$keyorder{$a} <=> $$keyorder{$b};
1.548     raeburn  2416:     } (keys(%{$name}));
1.210     www      2417: }
                   2418: 
1.236     albertel 2419: sub keysinorder_bytype {
                   2420:     my ($name,$keyorder)=@_;
                   2421:     return sort {
1.560     damieng  2422:         my $ta=(split('_',$a))[-1];
                   2423:         my $tb=(split('_',$b))[-1];
                   2424:         if ($$keyorder{'parameter_0_'.$ta} == $$keyorder{'parameter_0_'.$tb}) {
                   2425:             return ($a cmp $b);
                   2426:         }
                   2427:         $$keyorder{'parameter_0_'.$ta} <=> $$keyorder{'parameter_0_'.$tb};
1.548     raeburn  2428:     } (keys(%{$name}));
1.236     albertel 2429: }
                   2430: 
1.211     www      2431: sub keysindisplayorder {
                   2432:     my ($name,$keyorder)=@_;
                   2433:     return sort {
1.560     damieng  2434:         $$keyorder{'parameter_0_'.$a} <=> $$keyorder{'parameter_0_'.$b};
1.548     raeburn  2435:     } (keys(%{$name}));
1.211     www      2436: }
                   2437: 
1.214     www      2438: sub sortmenu {
                   2439:     my ($r,$sortorder)=@_;
1.236     albertel 2440:     $r->print('<br /><label><input type="radio" name="sortorder" value="realmstudent"');
1.214     www      2441:     if ($sortorder eq 'realmstudent') {
1.422     bisitz   2442:        $r->print(' checked="checked"');
1.214     www      2443:     }
                   2444:     $r->print(' />'.&mt('Sort by realm first, then student (group/section)'));
1.236     albertel 2445:     $r->print('</label><br /><label><input type="radio" name="sortorder" value="studentrealm"');
1.214     www      2446:     if ($sortorder eq 'studentrealm') {
1.422     bisitz   2447:        $r->print(' checked="checked"');
1.214     www      2448:     }
1.236     albertel 2449:     $r->print(' />'.&mt('Sort by student (group/section) first, then realm').
1.473     amueller 2450:           '</label>');
1.214     www      2451: }
                   2452: 
1.211     www      2453: sub standardkeyorder {
                   2454:     return ('parameter_0_opendate' => 1,
1.473     amueller 2455:         'parameter_0_duedate' => 2,
                   2456:         'parameter_0_answerdate' => 3,
                   2457:         'parameter_0_interval' => 4,
                   2458:         'parameter_0_weight' => 5,
                   2459:         'parameter_0_maxtries' => 6,
                   2460:         'parameter_0_hinttries' => 7,
                   2461:         'parameter_0_contentopen' => 8,
                   2462:         'parameter_0_contentclose' => 9,
                   2463:         'parameter_0_type' => 10,
                   2464:         'parameter_0_problemstatus' => 11,
                   2465:         'parameter_0_hiddenresource' => 12,
                   2466:         'parameter_0_hiddenparts' => 13,
                   2467:         'parameter_0_display' => 14,
                   2468:         'parameter_0_ordered' => 15,
                   2469:         'parameter_0_tol' => 16,
                   2470:         'parameter_0_sig' => 17,
                   2471:         'parameter_0_turnoffunit' => 18,
1.521     raeburn  2472:         'parameter_0_discussend' => 19,
                   2473:         'parameter_0_discusshide' => 20,
                   2474:         'parameter_0_discussvote' => 21,
1.560     damieng  2475:         'parameter_0_printstartdate'  =>  22,
                   2476:         'parameter_0_printenddate' =>  23);
1.211     www      2477: }
                   2478: 
1.59      matthew  2479: 
1.560     damieng  2480: # Table mode UI.
1.30      www      2481: sub assessparms {
1.1       www      2482: 
1.43      albertel 2483:     my $r=shift;
1.201     www      2484: 
1.512     foxr     2485: 
                   2486: # -------------------------------------------------------- Variable declaration
1.201     www      2487:     my @ids=();
                   2488:     my %symbp=();
                   2489:     my %mapp=();
                   2490:     my %typep=();
                   2491:     my %keyp=();
                   2492:     my %uris=();
                   2493:     my %maptitles=();
1.129     www      2494:     my %allmaps=();
                   2495:     my %alllevs=();
1.57      albertel 2496: 
1.187     www      2497:     my $uname;
                   2498:     my $udom;
                   2499:     my $uhome;
                   2500:     my $csec;
1.269     raeburn  2501:     my $cgroup;
1.275     raeburn  2502:     my @usersgroups = ();
1.446     bisitz   2503: 
1.190     albertel 2504:     my $coursename=$env{'course.'.$env{'request.course.id'}.'.description'};
1.187     www      2505: 
1.57      albertel 2506:     $alllevs{'Resource Level'}='full';
1.215     www      2507:     $alllevs{'Map/Folder Level'}='map';
1.57      albertel 2508:     $alllevs{'Course Level'}='general';
                   2509: 
                   2510:     my %allparms;
                   2511:     my %allparts;
1.512     foxr     2512: # ------------------------------------------------------------------------------
                   2513: 
1.210     www      2514: #
                   2515: # Order in which these parameters will be displayed
                   2516: #
1.211     www      2517:     my %keyorder=&standardkeyorder();
                   2518: 
1.512     foxr     2519: #    @ids=();
                   2520: #    %symbp=();       # These seem defined above already.
                   2521: #    %typep=();
1.43      albertel 2522: 
                   2523:     my $message='';
                   2524: 
1.190     albertel 2525:     $csec=$env{'form.csec'};
1.552     raeburn  2526:     if ($env{'request.course.sec'} ne '') {
                   2527:         $csec = $env{'request.course.sec'};    
                   2528:     }
                   2529: 
1.553     raeburn  2530: # Check group privs.
1.269     raeburn  2531:     $cgroup=$env{'form.cgroup'};
1.553     raeburn  2532:     my $noeditgrp; 
                   2533:     if ($cgroup ne '') {
                   2534:         unless (&Apache::lonnet::allowed('mdg',$env{'request.course.id'})) {
                   2535:             if (($env{'request.course.groups'} eq '') || 
                   2536:                 (!grep(/^\Q$cgroup\E$/,split(/,/,$env{'request.course.groups'})))) {
                   2537:                 $noeditgrp = 1;
                   2538:             }
                   2539:         }
                   2540:     }
1.188     www      2541: 
1.190     albertel 2542:     if      ($udom=$env{'form.udom'}) {
                   2543:     } elsif ($udom=$env{'request.role.domain'}) {
                   2544:     } elsif ($udom=$env{'user.domain'}) {
1.172     albertel 2545:     } else {
1.473     amueller 2546:         $udom=$r->dir_config('lonDefDomain');
1.172     albertel 2547:     }
1.468     amueller 2548:     
1.43      albertel 2549: 
1.134     albertel 2550:     my @pscat=&Apache::loncommon::get_env_multiple('form.pscat');
1.190     albertel 2551:     my $pschp=$env{'form.pschp'};
1.506     www      2552: 
                   2553: 
1.134     albertel 2554:     my @psprt=&Apache::loncommon::get_env_multiple('form.psprt');
1.516     www      2555:     if (!@psprt) { $psprt[0]='all'; }
1.506     www      2556:     if (($env{'form.part'}) && ($psprt[0] ne 'all')) { $psprt[0]=$env{'form.part'}; }
1.57      albertel 2557: 
1.43      albertel 2558:     my $pssymb='';
1.57      albertel 2559:     my $parmlev='';
1.446     bisitz   2560: 
1.190     albertel 2561:     unless ($env{'form.parmlev'}) {
1.57      albertel 2562:         $parmlev = 'map';
                   2563:     } else {
1.190     albertel 2564:         $parmlev = $env{'form.parmlev'};
1.57      albertel 2565:     }
1.26      www      2566: 
1.29      www      2567: # ----------------------------------------------- Was this started from grades?
                   2568: 
1.560     damieng  2569:     if (($env{'form.command'} eq 'set') && ($env{'form.url'}) &&
                   2570:             (!$env{'form.dis'})) {
1.473     amueller 2571:         my $url=$env{'form.url'};
                   2572:         $url=~s-^http://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--;
                   2573:         $pssymb=&Apache::lonnet::symbread($url);
                   2574:         if (!@pscat) { @pscat=('all'); }
                   2575:         $pschp='';
1.57      albertel 2576:         $parmlev = 'full';
1.190     albertel 2577:     } elsif ($env{'form.symb'}) {
1.473     amueller 2578:         $pssymb=$env{'form.symb'};
                   2579:         if (!@pscat) { @pscat=('all'); }
                   2580:         $pschp='';
1.57      albertel 2581:         $parmlev = 'full';
1.43      albertel 2582:     } else {
1.473     amueller 2583:         $env{'form.url'}='';
1.43      albertel 2584:     }
                   2585: 
1.190     albertel 2586:     my $id=$env{'form.id'};
1.43      albertel 2587:     if (($id) && ($udom)) {
1.555     raeburn  2588:         $uname=(&Apache::lonnet::idget($udom,[$id],'ids'))[1];
1.473     amueller 2589:         if ($uname) {
                   2590:             $id='';
                   2591:         } else {
                   2592:             $message=
1.540     bisitz   2593:                 '<p class="LC_warning">'.
                   2594:                 &mt('Unknown ID [_1] at domain [_2]',
                   2595:                     "'".$id."'","'".$udom."'").
                   2596:                 '</p>';
1.473     amueller 2597:         }
1.43      albertel 2598:     } else {
1.473     amueller 2599:         $uname=$env{'form.uname'};
1.43      albertel 2600:     }
                   2601:     unless ($udom) { $uname=''; }
                   2602:     $uhome='';
                   2603:     if ($uname) {
1.473     amueller 2604:         $uhome=&Apache::lonnet::homeserver($uname,$udom);
1.43      albertel 2605:         if ($uhome eq 'no_host') {
1.473     amueller 2606:             $message=
1.540     bisitz   2607:                 '<p class="LC_warning">'.
                   2608:                 &mt('Unknown user [_1] at domain [_2]',
                   2609:                     "'".$uname."'","'".$udom."'").
                   2610:                 '</p>';
1.473     amueller 2611:             $uname='';
1.12      www      2612:         } else {
1.473     amueller 2613:             $csec=&Apache::lonnet::getsection($udom,$uname,
                   2614:                           $env{'request.course.id'});
                   2615:             if ($csec eq '-1') {
1.540     bisitz   2616:                 $message=
                   2617:                     '<p class="LC_warning">'.
                   2618:                     &mt('User [_1] at domain [_2] not in this course',
                   2619:                         "'".$uname."'","'".$udom."'").
                   2620:                     '</p>';
1.473     amueller 2621:                 $uname='';
                   2622:                 $csec=$env{'form.csec'};
1.269     raeburn  2623:                 $cgroup=$env{'form.cgroup'};
1.473     amueller 2624:             } else {
                   2625:                 my %name=&Apache::lonnet::userenvironment($udom,$uname,
                   2626:                   ('firstname','middlename','lastname','generation','id'));
                   2627:                 $message="\n<p>\n".&mt("Full Name").": ".
                   2628:                 $name{'firstname'}.' '.$name{'middlename'}.' '
                   2629:                 .$name{'lastname'}.' '.$name{'generation'}.
1.501     bisitz   2630:                 "<br />\n".&mt('Student/Employee ID').": ".$name{'id'}.'<p>';
1.473     amueller 2631:             }
1.297     raeburn  2632:             @usersgroups = &Apache::lonnet::get_users_groups(
1.275     raeburn  2633:                                        $udom,$uname,$env{'request.course.id'});
1.297     raeburn  2634:             if (@usersgroups > 0) {
1.306     albertel 2635:                 unless (grep(/^\Q$cgroup\E$/,@usersgroups)) {
1.275     raeburn  2636:                     $cgroup = $usersgroups[0];
1.297     raeburn  2637:                 }
1.269     raeburn  2638:             }
1.12      www      2639:         }
1.43      albertel 2640:     }
1.2       www      2641: 
1.43      albertel 2642:     unless ($csec) { $csec=''; }
1.269     raeburn  2643:     unless ($cgroup) { $cgroup=''; }
1.12      www      2644: 
1.14      www      2645: # --------------------------------------------------------- Get all assessments
1.446     bisitz   2646:     &extractResourceInformation(\@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allmaps,
1.473     amueller 2647:                 \%mapp, \%symbp,\%maptitles,\%uris,
                   2648:                 \%keyorder);
1.63      bowersj2 2649: 
1.57      albertel 2650:     $mapp{'0.0'} = '';
                   2651:     $symbp{'0.0'} = '';
1.99      albertel 2652: 
1.14      www      2653: # ---------------------------------------------------------- Anything to store?
1.190     albertel 2654:     if ($env{'form.pres_marker'}) {
1.205     www      2655:         my @markers=split(/\&\&\&/,$env{'form.pres_marker'});
                   2656:         my @values=split(/\&\&\&/,$env{'form.pres_value'});
                   2657:         my @types=split(/\&\&\&/,$env{'form.pres_type'});
1.500     raeburn  2658:         my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   2659:         my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
1.504     raeburn  2660:         my $chome = $env{'course.'.$env{'request.course.id'}.'.home'};
                   2661:         my ($got_chostname,$chostname,$cmajor,$cminor);
                   2662:         my $totalstored = 0;
1.546     raeburn  2663:         my $now = time;
1.473     amueller 2664:         for (my $i=0;$i<=$#markers;$i++) {
1.557     raeburn  2665:             my ($needsrelease,$needsnewer,$name,$namematch);
1.556     raeburn  2666:             if (($env{'request.course.sec'} ne '') && ($markers[$i] =~ /\&(9|10|11|12)$/)) {
1.552     raeburn  2667:                 next if ($csec ne $env{'request.course.sec'});
                   2668:             }
1.556     raeburn  2669:             if ($markers[$i] =~ /\&(8|7|6|5)$/) {
1.553     raeburn  2670:                 next if ($noeditgrp);
1.557     raeburn  2671:             }
                   2672:             if ($markers[$i] =~ /\&(17|11|7|3)$/) {
                   2673:                 $namematch = 'maplevelrecurse';
                   2674:             }
1.556     raeburn  2675:             if ($markers[$i] =~ /^[\d.]+\&0_availablestudent\&(1|2|3|4)$/) {
1.437     raeburn  2676:                 my (@ok_slots,@fail_slots,@del_slots);
                   2677:                 my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom);
                   2678:                 my ($level,@all) =
                   2679:                     &parmval_by_symb('0.availablestudent',$pssymb,'',$uname,$udom,
                   2680:                                      $csec,$cgroup,$courseopt);
                   2681:                 foreach my $slot_name (split(/:/,$values[$i])) {
                   2682:                     next if ($slot_name eq '');
                   2683:                     if (&update_slots($slot_name,$cdom,$cnum,$pssymb,$uname,$udom) eq 'ok') {
                   2684:                         push(@ok_slots,$slot_name);
                   2685: 
                   2686:                     } else {
                   2687:                         push(@fail_slots,$slot_name);
                   2688:                     }
                   2689:                 }
                   2690:                 if (@ok_slots) {
                   2691:                     $values[$i] = join(':',@ok_slots);
                   2692:                 } else {
                   2693:                     $values[$i] = '';
                   2694:                 }
                   2695:                 if ($all[$level] ne '') {
                   2696:                     my @existing = split(/:/,$all[$level]);
                   2697:                     foreach my $slot_name (@existing) {
                   2698:                         if (!grep(/^\Q$slot_name\E$/,split(/:/,$values[$i]))) {
                   2699:                             if (&delete_slots($slot_name,$cdom,$cnum,$uname,$udom,$pssymb) eq 'ok') {
                   2700:                                 push(@del_slots,$slot_name);
                   2701:                             }
                   2702:                         }
                   2703:                     }
                   2704:                 }
1.554     raeburn  2705:             } elsif ($markers[$i] =~ /_(type|lenient|retrypartial|discussvote|examcode|printstartdate|printenddate|acc|interval)\&\d+$/) {
1.514     raeburn  2706:                 $name = $1;
1.533     raeburn  2707:                 my $val = $values[$i];
1.549     raeburn  2708:                 my $valmatch = '';
1.533     raeburn  2709:                 if ($name eq 'examcode') {
1.544     raeburn  2710:                     if (&Apache::lonnet::validCODE($values[$i])) {
                   2711:                         $val = 'valid';
                   2712:                     }
1.546     raeburn  2713:                 } elsif ($name eq 'printstartdate') {
                   2714:                     if ($val =~ /^\d+$/) {
                   2715:                         if ($val > $now) {
                   2716:                             $val = 'future';
                   2717:                         }
                   2718:                     } 
                   2719:                 } elsif ($name eq 'printenddate') {
                   2720:                     if ($val =~ /^\d+$/) {
                   2721:                         if ($val < $now) {
                   2722:                             $val = 'past';
                   2723:                         }
                   2724:                     }
1.549     raeburn  2725:                 } elsif (($name eq 'lenient') || ($name eq 'acc')) {
                   2726:                     my $stringtype = &get_stringtype($name);
                   2727:                     my $stringmatch = &standard_string_matches($stringtype);
                   2728:                     if (ref($stringmatch) eq 'ARRAY') {
                   2729:                         foreach my $item (@{$stringmatch}) {
                   2730:                             if (ref($item) eq 'ARRAY') {
                   2731:                                 my ($regexpname,$pattern) = @{$item};
                   2732:                                 if ($pattern ne '') {
                   2733:                                     if ($val =~ /$pattern/) {
                   2734:                                         $valmatch = $regexpname;
                   2735:                                         $val = '';
                   2736:                                         last;
                   2737:                                     }
                   2738:                                 }
                   2739:                             }
                   2740:                         }
                   2741:                     }
1.554     raeburn  2742:                 } elsif ($name eq 'interval') {
                   2743:                     my $intervaltype = &get_intervaltype($name);
                   2744:                     my $intervalmatch = &standard_interval_matches($intervaltype);
                   2745:                     if (ref($intervalmatch) eq 'ARRAY') {
                   2746:                         foreach my $item (@{$intervalmatch}) {
                   2747:                             if (ref($item) eq 'ARRAY') {
                   2748:                                 my ($regexpname,$pattern) = @{$item};
                   2749:                                 if ($pattern ne '') {
                   2750:                                     if ($val =~ /$pattern/) {
                   2751:                                         $valmatch = $regexpname;
                   2752:                                         $val = '';
                   2753:                                         last;
                   2754:                                     }
                   2755:                                 }
                   2756:                             }
                   2757:                         }
                   2758:                     }
1.533     raeburn  2759:                 }
1.504     raeburn  2760:                 $needsrelease =
1.557     raeburn  2761:                     $Apache::lonnet::needsrelease{"parameter:$name:$val:$valmatch:"};
1.504     raeburn  2762:                 if ($needsrelease) {
1.505     raeburn  2763:                     unless ($got_chostname) {
1.514     raeburn  2764:                         ($chostname,$cmajor,$cminor) = &parameter_release_vars();
1.504     raeburn  2765:                         $got_chostname = 1;
1.546     raeburn  2766:                     } 
1.557     raeburn  2767:                     $needsnewer = &parameter_releasecheck($name,$val,$valmatch,undef,
1.514     raeburn  2768:                                                           $needsrelease,
                   2769:                                                           $cmajor,$cminor);
1.500     raeburn  2770:                 }
1.437     raeburn  2771:             }
1.504     raeburn  2772:             if ($needsnewer) {
1.557     raeburn  2773:                 undef($namematch);
                   2774:             } else {
                   2775:                 my $currneeded;
                   2776:                 if ($needsrelease) {
                   2777:                     $currneeded = $needsrelease;
                   2778:                 }
                   2779:                 if ($namematch) {
                   2780:                     $needsrelease =
                   2781:                         $Apache::lonnet::needsrelease{"parameter::::$namematch"};
                   2782:                     if (($needsrelease) && (($currneeded eq '') || ($needsrelease < $currneeded))) {
                   2783:                         unless ($got_chostname) {
                   2784:                             ($chostname,$cmajor,$cminor) = &parameter_release_vars();
                   2785:                             $got_chostname = 1;
                   2786:                         }
                   2787:                         $needsnewer = &parameter_releasecheck(undef,undef,undef,$namematch,
                   2788:                                                               $needsrelease,
                   2789:                                                               $cmajor,$cminor);
                   2790:                     } else {
                   2791:                         undef($namematch);
                   2792:                     }
                   2793:                 }
                   2794:             }
                   2795:             if ($needsnewer) {
                   2796:                 $message .= &oldversion_warning($name,$namematch,$values[$i],$chostname,$cmajor,
1.504     raeburn  2797:                                                 $cminor,$needsrelease);
                   2798:             } else {
                   2799:                 $message.=&storeparm(split(/\&/,$markers[$i]),
                   2800:                                      $values[$i],
                   2801:                                      $types[$i],
                   2802:                                      $uname,$udom,$csec,$cgroup);
                   2803:                 $totalstored ++;
                   2804:             }
1.473     amueller 2805:         }
1.68      www      2806: # ---------------------------------------------------------------- Done storing
1.504     raeburn  2807:         if ($totalstored) {
                   2808:             $message.='<p class="LC_warning">'
                   2809:                      .&mt('Changes can take up to 10 minutes before being active for all students.')
                   2810:                      .&Apache::loncommon::help_open_topic('Caching')
                   2811:                      .'</p>';
                   2812:         }
1.68      www      2813:     }
1.57      albertel 2814: #----------------------------------------------- if all selected, fill in array
1.548     raeburn  2815:     if ($pscat[0] eq "all") {@pscat = (keys(%allparms));}
1.501     bisitz   2816:     if (!@pscat) { @pscat=('duedate','opendate','answerdate','weight','maxtries','type','problemstatus') };
1.548     raeburn  2817:     if ($psprt[0] eq "all" || !@psprt) {@psprt = (keys(%allparts));}
1.2       www      2818: # ------------------------------------------------------------------ Start page
1.63      bowersj2 2819: 
1.531     raeburn  2820:     my $crstype = &Apache::loncommon::course_type();
                   2821:     &startpage($r,$pssymb,$crstype);
1.57      albertel 2822: 
1.548     raeburn  2823:     foreach my $item ('tolerance','date_default','date_start','date_end',
1.473     amueller 2824:         'date_interval','int','float','string') {
                   2825:         $r->print('<input type="hidden" value="'.
1.548     raeburn  2826:           &HTML::Entities::encode($env{'form.recent_'.$item},'"&<>').
                   2827:           '" name="recent_'.$item.'" />');
1.44      albertel 2828:     }
1.446     bisitz   2829: 
1.459     bisitz   2830:     # ----- Start Parameter Selection
                   2831: 
                   2832:     # Hide parm selection?
                   2833:     $r->print(<<ENDPARMSELSCRIPT);
                   2834: <script type="text/javascript">
                   2835: // <![CDATA[
                   2836: function parmsel_show() {
                   2837:   document.getElementById('parmsel').style.display = "";
                   2838:   document.getElementById('parmsellink').style.display = "none";
                   2839: }
                   2840: // ]]>
                   2841: </script>
                   2842: ENDPARMSELSCRIPT
1.474     amueller 2843:     
1.445     neumanie 2844:     if (!$pssymb) {
1.486     www      2845:         my $parmselhiddenstyle=' style="display:none"';
                   2846:         if($env{'form.hideparmsel'} eq 'hidden') {
                   2847:            $r->print('<div id="parmsel"'.$parmselhiddenstyle.'>');
                   2848:         } else  {
                   2849:            $r->print('<div id="parmsel">');
                   2850:         }
                   2851: 
1.491     bisitz   2852:         # Step 1
1.523     raeburn  2853:         $r->print(&Apache::lonhtmlcommon::topic_bar(1,&mt('Resource Specification'),'parmstep1'));
                   2854:         $r->print('
1.474     amueller 2855: <script type="text/javascript">
1.523     raeburn  2856: // <![CDATA['.
                   2857:                  &showhide_js().'
1.474     amueller 2858: // ]]>
                   2859: </script>
1.523     raeburn  2860: ');
                   2861:         $r->print(&Apache::lonhtmlcommon::start_pick_box(undef,'parmlevel'));
1.209     www      2862:         &levelmenu($r,\%alllevs,$parmlev);
1.491     bisitz   2863:         $r->print(&Apache::lonhtmlcommon::row_closure());
1.474     amueller 2864:         &mapmenu($r,\%allmaps,$pschp,\%maptitles, \%symbp);
1.491     bisitz   2865:         $r->print(&Apache::lonhtmlcommon::row_closure());
                   2866:         $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parts to View')));
                   2867:         &partmenu($r,\%allparts,\@psprt);
1.474     amueller 2868:         $r->print(&Apache::lonhtmlcommon::row_closure(1));
                   2869:         $r->print(&Apache::lonhtmlcommon::end_pick_box());
1.491     bisitz   2870: 
                   2871:         # Step 2
1.523     raeburn  2872:         $r->print(&Apache::lonhtmlcommon::topic_bar(2,&mt('Parameter Specification'),'parmstep2'));
1.536     raeburn  2873:         &displaymenu($r,\%allparms,\@pscat,\@psprt,\%keyorder,'parmmenuscroll');
1.491     bisitz   2874: 
                   2875:         # Step 3
1.523     raeburn  2876:         $r->print(&Apache::lonhtmlcommon::topic_bar(3,&mt('User Specification (optional)'),'parmstep3'));
1.486     www      2877:         $r->print(&Apache::lonhtmlcommon::start_pick_box());
1.553     raeburn  2878:         &usermenu($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,\@usersgroups,$pssymb);
1.486     www      2879:         $r->print(&Apache::lonhtmlcommon::row_closure(1));
                   2880:         $r->print(&Apache::lonhtmlcommon::end_pick_box());
1.491     bisitz   2881: 
                   2882:         # Update Display Button
1.486     www      2883:         $r->print('<p>'
                   2884:              .'<input type="submit" name="dis"'
1.511     www      2885:              .' value="'.&mt('Update Display').'" />'
1.486     www      2886:              .'<input type="hidden" name="hideparmsel" value="hidden" />'
                   2887:              .'</p>');
                   2888:         $r->print('</div>');
1.491     bisitz   2889: 
1.486     www      2890:         # Offer link to display parameter selection again
                   2891:         $r->print('<p id="parmsellink"');
                   2892:         if ($env{'form.hideparmsel'} ne 'hidden') {
                   2893:            $r->print($parmselhiddenstyle);
                   2894:         }
                   2895:         $r->print('>'
                   2896:              .'<a href="javascript:parmsel_show()">'
                   2897:              .&mt('Change Parameter Selection')
                   2898:              .'</a>'
                   2899:              .'</p>');
1.44      albertel 2900:     } else {
1.478     amueller 2901:         # parameter screen for a single resource. 
1.486     www      2902:         my ($map,$iid,$resource)=&Apache::lonnet::decode_symb($pssymb);
1.473     amueller 2903:         my $title = &Apache::lonnet::gettitle($pssymb);
1.501     bisitz   2904:         $r->print(&mt('Specific Resource: [_1] ([_2])',
                   2905:                          $title,'<span class="LC_filename">'.$resource.'</span>').
1.472     amueller 2906:                 '<input type="hidden" value="'.$pssymb.'" name="symb" />'.
1.486     www      2907:                   '<br />');
                   2908:         $r->print(&Apache::lonhtmlcommon::topic_bar('',&mt('Additional Display Specification (optional)')));
                   2909:         $r->print(&Apache::lonhtmlcommon::start_pick_box());
1.553     raeburn  2910:         &usermenu($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,\@usersgroups,$pssymb);
1.486     www      2911:         $r->print(&Apache::lonhtmlcommon::row_closure(1));
                   2912:         $r->print(&Apache::lonhtmlcommon::end_pick_box());
                   2913:         $r->print('<p>'
1.459     bisitz   2914:              .'<input type="submit" name="dis"'
1.511     www      2915:              .' value="'.&mt('Update Display').'" />'
1.459     bisitz   2916:              .'<input type="hidden" name="hideparmsel" value="hidden" />'
1.486     www      2917:              .'</p>');
1.459     bisitz   2918:     }
1.478     amueller 2919:     
1.486     www      2920:     # ----- End Parameter Selection
1.57      albertel 2921: 
1.459     bisitz   2922:     # Display Messages
                   2923:     $r->print('<div>'.$message.'</div>');
1.210     www      2924: 
1.57      albertel 2925: 
                   2926:     my @temp_pscat;
                   2927:     map {
                   2928:         my $cat = $_;
                   2929:         push(@temp_pscat, map { $_.'.'.$cat } @psprt);
                   2930:     } @pscat;
                   2931: 
                   2932:     @pscat = @temp_pscat;
                   2933: 
1.548     raeburn  2934: 
1.209     www      2935:     if (($env{'form.prevvisit'}) || ($pschp) || ($pssymb)) {
1.10      www      2936: # ----------------------------------------------------------------- Start Table
1.57      albertel 2937:         my @catmarker=map { tr|.|_|; 'parameter_'.$_; } @pscat;
1.190     albertel 2938:         my $csuname=$env{'user.name'};
                   2939:         my $csudom=$env{'user.domain'};
1.57      albertel 2940: 
1.203     www      2941:         if ($parmlev eq 'full') {
1.506     www      2942: #
                   2943: # This produces the cascading table output of parameters
                   2944: #
1.560     damieng  2945:             my $coursespan=$csec?10:6;
                   2946:             my $userspan=4;
                   2947:             if ($cgroup ne '') {
                   2948:                 $coursespan += 4;
                   2949:             }
1.473     amueller 2950: 
1.560     damieng  2951:             $r->print(&Apache::loncommon::start_data_table());
                   2952:             #
                   2953:             # This produces the headers
                   2954:             #
                   2955:             $r->print('<tr><td colspan="5"></td>');
                   2956:             $r->print('<th colspan="'.($coursespan).'">'.&mt('Any User').'</th>');
                   2957:             if ($uname) {
1.473     amueller 2958:                 if (@usersgroups > 1) {
1.560     damieng  2959:                     $userspan ++;
                   2960:                 }
                   2961:                 $r->print('<th colspan="'.$userspan.'" rowspan="2">');
                   2962:                 $r->print(&mt('User [_1] at Domain [_2]',"'".$uname."'","'".$udom."'").'</th>');
                   2963:             }
                   2964:             my %lt=&Apache::lonlocal::texthash(
1.473     amueller 2965:                 'pie'    => "Parameter in Effect",
                   2966:                 'csv'    => "Current Session Value",
1.472     amueller 2967:                 'rl'     => "Resource Level",
1.473     amueller 2968:                 'ic'     => 'in Course',
                   2969:                 'aut'    => "Assessment URL and Title",
                   2970:                 'type'   => 'Type',
                   2971:                 'emof'   => "Enclosing Map or Folder",
                   2972:                 'part'   => 'Part',
1.472     amueller 2973:                 'pn'     => 'Parameter Name',
1.473     amueller 2974:                 'def'    => 'default',
                   2975:                 'femof'  => 'from Enclosing Map or Folder',
                   2976:                 'gen'    => 'general',
                   2977:                 'foremf' => 'for Enclosing Map or Folder',
1.556     raeburn  2978:                 'formfr' => 'for Map or Folder (recursive)',
1.473     amueller 2979:                 'fr'     => 'for Resource'
                   2980:             );
1.560     damieng  2981:             $r->print(<<ENDTABLETWO);
1.419     bisitz   2982: <th rowspan="3">$lt{'pie'}</th>
1.501     bisitz   2983: <th rowspan="3">$lt{'csv'}<br />($csuname:$csudom)</th>
1.556     raeburn  2984: </tr><tr><td colspan="5"></td><th colspan="3">$lt{'ic'}</th><th colspan="2">$lt{'rl'}</th>
1.419     bisitz   2985: <th colspan="1">$lt{'ic'}</th>
1.182     albertel 2986: 
1.10      www      2987: ENDTABLETWO
1.560     damieng  2988:             if ($csec) {
                   2989:                 $r->print('<th colspan="4">'.
                   2990:                 &mt("in Section")." $csec</th>");
                   2991:             }
                   2992:             if ($cgroup) {
1.556     raeburn  2993:                 $r->print('<th colspan="4">'.
1.472     amueller 2994:                 &mt("in Group")." $cgroup</th>");
1.560     damieng  2995:             }
                   2996:             $r->print(<<ENDTABLEHEADFOUR);
1.133     www      2997: </tr><tr><th>$lt{'aut'}</th><th>$lt{'type'}</th>
                   2998: <th>$lt{'emof'}</th><th>$lt{'part'}</th><th>$lt{'pn'}</th>
1.556     raeburn  2999: <th>$lt{'gen'}</th><th>$lt{'formfr'}</th><th>$lt{'foremf'}</th>
1.192     albertel 3000: <th>$lt{'def'}</th><th>$lt{'femof'}</th><th>$lt{'fr'}</th>
1.10      www      3001: ENDTABLEHEADFOUR
1.57      albertel 3002: 
1.560     damieng  3003:             if ($csec) {
                   3004:                 $r->print('<th>'.$lt{'gen'}.'</th><th>'.$lt{'formfr'}.'</th><th>'.$lt{'foremf'}.'</th><th>'.$lt{'fr'}.'</th>');
                   3005:             }
1.473     amueller 3006: 
1.560     damieng  3007:             if ($cgroup) {
                   3008:                 $r->print('<th>'.$lt{'gen'}.'</th><th>'.$lt{'formfr'}.'</th><th>'.&mt('foremf').'</th><th>'.$lt{'fr'}.'</th>');
                   3009:             }
                   3010: 
                   3011:             if ($uname) {
                   3012:                 if (@usersgroups > 1) {
                   3013:                     $r->print('<th>'.&mt('Control by other group?').'</th>');
                   3014:                 }
                   3015:                 $r->print('<th>'.$lt{'gen'}.'</th><th>'.$lt{'formfr'}.'</th><th>'.$lt{'foremf'}.'</th><th>'.$lt{'fr'}.'</th>');
                   3016:             }
                   3017: 
                   3018:             $r->print('</tr>');
1.506     www      3019: #
                   3020: # Done with the headers
                   3021: # 
1.560     damieng  3022:             my $defbgone='';
                   3023:             my $defbgtwo='';
                   3024:             my $defbgthree = '';
1.57      albertel 3025: 
1.560     damieng  3026:             foreach my $rid (@ids) {
1.57      albertel 3027: 
                   3028:                 my ($inmapid)=($rid=~/\.(\d+)$/);
                   3029: 
1.446     bisitz   3030:                 if ((!$pssymb &&
1.560     damieng  3031:                         (($pschp eq 'all') || ($allmaps{$pschp} eq $mapp{$rid})))
                   3032:                         ||
                   3033:                         ($pssymb && $pssymb eq $symbp{$rid})) {
1.4       www      3034: # ------------------------------------------------------ Entry for one resource
1.473     amueller 3035:                     if ($defbgone eq '#E0E099') {
                   3036:                         $defbgone='#E0E0DD';
1.57      albertel 3037:                     } else {
1.419     bisitz   3038:                         $defbgone='#E0E099';
1.57      albertel 3039:                     }
1.419     bisitz   3040:                     if ($defbgtwo eq '#FFFF99') {
1.473     amueller 3041:                         $defbgtwo='#FFFFDD';
1.57      albertel 3042:                     } else {
1.473     amueller 3043:                         $defbgtwo='#FFFF99';
1.57      albertel 3044:                     }
1.419     bisitz   3045:                     if ($defbgthree eq '#FFBB99') {
                   3046:                         $defbgthree='#FFBBDD';
1.269     raeburn  3047:                     } else {
1.419     bisitz   3048:                         $defbgthree='#FFBB99';
1.269     raeburn  3049:                     }
                   3050: 
1.57      albertel 3051:                     my $thistitle='';
                   3052:                     my %name=   ();
                   3053:                     undef %name;
                   3054:                     my %part=   ();
                   3055:                     my %display=();
                   3056:                     my %type=   ();
                   3057:                     my %default=();
1.196     www      3058:                     my $uri=&Apache::lonnet::declutter($uris{$rid});
1.57      albertel 3059: 
1.506     www      3060:                     my $filter=$env{'form.filter'};
1.548     raeburn  3061:                     foreach my $tempkeyp (&keysplit($keyp{$rid})) {
1.57      albertel 3062:                         if (grep $_ eq $tempkeyp, @catmarker) {
1.560     damieng  3063:                             my $parmname=&Apache::lonnet::metadata($uri,$tempkeyp.'.name');
                   3064:     # We may only want certain parameters listed
                   3065:                             if ($filter) {
                   3066:                                 unless ($filter=~/\Q$parmname\E/) { next; }
                   3067:                             }
                   3068:                             $name{$tempkeyp}=$parmname;
                   3069:                             $part{$tempkeyp}=&Apache::lonnet::metadata($uri,$tempkeyp.'.part');
                   3070: 
                   3071:                             my $parmdis=&Apache::lonnet::metadata($uri,$tempkeyp.'.display');
                   3072:                             if ($allparms{$name{$tempkeyp}} ne '') {
                   3073:                                 my $identifier;
                   3074:                                 if ($parmdis =~ /(\s*\[Part.*)$/) {
                   3075:                                     $identifier = $1;
                   3076:                                 }
                   3077:                                 $display{$tempkeyp} = $allparms{$name{$tempkeyp}}.$identifier;
                   3078:                             } else {
                   3079:                                 $display{$tempkeyp} = $parmdis;
                   3080:                             }
                   3081:                             unless ($display{$tempkeyp}) { $display{$tempkeyp}=''; }
                   3082:                             $display{$tempkeyp}.=' ('.$name{$tempkeyp}.')';
                   3083:                             $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$tempkeyp);
                   3084:                             $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$tempkeyp.'.type');
                   3085:                             $thistitle=&Apache::lonnet::metadata($uri,$tempkeyp.'.title');
1.57      albertel 3086:                         }
                   3087:                     }
1.548     raeburn  3088:                     my $totalparms=scalar(keys(%name));
1.57      albertel 3089:                     if ($totalparms>0) {
1.560     damieng  3090:                         my $firstrow=1;
1.473     amueller 3091:                         my $title=&Apache::lonnet::gettitle($symbp{$rid});
1.419     bisitz   3092:                         $r->print('<tr><td style="background-color:'.$defbgone.';"'.
1.57      albertel 3093:                              ' rowspan='.$totalparms.
1.419     bisitz   3094:                              '><tt><font size="-1">'.
1.57      albertel 3095:                              join(' / ',split(/\//,$uri)).
                   3096:                              '</font></tt><p><b>'.
1.154     albertel 3097:                              "<a href=\"javascript:openWindow('".
1.473     amueller 3098:                           &Apache::lonnet::clutter($uri).'?symb='.
                   3099:                           &escape($symbp{$rid}).
1.336     albertel 3100:                              "', 'metadatafile', '450', '500', 'no', 'yes');\"".
                   3101:                              " target=\"_self\">$title");
1.57      albertel 3102: 
                   3103:                         if ($thistitle) {
1.473     amueller 3104:                             $r->print(' ('.$thistitle.')');
1.57      albertel 3105:                         }
                   3106:                         $r->print('</a></b></td>');
1.419     bisitz   3107:                         $r->print('<td style="background-color:'.$defbgtwo.';"'.
1.57      albertel 3108:                                       ' rowspan='.$totalparms.'>'.$typep{$rid}.
                   3109:                                       '</td>');
                   3110: 
1.419     bisitz   3111:                         $r->print('<td style="background-color:'.$defbgone.';"'.
1.57      albertel 3112:                                       ' rowspan='.$totalparms.
1.238     www      3113:                                       '>'.$maptitles{$mapp{$rid}}.'</td>');
1.548     raeburn  3114:                         foreach my $item (&keysinorder_bytype(\%name,\%keyorder)) {
1.57      albertel 3115:                             unless ($firstrow) {
                   3116:                                 $r->print('<tr>');
                   3117:                             } else {
                   3118:                                 undef $firstrow;
                   3119:                             }
1.548     raeburn  3120:                             &print_row($r,$item,\%part,\%name,\%symbp,$rid,\%default,
1.57      albertel 3121:                                        \%type,\%display,$defbgone,$defbgtwo,
1.269     raeburn  3122:                                        $defbgthree,$parmlev,$uname,$udom,$csec,
1.553     raeburn  3123:                                        $cgroup,\@usersgroups,$noeditgrp);
1.57      albertel 3124:                         }
                   3125:                     }
                   3126:                 }
                   3127:             } # end foreach ids
1.43      albertel 3128: # -------------------------------------------------- End entry for one resource
1.517     www      3129:             $r->print(&Apache::loncommon::end_data_table);
1.203     www      3130:         } # end of  full
1.57      albertel 3131: #--------------------------------------------------- Entry for parm level map
                   3132:         if ($parmlev eq 'map') {
1.419     bisitz   3133:             my $defbgone = '#E0E099';
                   3134:             my $defbgtwo = '#FFFF99';
                   3135:             my $defbgthree = '#FFBB99';
1.57      albertel 3136: 
                   3137:             my %maplist;
                   3138: 
                   3139:             if ($pschp eq 'all') {
1.446     bisitz   3140:                 %maplist = %allmaps;
1.57      albertel 3141:             } else {
                   3142:                 %maplist = ($pschp => $mapp{$pschp});
                   3143:             }
                   3144: 
                   3145: #-------------------------------------------- for each map, gather information
                   3146:             my $mapid;
1.560     damieng  3147:             foreach $mapid (sort {$maplist{$a} cmp $maplist{$b}} keys(%maplist)) {
1.60      albertel 3148:                 my $maptitle = $maplist{$mapid};
1.57      albertel 3149: 
                   3150: #-----------------------  loop through ids and get all parameter types for map
                   3151: #-----------------------------------------          and associated information
                   3152:                 my %name = ();
                   3153:                 my %part = ();
                   3154:                 my %display = ();
                   3155:                 my %type = ();
                   3156:                 my %default = ();
                   3157:                 my $map = 0;
                   3158: 
1.473     amueller 3159: #        $r->print("Catmarker: @catmarker<br />\n");
1.446     bisitz   3160: 
1.548     raeburn  3161:                 foreach my $id (@ids) {
                   3162:                     ($map)=($id =~ /([\d]*?)\./);
                   3163:                     my $rid = $id;
1.446     bisitz   3164: 
1.57      albertel 3165: #                  $r->print("$mapid:$map:   $rid <br /> \n");
                   3166: 
1.560     damieng  3167:                     if ($map eq $mapid) {
1.473     amueller 3168:                         my $uri=&Apache::lonnet::declutter($uris{$rid});
1.57      albertel 3169: #                    $r->print("Keys: $keyp{$rid} <br />\n");
                   3170: 
                   3171: #--------------------------------------------------------------------
                   3172: # @catmarker contains list of all possible parameters including part #s
                   3173: # $fullkeyp contains the full part/id # for the extraction of proper parameters
                   3174: # $tempkeyp contains part 0 only (no ids - ie, subparts)
                   3175: # When storing information, store as part 0
                   3176: # When requesting information, request from full part
                   3177: #-------------------------------------------------------------------
1.548     raeburn  3178:                         foreach my $fullkeyp (&keysplit($keyp{$rid})) {
                   3179:                             my $tempkeyp = $fullkeyp;
                   3180:                             $tempkeyp =~ s/_\w+_/_0_/;
1.473     amueller 3181: 
1.548     raeburn  3182:                             if ((grep $_ eq $fullkeyp, @catmarker) &&(!$name{$tempkeyp})) {
1.473     amueller 3183:                                 $part{$tempkeyp}="0";
                   3184:                                 $name{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.name');
                   3185:                                 my $parmdis=&Apache::lonnet::metadata($uri,$fullkeyp.'.display');
                   3186:                                 if ($allparms{$name{$tempkeyp}} ne '') {
                   3187:                                     my $identifier;
                   3188:                                     if ($parmdis =~ /(\s*\[Part.*)$/) {
                   3189:                                         $identifier = $1;
                   3190:                                     }
                   3191:                                     $display{$tempkeyp} = $allparms{$name{$tempkeyp}}.$identifier;
                   3192:                                 } else {
                   3193:                                     $display{$tempkeyp} = $parmdis;
                   3194:                                 }
                   3195:                                 unless ($display{$tempkeyp}) { $display{$tempkeyp}=''; }
                   3196:                                 $display{$tempkeyp}.=' ('.$name{$tempkeyp}.')';
                   3197:                                 $display{$tempkeyp} =~ s/_\w+_/_0_/;
                   3198:                                 $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp);
                   3199:                                 $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.type');
                   3200:                               }
                   3201:                         } # end loop through keys
1.560     damieng  3202:                     }
1.57      albertel 3203:                 } # end loop through ids
1.446     bisitz   3204: 
1.57      albertel 3205: #---------------------------------------------------- print header information
1.133     www      3206:                 my $foldermap=&mt($maptitle=~/^uploaded/?'Folder':'Map');
1.82      www      3207:                 my $showtitle=$maptitles{$maptitle}.($maptitle!~/^uploaded/?' ['.$maptitle.']':'');
1.401     bisitz   3208:                 my $tmp="";
1.57      albertel 3209:                 if ($uname) {
1.473     amueller 3210:                     my $person=&Apache::loncommon::plainname($uname,$udom);
1.401     bisitz   3211:                     $tmp.=&mt("User")." <font color=\"red\"><i>$uname \($person\) </i></font> ".
                   3212:                         &mt('in')." \n";
1.57      albertel 3213:                 } else {
1.401     bisitz   3214:                     $tmp.="<font color=\"red\"><i>".&mt('all').'</i></font> '.&mt('users in')." \n";
1.57      albertel 3215:                 }
1.269     raeburn  3216:                 if ($cgroup) {
1.401     bisitz   3217:                     $tmp.=&mt("Group")." <font color=\"red\"><i>$cgroup".
                   3218:                               "</i></font> ".&mt('of')." \n";
1.269     raeburn  3219:                     $csec = '';
                   3220:                 } elsif ($csec) {
1.401     bisitz   3221:                     $tmp.=&mt("Section")." <font color=\"red\"><i>$csec".
                   3222:                               "</i></font> ".&mt('of')." \n";
1.269     raeburn  3223:                 }
1.401     bisitz   3224:                 $r->print('<div align="center"><h4>'
                   3225:                          .&mt('Set Defaults for All Resources in [_1]Specifically for [_2][_3]'
1.404     bisitz   3226:                              ,$foldermap.'<br /><font color="red"><i>'.$showtitle.'</i></font><br />'
1.401     bisitz   3227:                              ,$tmp
                   3228:                              ,'<font color="red"><i>'.$coursename.'</i></font>'
                   3229:                              )
                   3230:                          ."<br /></h4>\n"
1.422     bisitz   3231:                 );
1.57      albertel 3232: #---------------------------------------------------------------- print table
1.419     bisitz   3233:                 $r->print('<p>'.&Apache::loncommon::start_data_table()
                   3234:                          .&Apache::loncommon::start_data_table_header_row()
                   3235:                          .'<th>'.&mt('Parameter Name').'</th>'
1.556     raeburn  3236:                          .'<th>'.&mt('Recursive Value').'</th>'
                   3237:                          .'<th>'.&mt('Non-Recursive Value').'</th>'
1.419     bisitz   3238:                          .'<th>'.&mt('Parameter in Effect').'</th>'
                   3239:                          .&Apache::loncommon::end_data_table_header_row()
                   3240:                 );
1.57      albertel 3241: 
1.548     raeburn  3242:                 foreach my $item (&keysinorder(\%name,\%keyorder)) {
1.473     amueller 3243:                     $r->print(&Apache::loncommon::start_data_table_row());
1.548     raeburn  3244:                     &print_row($r,$item,\%part,\%name,\%symbp,$mapid,\%default,
1.269     raeburn  3245:                            \%type,\%display,$defbgone,$defbgtwo,$defbgthree,
1.553     raeburn  3246:                            $parmlev,$uname,$udom,$csec,$cgroup,'',$noeditgrp);
1.57      albertel 3247:                 }
1.422     bisitz   3248:                 $r->print(&Apache::loncommon::end_data_table().'</p>'
                   3249:                          .'</div>'
                   3250:                 );
1.57      albertel 3251:             } # end each map
                   3252:         } # end of $parmlev eq map
                   3253: #--------------------------------- Entry for parm level general (Course level)
                   3254:         if ($parmlev eq 'general') {
1.473     amueller 3255:             my $defbgone = '#E0E099';
1.419     bisitz   3256:             my $defbgtwo = '#FFFF99';
                   3257:             my $defbgthree = '#FFBB99';
1.57      albertel 3258: 
                   3259: #-------------------------------------------- for each map, gather information
                   3260:             my $mapid="0.0";
                   3261: #-----------------------  loop through ids and get all parameter types for map
                   3262: #-----------------------------------------          and associated information
                   3263:             my %name = ();
                   3264:             my %part = ();
                   3265:             my %display = ();
                   3266:             my %type = ();
                   3267:             my %default = ();
1.446     bisitz   3268: 
1.548     raeburn  3269:             foreach $id (@ids) {
                   3270:                 my $rid = $id;
1.446     bisitz   3271: 
1.196     www      3272:                 my $uri=&Apache::lonnet::declutter($uris{$rid});
1.57      albertel 3273: 
                   3274: #--------------------------------------------------------------------
                   3275: # @catmarker contains list of all possible parameters including part #s
                   3276: # $fullkeyp contains the full part/id # for the extraction of proper parameters
                   3277: # $tempkeyp contains part 0 only (no ids - ie, subparts)
                   3278: # When storing information, store as part 0
                   3279: # When requesting information, request from full part
                   3280: #-------------------------------------------------------------------
1.548     raeburn  3281:                 foreach my $fullkeyp (&keysplit($keyp{$rid})) {
                   3282:                     my $tempkeyp = $fullkeyp;
                   3283:                     $tempkeyp =~ s/_\w+_/_0_/;
                   3284:                     if ((grep $_ eq $fullkeyp, @catmarker) &&(!$name{$tempkeyp})) {
1.473     amueller 3285:                         $part{$tempkeyp}="0";
                   3286:                         $name{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.name');
                   3287:                         my $parmdis=&Apache::lonnet::metadata($uri,$fullkeyp.'.display');
                   3288:                         if ($allparms{$name{$tempkeyp}} ne '') {
                   3289:                             my $identifier;
                   3290:                             if ($parmdis =~ /(\s*\[Part.*)$/) {
                   3291:                                 $identifier = $1;
                   3292:                             }
                   3293:                             $display{$tempkeyp} = $allparms{$name{$tempkeyp}}.$identifier;
                   3294:                         } else {
                   3295:                             $display{$tempkeyp} = $parmdis;
                   3296:                         }
                   3297:                         unless ($display{$tempkeyp}) { $display{$tempkeyp}=''; }
                   3298:                         $display{$tempkeyp}.=' ('.$name{$tempkeyp}.')';
                   3299:                         $display{$tempkeyp} =~ s/_\w+_/_0_/;
                   3300:                         $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp);
                   3301:                         $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.type');
1.560     damieng  3302:                     }
1.57      albertel 3303:                 } # end loop through keys
                   3304:             } # end loop through ids
1.446     bisitz   3305: 
1.57      albertel 3306: #---------------------------------------------------- print header information
1.473     amueller 3307:             my $setdef=&mt("Set Defaults for All Resources in Course");
1.57      albertel 3308:             $r->print(<<ENDMAPONE);
1.419     bisitz   3309: <center>
                   3310: <h4>$setdef
1.135     albertel 3311: <font color="red"><i>$coursename</i></font><br />
1.57      albertel 3312: ENDMAPONE
                   3313:             if ($uname) {
1.473     amueller 3314:                 my $person=&Apache::loncommon::plainname($uname,$udom);
1.135     albertel 3315:                 $r->print(" ".&mt("User")."<font color=\"red\"> <i>$uname \($person\) </i></font> \n");
1.57      albertel 3316:             } else {
1.135     albertel 3317:                 $r->print("<i><font color=\"red\"> ".&mt("ALL")."</i> ".&mt("USERS")."</font> \n");
1.57      albertel 3318:             }
1.446     bisitz   3319: 
1.135     albertel 3320:             if ($csec) {$r->print(&mt("Section")."<font color=\"red\"> <i>$csec</i></font>\n")};
1.306     albertel 3321:             if ($cgroup) {$r->print(&mt("Group")."<font color=\"red\"> <i>$cgroup</i></font>\n")};
1.135     albertel 3322:             $r->print("</h4>\n");
1.57      albertel 3323: #---------------------------------------------------------------- print table
1.419     bisitz   3324:             $r->print('<p>'.&Apache::loncommon::start_data_table()
                   3325:                      .&Apache::loncommon::start_data_table_header_row()
                   3326:                      .'<th>'.&mt('Parameter Name').'</th>'
                   3327:                      .'<th>'.&mt('Default Value').'</th>'
                   3328:                      .'<th>'.&mt('Parameter in Effect').'</th>'
                   3329:                      .&Apache::loncommon::end_data_table_header_row()
                   3330:             );
1.57      albertel 3331: 
1.548     raeburn  3332:             foreach my $item (&keysinorder(\%name,\%keyorder)) {
1.419     bisitz   3333:                 $r->print(&Apache::loncommon::start_data_table_row());
1.548     raeburn  3334:                 &print_row($r,$item,\%part,\%name,\%symbp,$mapid,\%default,
1.269     raeburn  3335:                        \%type,\%display,$defbgone,$defbgtwo,$defbgthree,
1.553     raeburn  3336:                                    $parmlev,$uname,$udom,$csec,$cgroup,'',$noeditgrp);
1.57      albertel 3337:             }
1.419     bisitz   3338:             $r->print(&Apache::loncommon::end_data_table()
                   3339:                      .'</p>'
                   3340:                      .'</center>'
                   3341:             );
1.57      albertel 3342:         } # end of $parmlev eq general
1.43      albertel 3343:     }
1.507     www      3344:     $r->print('</form>');
                   3345:     &endSettingsScreen($r);
                   3346:     $r->print(&Apache::loncommon::end_page());
1.57      albertel 3347: } # end sub assessparms
1.30      www      3348: 
1.560     damieng  3349: 
                   3350: 
1.120     www      3351: ##################################################
1.560     damieng  3352: # OVERVIEW MODE
1.207     www      3353: ##################################################
1.124     www      3354: my $tableopen;
                   3355: 
                   3356: sub tablestart {
1.552     raeburn  3357:     my ($readonly) = @_;
1.124     www      3358:     if ($tableopen) {
1.552     raeburn  3359:         return '';
1.124     www      3360:     } else {
1.552     raeburn  3361:         $tableopen=1;
                   3362:         my $output = &Apache::loncommon::start_data_table().'<tr><th>'.&mt('Parameter').'</th>';
                   3363:         if ($readonly) {
                   3364:             $output .= '<th>'.&mt('Current value').'</th>';
                   3365:         } else {
                   3366:             $output .= '<th>'.&mt('Delete').'</th><th>'.&mt('Set to ...').'</th>';
                   3367:         }
                   3368:         $output .= '</tr>';
                   3369:         return $output;
1.124     www      3370:     }
                   3371: }
                   3372: 
                   3373: sub tableend {
                   3374:     if ($tableopen) {
1.560     damieng  3375:         $tableopen=0;
                   3376:         return &Apache::loncommon::end_data_table();
1.124     www      3377:     } else {
1.560     damieng  3378:         return'';
1.124     www      3379:     }
                   3380: }
                   3381: 
1.207     www      3382: sub readdata {
                   3383:     my ($crs,$dom)=@_;
                   3384: # Read coursedata
                   3385:     my $resourcedata=&Apache::lonnet::get_courseresdata($crs,$dom);
                   3386: # Read userdata
                   3387: 
                   3388:     my $classlist=&Apache::loncoursedata::get_classlist();
1.548     raeburn  3389:     foreach my $user (keys(%$classlist)) {
                   3390:         if ($user=~/^($match_username)\:($match_domain)$/) {
                   3391:             my ($tuname,$tudom)=($1,$2);
                   3392:             my $useropt=&Apache::lonnet::get_userresdata($tuname,$tudom);
                   3393:             foreach my $userkey (keys(%{$useropt})) {
                   3394:                 if ($userkey=~/^\Q$env{'request.course.id'}\E/) {
1.207     www      3395:                     my $newkey=$userkey;
1.548     raeburn  3396:                     $newkey=~s/^($env{'request.course.id'}\.)/$1\[useropt\:$tuname\:$tudom\]\./;
                   3397:                     $$resourcedata{$newkey}=$$useropt{$userkey};
                   3398:                 }
                   3399:             }
1.473     amueller 3400:         }
                   3401:     }
1.552     raeburn  3402:     if (wantarray) {
                   3403:         return ($resourcedata,$classlist);
                   3404:     } else {
                   3405:         return $resourcedata;
                   3406:     }
1.207     www      3407: }
                   3408: 
                   3409: 
1.124     www      3410: # Setting
1.208     www      3411: 
                   3412: sub storedata {
                   3413:     my ($r,$crs,$dom)=@_;
1.207     www      3414: # Set userlevel immediately
                   3415: # Do an intermediate store of course level
                   3416:     my $olddata=&readdata($crs,$dom);
1.124     www      3417:     my %newdata=();
                   3418:     undef %newdata;
                   3419:     my @deldata=();
                   3420:     undef @deldata;
1.504     raeburn  3421:     my ($got_chostname,$chostname,$cmajor,$cminor);
1.546     raeburn  3422:     my $now = time;
1.560     damieng  3423:     foreach my $key (keys(%env)) {
                   3424:         if ($key =~ /^form\.([a-z]+)\_(.+)$/) {
                   3425:             my $cmd=$1;
                   3426:             my $thiskey=$2;
                   3427:             next if ($cmd eq 'settext' || $cmd eq 'setipallow' || $cmd eq 'setipdeny');
                   3428:             my ($tuname,$tudom)=&extractuser($thiskey);
                   3429:             my $tkey=$thiskey;
1.473     amueller 3430:             if ($tuname) {
1.560     damieng  3431:                 $tkey=~s/\.\[useropt\:$tuname\:$tudom\]\./\./;
                   3432:             }
                   3433:             if ($cmd eq 'set' || $cmd eq 'datepointer' || $cmd eq 'dateinterval') {
                   3434:             my ($data, $typeof, $text, $name, $valchk, $valmatch, $namematch);
                   3435:             if ($cmd eq 'set') {
                   3436:                 $data=$env{$key};
                   3437:                 $valmatch = '';
                   3438:                 $valchk = $data;
                   3439:                 $typeof=$env{'form.typeof_'.$thiskey};
                   3440:                 $text = &mt('Saved modified parameter for');
                   3441:                 if ($typeof eq 'string_questiontype') {
                   3442:                     $name = 'type';
                   3443:                 } elsif ($typeof eq 'string_lenient') {
                   3444:                     $name = 'lenient';
                   3445:                     my $stringmatch = &standard_string_matches($typeof);
                   3446:                     if (ref($stringmatch) eq 'ARRAY') {
                   3447:                         foreach my $item (@{$stringmatch}) {
                   3448:                             if (ref($item) eq 'ARRAY') {
                   3449:                                 my ($regexpname,$pattern) = @{$item};
                   3450:                                 if ($pattern ne '') {
                   3451:                                     if ($data =~ /$pattern/) {
                   3452:                                         $valmatch = $regexpname;
                   3453:                                         $valchk = '';
                   3454:                                         last;
                   3455:                                     }
1.549     raeburn  3456:                                 }
                   3457:                             }
                   3458:                         }
                   3459:                     }
1.560     damieng  3460:                 } elsif ($typeof eq 'string_discussvote') {
                   3461:                     $name = 'discussvote';
                   3462:                 } elsif ($typeof eq 'string_examcode') {
                   3463:                     $name = 'examcode';
                   3464:                     if (&Apache::lonnet::validCODE($data)) {
                   3465:                         $valchk = 'valid';
                   3466:                     }
                   3467:                 } elsif ($typeof eq 'string_yesno') {
                   3468:                     if ($thiskey =~ /\.retrypartial$/) {
                   3469:                         $name = 'retrypartial';
                   3470:                     }
                   3471:                 }
                   3472:             } elsif ($cmd eq 'datepointer') {
                   3473:                 $data=&Apache::lonhtmlcommon::get_date_from_form($env{$key});
                   3474:                 $typeof=$env{'form.typeof_'.$thiskey};
                   3475:                 $text = &mt('Saved modified date for');
                   3476:                 if ($typeof eq 'date_start') {
                   3477:                     if ($thiskey =~ /\.printstartdate$/) {
                   3478:                         $name = 'printstartdate';
                   3479:                         if (($data) && ($data > $now)) {
                   3480:                             $valchk = 'future';
                   3481:                         }
                   3482:                     }
                   3483:                 } elsif ($typeof eq 'date_end') {
                   3484:                     if ($thiskey =~ /\.printenddate$/) {
                   3485:                         $name = 'printenddate';
                   3486:                         if (($data) && ($data < $now)) {
                   3487:                             $valchk = 'past';
                   3488:                         }
1.504     raeburn  3489:                     }
                   3490:                 }
1.560     damieng  3491:             } elsif ($cmd eq 'dateinterval') {
                   3492:                 $data=&get_date_interval_from_form($thiskey);
                   3493:                 if ($thiskey =~ /\.interval$/) {
                   3494:                     $name = 'interval';
                   3495:                     my $intervaltype = &get_intervaltype($name);
                   3496:                     my $intervalmatch = &standard_interval_matches($intervaltype);
                   3497:                     if (ref($intervalmatch) eq 'ARRAY') {
                   3498:                         foreach my $item (@{$intervalmatch}) {
                   3499:                             if (ref($item) eq 'ARRAY') {
                   3500:                                 my ($regexpname,$pattern) = @{$item};
                   3501:                                 if ($pattern ne '') {
                   3502:                                     if ($data =~ /$pattern/) {
                   3503:                                         $valmatch = $regexpname;
                   3504:                                         $valchk = '';
                   3505:                                         last;
                   3506:                                     }
1.554     raeburn  3507:                                 }
                   3508:                             }
                   3509:                         }
                   3510:                     }
                   3511:                 }
1.560     damieng  3512:                 $typeof=$env{'form.typeof_'.$thiskey};
                   3513:                 $text = &mt('Saved modified date for');
1.554     raeburn  3514:             }
1.560     damieng  3515:             if ($thiskey =~ m{\.(?:sequence|page)___\(rec\)}) {
                   3516:                 $namematch = 'maplevelrecurse';
1.557     raeburn  3517:             }
1.560     damieng  3518:             if (($name ne '') || ($namematch ne '')) {
                   3519:                 my ($needsrelease,$needsnewer);
                   3520:                 if ($name ne '') {
                   3521:                     $needsrelease = $Apache::lonnet::needsrelease{"parameter:$name:$valchk:$valmatch:"};
1.557     raeburn  3522:                     if ($needsrelease) {
                   3523:                         unless ($got_chostname) {
1.560     damieng  3524:                             ($chostname,$cmajor,$cminor)=&parameter_release_vars();
1.557     raeburn  3525:                             $got_chostname = 1;
                   3526:                         }
1.560     damieng  3527:                         $needsnewer = &parameter_releasecheck($name,$valchk,$valmatch,undef,
                   3528:                                                             $needsrelease,
                   3529:                                                             $cmajor,$cminor);
                   3530:                     }
                   3531:                 }
                   3532:                 if ($namematch ne '') {
                   3533:                     if ($needsnewer) {
                   3534:                         undef($namematch);
1.557     raeburn  3535:                     } else {
1.560     damieng  3536:                         my $currneeded;
                   3537:                         if ($needsrelease) {
                   3538:                             $currneeded = $needsrelease;
                   3539:                         }
                   3540:                         $needsrelease =
                   3541:                             $Apache::lonnet::needsrelease{"parameter::::$namematch"};
                   3542:                         if (($needsrelease) && (($currneeded eq '') || ($needsrelease < $currneeded))) {
                   3543:                             unless ($got_chostname) {
                   3544:                                 ($chostname,$cmajor,$cminor) = &parameter_release_vars();
                   3545:                                 $got_chostname = 1;
                   3546:                             }
                   3547:                             $needsnewer = &parameter_releasecheck(undef,$valchk,$valmatch,$namematch,
                   3548:                                                                 $needsrelease,$cmajor,$cminor);
                   3549:                         } else {
                   3550:                             undef($namematch);
                   3551:                         }
1.557     raeburn  3552:                     }
1.504     raeburn  3553:                 }
1.560     damieng  3554:                 if ($needsnewer) {
                   3555:                     $r->print('<br />'.&oldversion_warning($name,$namematch,$data,
                   3556:                                                         $chostname,$cmajor,
                   3557:                                                         $cminor,$needsrelease));
                   3558:                     next;
                   3559:                 }
1.504     raeburn  3560:             }
1.560     damieng  3561:             if (defined($data) and $$olddata{$thiskey} ne $data) {
                   3562:                 if ($tuname) {
                   3563:                     if (&Apache::lonnet::put('resourcedata',{$tkey=>$data,
                   3564:                                         $tkey.'.type' => $typeof},
                   3565:                                 $tudom,$tuname) eq 'ok') {
                   3566:                         &log_parmset({$tkey=>$data,$tkey.'.type' => $typeof},0,$tuname,$tudom);
                   3567:                         $r->print('<br />'.$text.' '.
                   3568:                             &Apache::loncommon::plainname($tuname,$tudom));
                   3569:                     } else {
                   3570:                         $r->print('<div class="LC_error">'.
                   3571:                             &mt('Error saving parameters').'</div>');
                   3572:                     }
                   3573:                     &Apache::lonnet::devalidateuserresdata($tuname,$tudom);
                   3574:                 } else {
                   3575:                     $newdata{$thiskey}=$data;
                   3576:                     $newdata{$thiskey.'.type'}=$typeof;
                   3577:                 }
1.557     raeburn  3578:             }
1.560     damieng  3579:             } elsif ($cmd eq 'del') {
                   3580:                 if ($tuname) {
                   3581:                     if (&Apache::lonnet::del('resourcedata',[$tkey],$tudom,$tuname) eq 'ok') {
                   3582:                             &log_parmset({$tkey=>''},1,$tuname,$tudom);
                   3583:                         $r->print('<br />'.&mt('Deleted parameter for').' '.&Apache::loncommon::plainname($tuname,$tudom));
                   3584:                     } else {
                   3585:                         $r->print('<div class="LC_error">'.
                   3586:                             &mt('Error deleting parameters').'</div>');
                   3587:                     }
                   3588:                     &Apache::lonnet::devalidateuserresdata($tuname,$tudom);
                   3589:                 } else {
                   3590:                     push (@deldata,$thiskey,$thiskey.'.type');
                   3591:                 }
1.473     amueller 3592:             }
                   3593:         }
                   3594:     }
1.207     www      3595: # Store all course level
1.144     www      3596:     my $delentries=$#deldata+1;
1.548     raeburn  3597:     my @newdatakeys=keys(%newdata);
1.144     www      3598:     my $putentries=$#newdatakeys+1;
                   3599:     if ($delentries) {
1.560     damieng  3600:         if (&Apache::lonnet::del('resourcedata',\@deldata,$dom,$crs) eq 'ok') {
                   3601:             my %loghash=map { $_ => '' } @deldata;
                   3602:             &log_parmset(\%loghash,1);
                   3603:             $r->print('<h2>'.&mt('Deleted [quant,_1,parameter]',$delentries/2).'</h2>');
                   3604:         } else {
                   3605:             $r->print('<div class="LC_error">'.
                   3606:                 &mt('Error deleting parameters').'</div>');
                   3607:         }
                   3608:         &Apache::lonnet::devalidatecourseresdata($crs,$dom);
1.144     www      3609:     }
                   3610:     if ($putentries) {
1.560     damieng  3611:         if (&Apache::lonnet::put('resourcedata',\%newdata,$dom,$crs) eq 'ok') {
                   3612:                     &log_parmset(\%newdata,0);
                   3613:             $r->print('<h3>'.&mt('Saved [quant,_1,parameter]',$putentries/2).'</h3>');
                   3614:         } else {
                   3615:             $r->print('<div class="LC_error">'.
                   3616:                 &mt('Error saving parameters').'</div>');
                   3617:         }
                   3618:         &Apache::lonnet::devalidatecourseresdata($crs,$dom);
1.144     www      3619:     }
1.208     www      3620: }
1.207     www      3621: 
1.208     www      3622: sub extractuser {
                   3623:     my $key=shift;
1.350     albertel 3624:     return ($key=~/^$env{'request.course.id'}.\[useropt\:($match_username)\:($match_domain)\]\./);
1.208     www      3625: }
1.206     www      3626: 
1.381     albertel 3627: sub parse_listdata_key {
                   3628:     my ($key,$listdata) = @_;
                   3629:     # split into student/section affected, and
                   3630:     # the realm (folder/resource part and parameter
1.446     bisitz   3631:     my ($student,$realm) =
1.473     amueller 3632:     ($key=~/^\Q$env{'request.course.id'}\E\.\[([^\.]+)\]\.(.+)$/);
1.381     albertel 3633:     # if course wide student would be undefined
                   3634:     if (!defined($student)) {
1.560     damieng  3635:         ($realm)=($key=~/^\Q$env{'request.course.id'}\E\.(.+)$/);
1.381     albertel 3636:     }
                   3637:     # strip off the .type if it's not the Question type parameter
                   3638:     if ($realm=~/\.type$/ && !exists($listdata->{$key.'.type'})) {
1.560     damieng  3639:         $realm=~s/\.type//;
1.381     albertel 3640:     }
                   3641:     # split into resource+part and parameter name
1.388     albertel 3642:     my ($res,    $parm) = ($realm=~/^(.*)\.(.*)$/);
                   3643:        ($res, my $part) = ($res  =~/^(.*)\.(.*)$/);
1.381     albertel 3644:     return ($student,$res,$part,$parm);
                   3645: }
                   3646: 
1.560     damieng  3647: # Displays forms for the given data in overview mode (newoverview or overview).
1.208     www      3648: sub listdata {
1.552     raeburn  3649:     my ($r,$resourcedata,$listdata,$sortorder,$caller,$classlist)=@_;
                   3650:     
1.207     www      3651: # Start list output
1.206     www      3652: 
1.122     www      3653:     my $oldsection='';
                   3654:     my $oldrealm='';
                   3655:     my $oldpart='';
1.123     www      3656:     my $pointer=0;
1.124     www      3657:     $tableopen=0;
1.145     www      3658:     my $foundkeys=0;
1.248     albertel 3659:     my %keyorder=&standardkeyorder();
1.381     albertel 3660: 
1.552     raeburn  3661:     my ($secidx,%grouphash);
                   3662:     if (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {
                   3663:         $secidx = &Apache::loncoursedata::CL_SECTION();
1.553     raeburn  3664:         if (&Apache::lonnet::allowed('mdg',$env{'request.course.id'})) {
                   3665:             %grouphash = &Apache::longroup::coursegroups();
                   3666:         } elsif ($env{'request.course.groups'} ne '') {
                   3667:             map { $grouphash{$_} = 1; } split(/,/,$env{'request.course.groups'});
                   3668:         }
1.552     raeburn  3669:     }
                   3670: 
1.214     www      3671:     foreach my $thiskey (sort {
1.560     damieng  3672:         my ($astudent,$ares,$apart,$aparm) = &parse_listdata_key($a,$listdata);
                   3673:         my ($bstudent,$bres,$bpart,$bparm) = &parse_listdata_key($b,$listdata);
1.381     albertel 3674: 
1.560     damieng  3675:         # get the numerical order for the param
                   3676:         $aparm=$keyorder{'parameter_0_'.$aparm};
                   3677:         $bparm=$keyorder{'parameter_0_'.$bparm};
1.381     albertel 3678: 
1.560     damieng  3679:         my $result=0;
1.381     albertel 3680: 
1.560     damieng  3681:         if ($sortorder eq 'realmstudent') {
1.381     albertel 3682:             if ($ares     ne $bres    ) {
1.560     damieng  3683:                 $result = ($ares     cmp $bres);
1.446     bisitz   3684:             } elsif ($astudent ne $bstudent) {
1.560     damieng  3685:                 $result = ($astudent cmp $bstudent);
                   3686:             } elsif ($apart    ne $bpart   ) {
                   3687:                 $result = ($apart    cmp $bpart);
                   3688:             }
                   3689:         } else {
                   3690:             if      ($astudent ne $bstudent) {
                   3691:                 $result = ($astudent cmp $bstudent);
                   3692:             } elsif ($ares     ne $bres    ) {
                   3693:                 $result = ($ares     cmp $bres);
                   3694:             } elsif ($apart    ne $bpart   ) {
                   3695:                 $result = ($apart    cmp $bpart);
                   3696:             }
1.473     amueller 3697:         }
1.446     bisitz   3698: 
1.560     damieng  3699:         if (!$result) {
1.381     albertel 3700:             if (defined($aparm) && defined($bparm)) {
1.560     damieng  3701:                 $result = ($aparm <=> $bparm);
1.381     albertel 3702:             } elsif (defined($aparm)) {
1.560     damieng  3703:                 $result = -1;
1.381     albertel 3704:             } elsif (defined($bparm)) {
1.560     damieng  3705:                 $result = 1;
                   3706:             }
1.473     amueller 3707:         }
1.381     albertel 3708: 
1.560     damieng  3709:         $result;
                   3710:         
                   3711:     } keys(%{$listdata})) { # foreach my $thiskey
1.381     albertel 3712: 
1.560     damieng  3713:         my $readonly;
                   3714:         if ($$listdata{$thiskey.'.type'}) {
                   3715:             my $thistype=$$listdata{$thiskey.'.type'};
                   3716:             if ($$resourcedata{$thiskey.'.type'}) {
                   3717:                 $thistype=$$resourcedata{$thiskey.'.type'};
                   3718:             }
                   3719:             my ($middle,$part,$name)=
                   3720:                 ($thiskey=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s]+)\.(\w+)$/);
                   3721:             my $section=&mt('All Students');
                   3722:             if ($middle=~/^\[(.*)\]/) {
                   3723:                 my $issection=$1;
                   3724:                 if ($issection=~/^useropt\:($match_username)\:($match_domain)/) {
                   3725:                     my ($stuname,$studom) = ($1,$2);
                   3726:                     if (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {
                   3727:                         if (ref($classlist) eq 'HASH') {
                   3728:                             if (ref($classlist->{$stuname.':'.$studom}) eq 'ARRAY') {
                   3729:                                 next unless ($classlist->{$stuname.':'.$studom}->[$secidx] eq $env{'request.course.sec'}); 
                   3730:                             }
                   3731:                         }
                   3732:                     }
                   3733:                     $section=&mt('User').": ".&Apache::loncommon::plainname($stuname,$studom);
                   3734:                 } else {
                   3735:                     if (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {
                   3736:                         if (exists($grouphash{$issection})) {
                   3737:                             $section=&mt('Group').': '.$issection;
                   3738:                         } elsif ($issection eq $env{'request.course.sec'}) {
                   3739:                             $section = &mt('Section').': '.$issection;
                   3740:                         } else {
                   3741:                             next; 
1.552     raeburn  3742:                         }
1.560     damieng  3743:                     } else {
                   3744:                         $section=&mt('Group/Section').': '.$issection;
1.552     raeburn  3745:                     }
                   3746:                 }
1.560     damieng  3747:                 $middle=~s/^\[(.*)\]//;
                   3748:             } elsif (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {
                   3749:                 $readonly = 1;
                   3750:             }
                   3751:             $middle=~s/\.+$//;
                   3752:             $middle=~s/^\.+//;
                   3753:             my $realm='<span class="LC_parm_scope_all">'.&mt('All Resources').'</span>';
                   3754:             if ($middle=~/^(.+)\_\_\_\((all|rec)\)$/) {
                   3755:                 my $mapurl = $1;
                   3756:                 my $maplevel = $2;
                   3757:                 my $leveltitle = &mt('Folder/Map');
                   3758:                 if ($maplevel eq 'rec') {
                   3759:                     $leveltitle = &mt('Recursive');
                   3760:                 }
                   3761:                 $realm='<span class="LC_parm_scope_folder">'.$leveltitle.': '.&Apache::lonnet::gettitle($mapurl).' <br /><span class="LC_parm_folder">('.$mapurl.')</span></span>';
                   3762:             } elsif ($middle) {
                   3763:                 my ($map,$id,$url)=&Apache::lonnet::decode_symb($middle);
                   3764:                 $realm='<span class="LC_parm_scope_resource">'.&mt('Resource').
                   3765:                     ': '.&Apache::lonnet::gettitle($middle).
                   3766:                     ' <br /><span class="LC_parm_symb">('.$url.' in '.$map.' id: '.
                   3767:                     $id.')</span></span>';
                   3768:             }
                   3769:             if ($sortorder eq 'realmstudent') {
                   3770:                 if ($realm ne $oldrealm) {
                   3771:                     $r->print(&tableend()."\n<hr /><h1>$realm</h1>");
                   3772:                     $oldrealm=$realm;
                   3773:                     $oldsection='';
                   3774:                 }
                   3775:                 if ($section ne $oldsection) {
                   3776:                     $r->print(&tableend()."\n<h2>$section</h2>");
                   3777:                     $oldsection=$section;
                   3778:                     $oldpart='';
                   3779:                 }
1.552     raeburn  3780:             } else {
1.560     damieng  3781:                 if ($section ne $oldsection) {
                   3782:                     $r->print(&tableend()."\n<hr /><h1>$section</h1>");
                   3783:                     $oldsection=$section;
                   3784:                     $oldrealm='';
                   3785:                 }
                   3786:                 if ($realm ne $oldrealm) {
                   3787:                     $r->print(&tableend()."\n<h2>$realm</h2>");
                   3788:                     $oldrealm=$realm;
                   3789:                     $oldpart='';
1.552     raeburn  3790:                 }
                   3791:             }
1.560     damieng  3792:             if ($part ne $oldpart) {
                   3793:                 $r->print(&tableend().
                   3794:                     "\n".'<span class="LC_parm_part">'.&mt('Part').": $part</span>");
                   3795:                 $oldpart=$part;
1.556     raeburn  3796:             }
1.560     damieng  3797:     #
                   3798:     # Ready to print
                   3799:     #
1.470     raeburn  3800:             my $parmitem = &standard_parameter_names($name);
1.560     damieng  3801:             $r->print(&tablestart($readonly).
                   3802:                 &Apache::loncommon::start_data_table_row().
                   3803:                 '<td><b>'.&mt($parmitem).
                   3804:                 '</b></td>');
                   3805:             unless ($readonly) {
                   3806:                 $r->print('<td><input type="checkbox" name="del_'.
                   3807:                         $thiskey.'" /></td>');
                   3808:             }
                   3809:             $r->print('<td>');
                   3810:             $foundkeys++;
                   3811:             if (&isdateparm($thistype)) {
                   3812:                 my $jskey='key_'.$pointer;
                   3813:                 my $state;
                   3814:                 $pointer++;
                   3815:                 if ($readonly) {
                   3816:                     $state = 'disabled';
                   3817:                 }
                   3818:                 $r->print(
                   3819:                     &Apache::lonhtmlcommon::date_setter('parmform',
                   3820:                                                         $jskey,
                   3821:                                                         $$resourcedata{$thiskey},
                   3822:                                                         '',1,$state));
                   3823:                 unless  ($readonly) {
                   3824:                     $r->print(
                   3825:     '<input type="hidden" name="datepointer_'.$thiskey.'" value="'.$jskey.'" />'.
                   3826:     (($$resourcedata{$thiskey}!=0)?'<span class="LC_nobreak"><a href="/adm/parmset?&action=dateshift1&timebase='.$$resourcedata{$thiskey}.'">'.
                   3827:     &mt('Shift all dates based on this date').'</a></span>':'').
                   3828:     &date_sanity_info($$resourcedata{$thiskey})
                   3829:                     );
                   3830:                 }
                   3831:             } elsif ($thistype eq 'date_interval') {
                   3832:                 $r->print(&date_interval_selector($thiskey,$name,
                   3833:                         $$resourcedata{$thiskey},$readonly));
                   3834:             } elsif ($thistype =~ m/^string/) {
                   3835:                 $r->print(&string_selector($thistype,$thiskey,
                   3836:                         $$resourcedata{$thiskey},$name,$readonly));
                   3837:             } else {
                   3838:                 $r->print(&default_selector($thiskey,$$resourcedata{$thiskey},$readonly));
1.552     raeburn  3839:             }
1.560     damieng  3840:             unless ($readonly) {
                   3841:                 $r->print('<input type="hidden" name="typeof_'.$thiskey.'" value="'.
                   3842:                         $thistype.'" />');
1.552     raeburn  3843:             }
1.560     damieng  3844:             $r->print('</td>'.&Apache::loncommon::end_data_table_row());
1.473     amueller 3845:         }
1.121     www      3846:     }
1.208     www      3847:     return $foundkeys;
                   3848: }
                   3849: 
1.385     albertel 3850: sub get_date_interval_from_form {
                   3851:     my ($key) = @_;
                   3852:     my $seconds = 0;
                   3853:     foreach my $which (['days', 86400],
1.473     amueller 3854:                ['hours', 3600],
                   3855:                ['minutes', 60],
                   3856:                ['seconds',  1]) {
1.560     damieng  3857:         my ($name, $factor) = @{ $which };
                   3858:         if (defined($env{'form.'.$name.'_'.$key})) {
                   3859:             $seconds += $env{'form.'.$name.'_'.$key} * $factor;
                   3860:         }
1.473     amueller 3861:     }
1.560     damieng  3862:     if (($key =~ /\.interval$/) &&
                   3863:             (($env{'form.done_'.$key} eq '_done') || ($env{'form.done_'.$key} eq '_done_proctor'))) {
1.559     raeburn  3864:         if ($env{'form.done_'.$key.'_buttontext'}) {
                   3865:             $env{'form.done_'.$key.'_buttontext'} =~ s/\://g;
                   3866:             $seconds .= '_done:'.$env{'form.done_'.$key.'_buttontext'}.':';
                   3867:             if ($env{'form.done_'.$key} eq '_done_proctor') {
                   3868:                 $seconds .= '_proctor';
                   3869:             }
                   3870:         } else {
                   3871:             $seconds .= $env{'form.done_'.$key}; 
                   3872:         }
                   3873:         if (($env{'form.done_'.$key} eq '_done_proctor') && 
1.560     damieng  3874:                 ($env{'form.done_'.$key.'_proctorkey'})) {
1.558     raeburn  3875:             $seconds .= '_'.$env{'form.done_'.$key.'_proctorkey'};
                   3876:         }
1.554     raeburn  3877:     }
1.385     albertel 3878:     return $seconds;
                   3879: }
                   3880: 
                   3881: 
1.383     albertel 3882: sub default_selector {
1.552     raeburn  3883:     my ($thiskey, $showval, $readonly) = @_;
                   3884:     my $disabled;
                   3885:     if ($readonly) {
                   3886:         $disabled = ' disabled="disabled"';
                   3887:     }
                   3888:     return '<input type="text" name="set_'.$thiskey.'" value="'.$showval.'"'.$disabled.' />';
1.383     albertel 3889: }
                   3890: 
1.549     raeburn  3891: sub string_ip_selector {
1.552     raeburn  3892:     my ($thiskey, $showval, $readonly) = @_;
1.549     raeburn  3893:     my %access = (
                   3894:                    allow => [],
                   3895:                    deny  => [],
                   3896:                  );
                   3897:     if ($showval ne '') {
                   3898:         my @current;
                   3899:         if ($showval =~ /,/) {
                   3900:             @current = split(/,/,$showval);
                   3901:         } else {
                   3902:             @current = ($showval);
                   3903:         }
                   3904:         foreach my $item (@current) {
                   3905:             if ($item =~ /^\!([\[\]a-zA-Z\.\d\*\-]+)$/) {
                   3906:                 push(@{$access{'deny'}},$1);
                   3907:             } elsif ($item =~ /^([\[\]a-zA-Z\.\d\*\-]+)$/) {
                   3908:                 push(@{$access{'allow'}},$item);
                   3909:             }
                   3910:         }
                   3911:     }
                   3912:     if (!@{$access{'allow'}}) {
                   3913:         @{$access{'allow'}} = ('');
                   3914:     }
                   3915:     if (!@{$access{'deny'}}) {
                   3916:         @{$access{'deny'}} = ('');
                   3917:     }
1.552     raeburn  3918:     my ($disabled,$addmore);
                   3919:     if ($disabled) {
                   3920:         $disabled=' disabled="disabled"';
                   3921:     } else {
                   3922:         $addmore = "\n".'<button class="LC_add_ipacc_button">'.&mt('Add more').'</button>';
                   3923:     }
1.549     raeburn  3924:     my $output = '<input type="hidden" name="set_'.$thiskey.'" />
                   3925: <table><tr><th>'.&mt('Allow from').'</th><th>'.&mt('Deny from').'</th></tr><tr>';
                   3926:     foreach my $acctype ('allow','deny') {
                   3927:         $output .= '
                   3928: <td valign="top">
                   3929: <div class="LC_string_ipacc_wrap" id="LC_string_ipacc_'.$acctype.'_'.$thiskey.'">
                   3930:   <div class="LC_string_ipacc_inner">'."\n";
                   3931:         my $num = 0;
                   3932:         foreach my $curr (@{$access{$acctype}}) {
1.552     raeburn  3933:             $output .= '<div><input type="text" name="setip'.$acctype.'_'.$thiskey.'" value="'.$curr.'"'.$disabled.' />';
1.549     raeburn  3934:             if ($num > 0) {
                   3935:                 $output .= '<a href="#" class="LC_remove_ipacc">'.&mt('Remove').'</a>'; 
                   3936:             }
                   3937:             $output .= '</div>'."\n";
                   3938:             $num ++;
                   3939:         }
                   3940:         $output .= '
1.552     raeburn  3941:   </div>'.$addmore.'
1.549     raeburn  3942: </div>
                   3943: </td>';
                   3944:    }
                   3945:    $output .= '
                   3946: </tr>
                   3947: </table>'."\n";
                   3948:     return $output;
                   3949: }
                   3950: 
1.560     damieng  3951: 
                   3952: { # block using some constants related to parameter types (overview mode)
                   3953: 
1.446     bisitz   3954: my %strings =
1.383     albertel 3955:     (
                   3956:      'string_yesno'
                   3957:              => [[ 'yes', 'Yes' ],
1.560     damieng  3958:                  [ 'no', 'No' ]],
1.383     albertel 3959:      'string_problemstatus'
                   3960:              => [[ 'yes', 'Yes' ],
1.473     amueller 3961:          [ 'answer', 'Yes, and show correct answer if they exceed the maximum number of tries.' ],
                   3962:          [ 'no', 'No, don\'t show correct/incorrect feedback.' ],
                   3963:          [ 'no_feedback_ever', 'No, show no feedback at all.' ]],
1.504     raeburn  3964:      'string_questiontype'
                   3965:              => [[ 'problem', 'Standard Problem'],
                   3966:                  [ 'survey', 'Survey'],
                   3967:                  [ 'anonsurveycred', 'Anonymous Survey (credit for submission)'],
1.530     bisitz   3968:                  [ 'exam', 'Bubblesheet Exam'],
1.504     raeburn  3969:                  [ 'anonsurvey', 'Anonymous Survey'],
                   3970:                  [ 'randomizetry', 'New Randomization Each N Tries (default N=1)'],
                   3971:                  [ 'practice', 'Practice'],
                   3972:                  [ 'surveycred', 'Survey (credit for submission)']],
1.514     raeburn  3973:      'string_lenient'
                   3974:              => [['yes', 'Yes' ],
                   3975:                  [ 'no', 'No' ],
1.549     raeburn  3976:                  [ 'default', 'Default - only bubblesheet grading is lenient' ],
                   3977:                  [ 'weighted', 'Yes, weighted (optionresponse in checkbox mode)' ]],
1.521     raeburn  3978:      'string_discussvote'
                   3979:              => [['yes','Yes'],
                   3980:                  ['notended','Yes, unless discussion ended'],
                   3981:                  ['no','No']],
1.549     raeburn  3982:      'string_ip'
                   3983:              => [['_allowfrom_','Hostname(s), or IP(s) from which access is allowed'],
                   3984:                  ['_denyfrom_',], 'Hostname(s) or IP(s) from which access is disallowed'], 
1.383     albertel 3985:      );
                   3986: 
1.549     raeburn  3987: my %stringmatches = (
                   3988:          'string_lenient'
                   3989:               => [['weighted','^\-?[.\d]+,\-?[.\d]+,\-?[.\d]+,\-?[.\d]+$'],],
                   3990:          'string_ip'
                   3991:               => [['_allowfrom_','[^\!]+'],
                   3992:                   ['_denyfrom_','\!']],
                   3993:     );
                   3994: 
                   3995: my %stringtypes = (
                   3996:                     type         => 'string_questiontype',
                   3997:                     lenient      => 'string_lenient',
                   3998:                     retrypartial => 'string_yesno',
                   3999:                     discussvote  => 'string_discussvote',
                   4000:                     examcode     => 'string_examcode',
                   4001:                     acc          => 'string_ip',
                   4002:                   );
                   4003: 
1.505     raeburn  4004: sub standard_string_options {
                   4005:     my ($string_type) = @_;
                   4006:     if (ref($strings{$string_type}) eq 'ARRAY') {
                   4007:         return $strings{$string_type};
                   4008:     }
                   4009:     return;
                   4010: }
1.383     albertel 4011: 
1.549     raeburn  4012: sub standard_string_matches {
                   4013:     my ($string_type) = @_;
                   4014:     if (ref($stringmatches{$string_type}) eq 'ARRAY') {
                   4015:         return $stringmatches{$string_type};
                   4016:     }
                   4017:     return;
                   4018: }
                   4019: 
                   4020: sub get_stringtype {
                   4021:     my ($name) = @_;
                   4022:     if (exists($stringtypes{$name})) {
                   4023:         return $stringtypes{$name};
                   4024:     }
                   4025:     return;
                   4026: }
                   4027: 
1.383     albertel 4028: sub string_selector {
1.552     raeburn  4029:     my ($thistype, $thiskey, $showval, $name, $readonly) = @_;
1.446     bisitz   4030: 
1.383     albertel 4031:     if (!exists($strings{$thistype})) {
1.552     raeburn  4032:         return &default_selector($thiskey,$showval,$readonly);
1.383     albertel 4033:     }
                   4034: 
1.504     raeburn  4035:     my %skiptype;
1.514     raeburn  4036:     if (($thistype eq 'string_questiontype') || 
1.560     damieng  4037:             ($thistype eq 'string_lenient') ||
                   4038:             ($thistype eq 'string_discussvote') ||
                   4039:             ($thistype eq 'string_ip') ||
                   4040:             ($name eq 'retrypartial')) {
1.504     raeburn  4041:         my ($got_chostname,$chostname,$cmajor,$cminor); 
                   4042:         foreach my $possibilities (@{ $strings{$thistype} }) {
                   4043:             next unless (ref($possibilities) eq 'ARRAY');
1.514     raeburn  4044:             my ($parmval, $description) = @{ $possibilities };
1.549     raeburn  4045:             my $parmmatch;
                   4046:             if (ref($stringmatches{$thistype}) eq 'ARRAY') {
                   4047:                 foreach my $item (@{$stringmatches{$thistype}}) {
                   4048:                     if (ref($item) eq 'ARRAY') {
                   4049:                         if ($parmval eq $item->[0]) {
                   4050:                             $parmmatch = $parmval;
                   4051:                             $parmval = '';
                   4052:                             last;
                   4053:                         }
                   4054:                     }
                   4055:                 }
                   4056:             }
                   4057:             my $needsrelease=$Apache::lonnet::needsrelease{"parameter:$name:$parmval:$parmmatch"}; 
1.504     raeburn  4058:             if ($needsrelease) {
                   4059:                 unless ($got_chostname) {
1.514     raeburn  4060:                     ($chostname,$cmajor,$cminor)=&parameter_release_vars();
1.504     raeburn  4061:                     $got_chostname = 1;
                   4062:                 }
1.557     raeburn  4063:                 my $needsnewer=&parameter_releasecheck($name,$parmval,$parmmatch,undef,
1.549     raeburn  4064:                                                        $needsrelease,$cmajor,$cminor);
1.504     raeburn  4065:                 if ($needsnewer) {
1.549     raeburn  4066:                     if ($parmmatch ne '') {
                   4067:                         $skiptype{$parmmatch} = 1;
                   4068:                     } elsif ($parmval ne '') {
                   4069:                         $skiptype{$parmval} = 1;
                   4070:                     }
1.504     raeburn  4071:                 }
                   4072:             }
                   4073:         }
                   4074:     }
1.549     raeburn  4075: 
                   4076:     if ($thistype eq 'string_ip') {
1.552     raeburn  4077:         return &string_ip_selector($thiskey,$showval,$readonly); 
1.549     raeburn  4078:     }
1.504     raeburn  4079: 
1.552     raeburn  4080:     my ($result,$disabled);
                   4081: 
                   4082:     if ($readonly) {
                   4083:         $disabled = ' disabled="disabled"';
                   4084:     }
1.504     raeburn  4085:     my $numinrow = 3;
                   4086:     if ($thistype eq 'string_problemstatus') {
                   4087:         $numinrow = 2;
                   4088:     } elsif ($thistype eq 'string_questiontype') {
                   4089:         if (keys(%skiptype) > 0) {
                   4090:              $numinrow = 4;
                   4091:         }
                   4092:     }
                   4093:     my $rem;
                   4094:     if (ref($strings{$thistype}) eq 'ARRAY') {
                   4095:         my $i=0;
                   4096:         foreach my $possibilities (@{ $strings{$thistype} }) {
                   4097:             next unless (ref($possibilities) eq 'ARRAY');
                   4098:             my ($name, $description) = @{ $possibilities };
1.549     raeburn  4099:             next if ($skiptype{$name});
1.504     raeburn  4100:             $rem = $i%($numinrow);
                   4101:             if ($rem == 0) {
                   4102:                 if ($i > 0) {
                   4103:                     $result .= '</tr>';
                   4104:                 }
                   4105:                 $result .= '<tr>';
                   4106:             }
1.549     raeburn  4107:             my $colspan;
                   4108:             if ($i == @{ $strings{$thistype} }-1) {
                   4109:                 $rem = @{ $strings{$thistype} }%($numinrow);
                   4110:                 if ($rem) {
                   4111:                     my $colsleft = $numinrow - $rem;
                   4112:                     if ($colsleft) {
                   4113:                         $colspan = $colsleft+1;
                   4114:                         $colspan = ' colspan="'.$colspan.'"';
                   4115:                     }
                   4116:                 }
                   4117:             }
                   4118:             my ($add,$onchange,$css_class);
                   4119:             if ($thistype eq 'string_lenient') {
                   4120:                 if ($name eq 'weighted') {
                   4121:                     my $display;
                   4122:                     my %relatives = &Apache::lonlocal::texthash(
                   4123:                                         corrchkd     => 'Correct (checked)',
                   4124:                                         corrunchkd   => 'Correct (unchecked)',
                   4125:                                         incorrchkd   => 'Incorrect (checked)',
                   4126:                                         incorrunchkd => 'Incorrect (unchecked)',
                   4127:                     );
                   4128:                     my %textval = (
                   4129:                                     corrchkd     => '1.0',
                   4130:                                     corrunchkd   => '1.0',
                   4131:                                     incorrchkd   => '0.0',
                   4132:                                     incorrunchkd => '0.0',
                   4133:                     );
                   4134:                     if ($showval =~ /^([\-\d\.]+)\,([\-\d\.]+)\,([\-\d\.]+)\,([\-\d\.]+)$/) {
                   4135:                         $textval{'corrchkd'} = $1;
                   4136:                         $textval{'corrunchkd'} = $2;
                   4137:                         $textval{'incorrchkd'} = $3;
                   4138:                         $textval{'incorrunchkd'} = $4;
                   4139:                         $display = 'inline';
                   4140:                         $showval = $name;
                   4141:                     } else {
                   4142:                         $display = 'none';
                   4143:                     }
                   4144:                     $add = ' <div id="LC_parmtext_'.$thiskey.'" style="display:'.$display.'"><table>'.
                   4145:                            '<tr><th colspan="2">'.&mt("Foil's submission status").'</th><th>'.&mt('Points').'</th></tr>';  
                   4146:                     foreach my $reltype ('corrchkd','corrunchkd','incorrchkd','incorrunchkd') {
                   4147:                         $add .= '<tr><td>&nbsp;</td><td>'.$relatives{$reltype}.'</td>'."\n".
                   4148:                                 '<td><input type="text" name="settext_'.$thiskey.'"'.
1.552     raeburn  4149:                                 ' value="'.$textval{$reltype}.'" size="3"'.$disabled.' />'.
1.549     raeburn  4150:                                 '</td></tr>';
                   4151:                     }
                   4152:                     $add .= '</table></div>'."\n";
                   4153:                 }
                   4154:                 $onchange = ' onclick="javascript:toggleParmTextbox(this.form,'."'$thiskey'".');"';
                   4155:                 $css_class = ' class="LC_lenient_radio"';
                   4156:             }
                   4157:             $result .= '<td class="LC_left_item"'.$colspan.'>'.
1.504     raeburn  4158:                        '<span class="LC_nobreak"><label>'.
                   4159:                        '<input type="radio" name="set_'.$thiskey.
1.552     raeburn  4160:                        '" value="'.$name.'"'.$onchange.$css_class.$disabled;
1.504     raeburn  4161:             if ($showval eq $name) {
                   4162:                 $result .= ' checked="checked"';
                   4163:             }
1.549     raeburn  4164:             $result .= ' />'.&mt($description).'</label>'.$add.'</span></td>';
1.504     raeburn  4165:             $i++;
                   4166:         }
                   4167:         $result .= '</tr>';
1.473     amueller 4168:     }
1.504     raeburn  4169:     if ($result) {
                   4170:         $result = '<table border="0">'.$result.'</table>';
1.383     albertel 4171:     }
                   4172:     return $result;
                   4173: }
                   4174: 
1.554     raeburn  4175: my %intervals =
                   4176:     (
                   4177:      'date_interval'
                   4178:              => [[ 'done', 'Yes' ],
1.558     raeburn  4179:                  [ 'done_proctor', 'Yes, with proctor key'],                  
1.554     raeburn  4180:                  [ '', 'No' ]],
                   4181:     );
                   4182: 
                   4183: my %intervalmatches = (
                   4184:          'date_interval'
1.559     raeburn  4185:               => [['done','\d+_done(|\:[^\:]+\:)$'],
                   4186:                   ['done_proctor','\d+_done(|\:[^\:]+\:)_proctor_']],
1.554     raeburn  4187:     );
                   4188: 
                   4189: my %intervaltypes = (
                   4190:                       interval => 'date_interval',
                   4191:     );
                   4192: 
                   4193: sub standard_interval_matches {
                   4194:     my ($interval_type) = @_;
                   4195:     if (ref($intervalmatches{$interval_type}) eq 'ARRAY') {
                   4196:         return $intervalmatches{$interval_type};
                   4197:     }
                   4198:     return;
                   4199: }
                   4200: 
                   4201: sub get_intervaltype {
                   4202:     my ($name) = @_;
                   4203:     if (exists($intervaltypes{$name})) {
                   4204:         return $intervaltypes{$name};
                   4205:     }
                   4206:     return;
                   4207: }
                   4208: 
                   4209: sub standard_interval_options {
                   4210:     my ($interval_type) = @_;
                   4211:     if (ref($intervals{$interval_type}) eq 'ARRAY') {
                   4212:         return $intervals{$interval_type};
                   4213:     }
                   4214:     return;
                   4215: }
                   4216: 
                   4217: sub date_interval_selector {
                   4218:     my ($thiskey, $name, $showval, $readonly) = @_;
                   4219:     my ($result,%skipval);
                   4220:     if ($name eq 'interval') {
                   4221:         my $intervaltype = &get_intervaltype($name);
                   4222:         my ($got_chostname,$chostname,$cmajor,$cminor);
                   4223:         foreach my $possibilities (@{ $intervals{$intervaltype} }) {
                   4224:             next unless (ref($possibilities) eq 'ARRAY');
                   4225:             my ($parmval, $description) = @{ $possibilities };
                   4226:             my $parmmatch;
                   4227:             if (ref($intervalmatches{$intervaltype}) eq 'ARRAY') {
                   4228:                 foreach my $item (@{$intervalmatches{$intervaltype}}) {
                   4229:                     if (ref($item) eq 'ARRAY') {
                   4230:                         if ($parmval eq $item->[0]) {
                   4231:                             $parmmatch = $parmval;
                   4232:                             $parmval = '';
                   4233:                             last;
                   4234:                         }
                   4235:                     }
                   4236:                 }
                   4237:             }
                   4238:             my $needsrelease=$Apache::lonnet::needsrelease{"parameter:$name:$parmval:$parmmatch"};
                   4239:             if ($needsrelease) {
                   4240:                 unless ($got_chostname) {
                   4241:                     ($chostname,$cmajor,$cminor)=&parameter_release_vars();
                   4242:                     $got_chostname = 1;
                   4243:                 }
1.557     raeburn  4244:                 my $needsnewer=&parameter_releasecheck($name,$parmval,$parmmatch,undef,
1.554     raeburn  4245:                                                        $needsrelease,$cmajor,$cminor);
                   4246:                 if ($needsnewer) {
                   4247:                     if ($parmmatch ne '') {
                   4248:                         $skipval{$parmmatch} = 1;
                   4249:                     } elsif ($parmval ne '') {
                   4250:                         $skipval{$parmval} = 1;
                   4251:                     }
                   4252:                 }
                   4253:             }
                   4254:         }
                   4255:     }
                   4256: 
                   4257:     my $currval = $showval;
                   4258:     foreach my $which (['days', 86400, 31],
                   4259:                ['hours', 3600, 23],
                   4260:                ['minutes', 60, 59],
                   4261:                ['seconds',  1, 59]) {
1.560     damieng  4262:         my ($name, $factor, $max) = @{ $which };
                   4263:         my $amount = int($showval/$factor);
                   4264:         $showval  %= $factor;
                   4265:         my %select = ((map {$_ => $_} (0..$max)),
                   4266:                 'select_form_order' => [0..$max]);
                   4267:         $result .= &Apache::loncommon::select_form($amount,$name.'_'.$thiskey,
                   4268:                             \%select,'',$readonly);
                   4269:         $result .= ' '.&mt($name);
1.554     raeburn  4270:     }
                   4271:     if ($name eq 'interval') {
                   4272:         unless ($skipval{'done'}) {
                   4273:             my $checkedon = '';
1.558     raeburn  4274:             my $checkedproc = '';
                   4275:             my $currproctorkey = '';
                   4276:             my $currprocdisplay = 'hidden';
1.559     raeburn  4277:             my $currdonetext = &mt('Done');
1.554     raeburn  4278:             my $checkedoff = ' checked="checked"';
1.559     raeburn  4279:             if ($currval =~ /^(?:\d+)_done$/) {
                   4280:                 $checkedon = ' checked="checked"';
                   4281:                 $checkedoff = '';
                   4282:             } elsif ($currval =~ /^(?:\d+)_done\:([^\:]+)\:$/) {
                   4283:                 $currdonetext = $1;
1.554     raeburn  4284:                 $checkedon = ' checked="checked"';
                   4285:                 $checkedoff = '';
1.558     raeburn  4286:             } elsif ($currval =~ /^(?:\d+)_done_proctor_(.+)$/) {
                   4287:                 $currproctorkey = $1;
                   4288:                 $checkedproc = ' checked="checked"';
                   4289:                 $checkedoff = '';
                   4290:                 $currprocdisplay = 'text';
1.559     raeburn  4291:             } elsif ($currval =~ /^(?:\d+)_done\:([^\:]+)\:_proctor_(.+)$/) {
                   4292:                 $currdonetext = $1;
                   4293:                 $currproctorkey = $2;
                   4294:                 $checkedproc = ' checked="checked"';
                   4295:                 $checkedoff = '';
                   4296:                 $currprocdisplay = 'text';
1.554     raeburn  4297:             }
1.558     raeburn  4298:             my $onclick = ' onclick="toggleSecret(this.form,'."'done_','$thiskey'".');"';
                   4299:             $result .= '<br /><span class="LC_nobreak">'.&mt('Include "done" button').
                   4300:                        '<label><input type="radio" value="" name="done_'.$thiskey.'"'.$checkedoff.$onclick.' />'.
                   4301:                        &mt('No').'</label>'.('&nbsp;'x2).
                   4302:                        '<label><input type="radio" value="_done" name="done_'.$thiskey.'"'.$checkedon.$onclick.' />'.
                   4303:                        &mt('Yes').'</label>'.('&nbsp;'x2).
                   4304:                        '<label><input type="radio" value="_done_proctor" name="done_'.$thiskey.'"'.$checkedproc.$onclick.' />'.
                   4305:                        &mt('Yes, with proctor key').'</label>'.
                   4306:                        '<input type="'.$currprocdisplay.'" id="done_'.$thiskey.'_proctorkey" '.
1.559     raeburn  4307:                        'name="done_'.$thiskey.'_proctorkey" value="'.&HTML::Entities::encode($currproctorkey,'"<>&').'" /></span><br />'.
                   4308:                        '<span class="LC_nobreak">'.&mt('Button text').': '.
                   4309:                        '<input type="text" name="done_'.$thiskey.'_buttontext" value="'.&HTML::Entities::encode($currdonetext,'"<>&').'" /></span>';
1.554     raeburn  4310:         }
                   4311:     }
                   4312:     unless ($readonly) {
                   4313:         $result .= '<input type="hidden" name="dateinterval_'.$thiskey.'" />';
                   4314:     }
                   4315:     return $result;
                   4316: }
                   4317: 
1.549     raeburn  4318: sub oldversion_warning {
1.557     raeburn  4319:     my ($name,$namematch,$value,$chostname,$cmajor,$cminor,$needsrelease) = @_;
                   4320:     my $standard_name = &standard_parameter_names($name);
                   4321:     if ($namematch) {
                   4322:         my $level = &standard_parameter_levels($namematch);
                   4323:         my $msg = '';
                   4324:         if ($level) {
                   4325:             $msg = &mt('[_1] was [_2]not[_3] set at the level of: [_4].',
                   4326:                        $standard_name,'<b>','</b>','"'.$level.'"');
                   4327:         } else {
                   4328:             $msg = &mt('[_1] was [_2]not[_3] set.',
                   4329:                       $standard_name,'<b>','</b>');
                   4330:         }
                   4331:         return '<p class="LC_warning">'.$msg.'<br />'.
                   4332:                &mt('LON-CAPA version ([_1]) installed on home server ([_2]) does not meet version requirements ([_3] or newer).',
                   4333:                    $cmajor.'.'.$cminor,$chostname,
                   4334:                    $needsrelease).
                   4335:                    '</p>';
                   4336:     }
1.549     raeburn  4337:     my $desc;
                   4338:     my $stringtype = &get_stringtype($name);
                   4339:     if ($stringtype ne '') {
                   4340:         if ($name eq 'examcode') {
                   4341:             $desc = $value;
                   4342:         } elsif (ref($strings{$stringtypes{$name}}) eq 'ARRAY') {
                   4343:             foreach my $possibilities (@{ $strings{$stringtypes{$name}} }) {
                   4344:                 next unless (ref($possibilities) eq 'ARRAY');
                   4345:                 my ($parmval, $description) = @{ $possibilities };
                   4346:                 my $parmmatch;
                   4347:                 if (ref($stringmatches{$stringtypes{$name}}) eq 'ARRAY') {
                   4348:                     foreach my $item (@{$stringmatches{$stringtypes{$name}}}) {
                   4349:                         if (ref($item) eq 'ARRAY') {
                   4350:                             my ($regexpname,$pattern) = @{$item};
                   4351:                             if ($parmval eq $regexpname) {
                   4352:                                 if ($value =~ /$pattern/) {
                   4353:                                     $desc = $description; 
                   4354:                                     $parmmatch = 1;
                   4355:                                     last;
                   4356:                                 }
                   4357:                             }
                   4358:                         }
                   4359:                     }
                   4360:                     last if ($parmmatch);
                   4361:                 } elsif ($parmval eq $value) {
                   4362:                     $desc = $description;
                   4363:                     last;
                   4364:                 }
                   4365:             }
                   4366:         }
                   4367:     } elsif (($name eq 'printstartdate') || ($name eq 'printenddate')) {
                   4368:         my $now = time;
                   4369:         if ($value =~ /^\d+$/) {
                   4370:             if ($name eq 'printstartdate') {
                   4371:                 if ($value > $now) {
                   4372:                     $desc = &Apache::lonlocal::locallocaltime($value);
                   4373:                 }
                   4374:             } elsif ($name eq 'printenddate') {
                   4375:                 if ($value < $now) {
                   4376:                     $desc = &Apache::lonlocal::locallocaltime($value);
                   4377:                 }
                   4378:             }
                   4379:         }
                   4380:     }
                   4381:     return '<p class="LC_warning">'.
1.557     raeburn  4382:        &mt('[_1] was [_2]not[_3] set to [_4].',
                   4383:            $standard_name,'<b>','</b>','"'.$desc.'"').'<br />'.
                   4384:        &mt('LON-CAPA version ([_1]) installed on home server ([_2]) does not meet version requirements ([_3] or newer).',
                   4385:        $cmajor.'.'.$cminor,$chostname,
                   4386:        $needsrelease).
                   4387:        '</p>';
1.549     raeburn  4388: }
                   4389: 
1.560     damieng  4390: } # end of block using some constants related to parameter types
                   4391: 
1.549     raeburn  4392: 
1.389     www      4393: #
                   4394: # Shift all start and end dates by $shift
                   4395: #
                   4396: 
                   4397: sub dateshift {
                   4398:     my ($shift)=@_;
                   4399:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   4400:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
                   4401:     my %data=&Apache::lonnet::dump('resourcedata',$dom,$crs);
                   4402: # ugly retro fix for broken version of types
1.548     raeburn  4403:     foreach my $key (keys(%data)) {
1.389     www      4404:         if ($key=~/\wtype$/) {
                   4405:             my $newkey=$key;
                   4406:             $newkey=~s/type$/\.type/;
                   4407:             $data{$newkey}=$data{$key};
                   4408:             delete $data{$key};
                   4409:         }
                   4410:     }
1.391     www      4411:     my %storecontent=();
1.389     www      4412: # go through all parameters and look for dates
1.548     raeburn  4413:     foreach my $key (keys(%data)) {
1.389     www      4414:        if ($data{$key.'.type'}=~/^date_(start|end)$/) {
                   4415:           my $newdate=$data{$key}+$shift;
1.391     www      4416:           $storecontent{$key}=$newdate;
1.389     www      4417:        }
                   4418:     }
1.391     www      4419:     my $reply=&Apache::lonnet::cput
                   4420:                 ('resourcedata',\%storecontent,$dom,$crs);
                   4421:     if ($reply eq 'ok') {
                   4422:        &log_parmset(\%storecontent);
                   4423:     }
                   4424:     &Apache::lonnet::devalidatecourseresdata($crs,$dom);
                   4425:     return $reply;
1.389     www      4426: }
                   4427: 
1.208     www      4428: sub newoverview {
1.280     albertel 4429:     my ($r) = @_;
                   4430: 
1.208     www      4431:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   4432:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531     raeburn  4433:     my $crstype =  $env{'course.'.$env{'request.course.id'}.'.type'};
1.414     droeschl 4434:     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview',
1.473     amueller 4435:         text=>"Overview Mode"});
1.523     raeburn  4436: 
                   4437:     my %loaditems = (
1.549     raeburn  4438:                       'onload'   => "showHide_courseContent(); resize_scrollbox('mapmenuscroll','1','1'); showHideLenient();",
1.523     raeburn  4439:                     );
                   4440:     my $js = '
                   4441: <script type="text/javascript">
                   4442: // <![CDATA[
                   4443: '.
                   4444:             &Apache::lonhtmlcommon::resize_scrollbox_js('params')."\n".
                   4445:             &showhide_js()."\n".
1.549     raeburn  4446:             &toggleparmtextbox_js()."\n".
                   4447:             &validateparms_js()."\n".
                   4448:             &ipacc_boxes_js()."\n".
1.558     raeburn  4449:             &done_proctor_js()."\n".
1.523     raeburn  4450: '// ]]>
                   4451: </script>
                   4452: ';
1.549     raeburn  4453: 
1.523     raeburn  4454:     my $start_page = &Apache::loncommon::start_page('Set Parameters',$js,
                   4455:                                                     {'add_entries' => \%loaditems,});
1.298     albertel 4456:     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview');
1.507     www      4457:     $r->print($start_page.$breadcrumbs);
1.531     raeburn  4458:     &startSettingsScreen($r,'parmset',$crstype);
1.208     www      4459:     $r->print(<<ENDOVER);
1.549     raeburn  4460: <form method="post" action="/adm/parmset?action=newoverview" name="parmform" onsubmit="return validateParms();">
1.208     www      4461: ENDOVER
1.211     www      4462:     my @ids=();
                   4463:     my %typep=();
                   4464:     my %keyp=();
                   4465:     my %allparms=();
                   4466:     my %allparts=();
                   4467:     my %allmaps=();
                   4468:     my %mapp=();
                   4469:     my %symbp=();
                   4470:     my %maptitles=();
                   4471:     my %uris=();
                   4472:     my %keyorder=&standardkeyorder();
                   4473:     my %defkeytype=();
                   4474: 
                   4475:     my %alllevs=();
                   4476:     $alllevs{'Resource Level'}='full';
1.215     www      4477:     $alllevs{'Map/Folder Level'}='map';
1.211     www      4478:     $alllevs{'Course Level'}='general';
                   4479: 
                   4480:     my $csec=$env{'form.csec'};
1.269     raeburn  4481:     my $cgroup=$env{'form.cgroup'};
1.211     www      4482: 
                   4483:     my @pscat=&Apache::loncommon::get_env_multiple('form.pscat');
                   4484:     my $pschp=$env{'form.pschp'};
1.506     www      4485: 
1.211     www      4486:     my @psprt=&Apache::loncommon::get_env_multiple('form.psprt');
1.516     www      4487:     if (!@psprt) { $psprt[0]='all'; }
1.211     www      4488: 
1.446     bisitz   4489:     my @selected_sections =
1.473     amueller 4490:     &Apache::loncommon::get_env_multiple('form.Section');
1.211     www      4491:     @selected_sections = ('all') if (! @selected_sections);
1.374     albertel 4492:     foreach my $sec (@selected_sections) {
                   4493:         if ($sec eq 'all') {
1.211     www      4494:             @selected_sections = ('all');
                   4495:         }
                   4496:     }
1.552     raeburn  4497:     if ($env{'request.course.sec'} ne '') {
                   4498:         @selected_sections = ($env{'request.course.sec'});
                   4499:     }
1.269     raeburn  4500:     my @selected_groups =
                   4501:         &Apache::loncommon::get_env_multiple('form.Group');
1.211     www      4502: 
                   4503:     my $pssymb='';
                   4504:     my $parmlev='';
1.446     bisitz   4505: 
1.211     www      4506:     unless ($env{'form.parmlev'}) {
                   4507:         $parmlev = 'map';
                   4508:     } else {
                   4509:         $parmlev = $env{'form.parmlev'};
                   4510:     }
                   4511: 
1.446     bisitz   4512:     &extractResourceInformation(\@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allmaps,
1.473     amueller 4513:                 \%mapp, \%symbp,\%maptitles,\%uris,
                   4514:                 \%keyorder,\%defkeytype);
1.211     www      4515: 
1.374     albertel 4516:     if (grep {$_ eq 'all'} (@psprt)) {
1.481     amueller 4517:         @psprt = keys(%allparts);
1.374     albertel 4518:     }
1.211     www      4519: # Menu to select levels, etc
                   4520: 
1.456     bisitz   4521:     $r->print('<div class="LC_Box">');
1.445     neumanie 4522:     #$r->print('<h2 class="LC_hcell">Step 1</h2>');
1.452     bisitz   4523:     $r->print('<div>');
1.523     raeburn  4524:     $r->print(&Apache::lonhtmlcommon::start_pick_box(undef,'parmlevel'));
1.211     www      4525:     &levelmenu($r,\%alllevs,$parmlev);
                   4526:     if ($parmlev ne 'general') {
1.447     bisitz   4527:         $r->print(&Apache::lonhtmlcommon::row_closure());
1.483     amueller 4528:         &mapmenu($r,\%allmaps,$pschp,\%maptitles,\%symbp);
1.211     www      4529:     }
1.447     bisitz   4530:     $r->print(&Apache::lonhtmlcommon::row_closure(1));
1.445     neumanie 4531:     $r->print(&Apache::lonhtmlcommon::end_pick_box());
                   4532:     $r->print('</div></div>');
1.446     bisitz   4533: 
1.456     bisitz   4534:     $r->print('<div class="LC_Box">');
1.452     bisitz   4535:     $r->print('<div>');
1.510     www      4536:     &displaymenu($r,\%allparms,\@pscat,\%keyorder);
1.453     schualex 4537:     $r->print(&Apache::lonhtmlcommon::start_pick_box());
1.446     bisitz   4538:     $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parts to View')));
1.553     raeburn  4539:     my $sectionselector = &sectionmenu(\@selected_sections);
                   4540:     my $groupselector = &groupmenu(\@selected_groups);
1.481     amueller 4541:     $r->print('<table>'.
1.553     raeburn  4542:               '<tr><th>'.&mt('Parts').'</th>');
                   4543:     if ($sectionselector) {
                   4544:         $r->print('<th>'.&mt('Section(s)').'</th>');
                   4545:     }
                   4546:     if ($groupselector) {
                   4547:         $r->print('<th>'.&mt('Group(s)').'</th>');
                   4548:     }
                   4549:     $r->print('</tr><tr><td>');
1.211     www      4550:     &partmenu($r,\%allparts,\@psprt);
1.553     raeburn  4551:     $r->print('</td>');
                   4552:     if ($sectionselector) { 
                   4553:         $r->print('<td>'.$sectionselector.'</td>');
                   4554:     }
                   4555:     if ($groupselector) {
                   4556:         $r->print('<td>'.$groupselector.'</td>');
                   4557:     }
                   4558:     $r->print('</tr></table>');
1.447     bisitz   4559:     $r->print(&Apache::lonhtmlcommon::row_closure(1));
1.445     neumanie 4560:     $r->print(&Apache::lonhtmlcommon::end_pick_box());
                   4561:     $r->print('</div></div>');
                   4562: 
1.456     bisitz   4563:     $r->print('<div class="LC_Box">');
1.452     bisitz   4564:     $r->print('<div>');
1.214     www      4565:     my $sortorder=$env{'form.sortorder'};
                   4566:     unless ($sortorder) { $sortorder='realmstudent'; }
                   4567:     &sortmenu($r,$sortorder);
1.445     neumanie 4568:     $r->print('</div></div>');
1.446     bisitz   4569: 
1.214     www      4570:     $r->print('<p><input type="submit" name="dis" value="'.&mt('Display').'" /></p>');
1.446     bisitz   4571: 
1.211     www      4572: # Build the list data hash from the specified parms
                   4573: 
                   4574:     my $listdata;
                   4575:     %{$listdata}=();
                   4576: 
                   4577:     foreach my $cat (@pscat) {
1.269     raeburn  4578:         &secgroup_lister($cat,$pschp,$parmlev,$listdata,\@psprt,\@selected_sections,\%defkeytype,\%allmaps,\@ids,\%symbp);
                   4579:         &secgroup_lister($cat,$pschp,$parmlev,$listdata,\@psprt,\@selected_groups,\%defkeytype,\%allmaps,\@ids,\%symbp);
1.211     www      4580:     }
                   4581: 
1.212     www      4582:     if (($env{'form.store'}) || ($env{'form.dis'})) {
1.211     www      4583: 
1.481     amueller 4584:         if ($env{'form.store'}) { &storedata($r,$crs,$dom); }
1.211     www      4585: 
                   4586: # Read modified data
                   4587: 
1.481     amueller 4588:         my $resourcedata=&readdata($crs,$dom);
1.211     www      4589: 
                   4590: # List data
                   4591: 
1.552     raeburn  4592:         &listdata($r,$resourcedata,$listdata,$sortorder,'newoverview');
1.211     www      4593:     }
                   4594:     $r->print(&tableend().
1.473     amueller 4595:          ((($env{'form.store'}) || ($env{'form.dis'}))?'<p><input type="submit" name="store" value="'.&mt('Save').'" /></p>':'').
1.507     www      4596:           '</form>');
                   4597:     &endSettingsScreen($r);
                   4598:     $r->print(&Apache::loncommon::end_page());
1.208     www      4599: }
                   4600: 
1.269     raeburn  4601: sub secgroup_lister {
                   4602:     my ($cat,$pschp,$parmlev,$listdata,$psprt,$selections,$defkeytype,$allmaps,$ids,$symbp) = @_;
                   4603:     foreach my $item (@{$selections}) {
                   4604:         foreach my $part (@{$psprt}) {
                   4605:             my $rootparmkey=$env{'request.course.id'};
                   4606:             if (($item ne 'all') && ($item ne 'none') && ($item)) {
                   4607:                 $rootparmkey.='.['.$item.']';
                   4608:             }
                   4609:             if ($parmlev eq 'general') {
                   4610: # course-level parameter
                   4611:                 my $newparmkey=$rootparmkey.'.'.$part.'.'.$cat;
                   4612:                 $$listdata{$newparmkey}=1;
                   4613:                 $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
                   4614:             } elsif ($parmlev eq 'map') {
                   4615: # map-level parameter
1.548     raeburn  4616:                 foreach my $mapid (keys(%{$allmaps})) {
1.269     raeburn  4617:                     if (($pschp ne 'all') && ($pschp ne $mapid)) { next; }
                   4618:                     my $newparmkey=$rootparmkey.'.'.$$allmaps{$mapid}.'___(all).'.$part.'.'.$cat;
                   4619:                     $$listdata{$newparmkey}=1;
                   4620:                     $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
1.556     raeburn  4621:                     $newparmkey=$rootparmkey.'.'.$$allmaps{$mapid}.'___(rec).'.$part.'.'.$cat;
                   4622:                     $$listdata{$newparmkey}=1;
                   4623:                     $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
1.269     raeburn  4624:                 }
                   4625:             } else {
                   4626: # resource-level parameter
                   4627:                 foreach my $rid (@{$ids}) {
                   4628:                     my ($map,$resid,$url)=&Apache::lonnet::decode_symb($$symbp{$rid});
                   4629:                     if (($pschp ne 'all') && ($$allmaps{$pschp} ne $map)) { next; }
                   4630:                     my $newparmkey=$rootparmkey.'.'.$$symbp{$rid}.'.'.$part.'.'.$cat;
                   4631:                     $$listdata{$newparmkey}=1;
                   4632:                     $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
                   4633:                 }
                   4634:             }
                   4635:         }
                   4636:     }
                   4637: }
                   4638: 
1.560     damieng  4639: # Display all existing parameter settings.
1.208     www      4640: sub overview {
1.280     albertel 4641:     my ($r) = @_;
1.208     www      4642:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   4643:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531     raeburn  4644:     my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
1.549     raeburn  4645:     my $js = '<script type="text/javascript">'."\n".
                   4646:              '// <![CDATA['."\n".
                   4647:              &toggleparmtextbox_js()."\n".
                   4648:              &validateparms_js()."\n".
                   4649:              &ipacc_boxes_js()."\n".
1.558     raeburn  4650:              &done_proctor_js()."\n".
1.549     raeburn  4651:              '// ]]>'."\n".
                   4652:              '</script>'."\n";
1.414     droeschl 4653:     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview',
1.473     amueller 4654:     text=>"Overview Mode"});
1.549     raeburn  4655:     my %loaditems = (
                   4656:                       'onload'   => "showHideLenient();",
                   4657:                     );
                   4658: 
                   4659:     my $start_page=&Apache::loncommon::start_page('Modify Parameters',$js,{'add_entries' => \%loaditems,});
1.298     albertel 4660:     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview');
1.507     www      4661:     $r->print($start_page.$breadcrumbs);
1.531     raeburn  4662:     &startSettingsScreen($r,'parmset',$crstype);
1.549     raeburn  4663:     $r->print('<form method="post" action="/adm/parmset?action=setoverview" name="parmform" onsubmit="return validateParms();">');
1.507     www      4664: 
1.208     www      4665: # Store modified
                   4666: 
                   4667:     &storedata($r,$crs,$dom);
                   4668: 
                   4669: # Read modified data
                   4670: 
1.552     raeburn  4671:     my ($resourcedata,$classlist)=&readdata($crs,$dom);
1.208     www      4672: 
1.214     www      4673: 
                   4674:     my $sortorder=$env{'form.sortorder'};
                   4675:     unless ($sortorder) { $sortorder='realmstudent'; }
                   4676:     &sortmenu($r,$sortorder);
                   4677: 
1.208     www      4678: # List data
                   4679: 
1.552     raeburn  4680:     my $foundkeys=&listdata($r,$resourcedata,$resourcedata,$sortorder,'overview',$classlist);
1.145     www      4681:     $r->print(&tableend().'<p>'.
1.527     bisitz   4682:     ($foundkeys?'<input type="submit" value="'.&mt('Save').'" />':'<span class="LC_info">'.&mt('There are no parameters.').'</span>').'</p></form>'.
1.473     amueller 4683:           &Apache::loncommon::end_page());
1.120     www      4684: }
1.121     www      4685: 
1.560     damieng  4686: # Unused sub.
1.333     albertel 4687: sub clean_parameters {
                   4688:     my ($r) = @_;
                   4689:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   4690:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
                   4691: 
1.414     droeschl 4692:     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=cleanparameters',
1.473     amueller 4693:         text=>"Clean Parameters"});
1.333     albertel 4694:     my $start_page=&Apache::loncommon::start_page('Clean Parameters');
                   4695:     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Clean');
                   4696:     $r->print(<<ENDOVER);
                   4697: $start_page
                   4698: $breadcrumbs
                   4699: <form method="post" action="/adm/parmset?action=cleanparameters" name="parmform">
                   4700: ENDOVER
                   4701: # Store modified
                   4702: 
                   4703:     &storedata($r,$crs,$dom);
                   4704: 
                   4705: # Read modified data
                   4706: 
                   4707:     my $resourcedata=&readdata($crs,$dom);
                   4708: 
                   4709: # List data
                   4710: 
                   4711:     $r->print('<h3>'.
1.473     amueller 4712:           &mt('These parameters refer to resources that do not exist.').
                   4713:           '</h3>'.
                   4714:           '<input type="submit" value="'.&mt('Delete Selected').'" />'.'<br />'.
                   4715:           '<br />');
1.333     albertel 4716:     $r->print(&Apache::loncommon::start_data_table().
1.473     amueller 4717:           '<tr>'.
                   4718:           '<th>'.&mt('Delete').'</th>'.
                   4719:           '<th>'.&mt('Parameter').'</th>'.
                   4720:           '</tr>');
1.333     albertel 4721:     foreach my $thiskey (sort(keys(%{$resourcedata}))) {
1.560     damieng  4722:         next if (!exists($resourcedata->{$thiskey.'.type'})
                   4723:             && $thiskey=~/\.type$/);
                   4724:         my %data = &parse_key($thiskey);
                   4725:         if (1) { #exists($data{'realm_exists'})
                   4726:             #&& !$data{'realm_exists'}) {
                   4727:             $r->print(&Apache::loncommon::start_data_table_row().
                   4728:                 '<tr>'.
                   4729:                 '<td><input type="checkbox" name="del_'.$thiskey.'" /></td>'              );
                   4730: 
                   4731:             $r->print('<td>');
                   4732:             my $display_value = $resourcedata->{$thiskey};
                   4733:             if (&isdateparm($resourcedata->{$thiskey.'.type'})) {
                   4734:             $display_value =
                   4735:                 &Apache::lonlocal::locallocaltime($display_value);
                   4736:             }
1.470     raeburn  4737:             my $parmitem = &standard_parameter_names($data{'parameter_name'});
                   4738:             $parmitem = &mt($parmitem);
1.560     damieng  4739:             $r->print(&mt('Parameter: "[_1]" with value: "[_2]"',
                   4740:                 $parmitem,$resourcedata->{$thiskey}));
                   4741:             $r->print('<br />');
                   4742:             if ($data{'scope_type'} eq 'all') {
                   4743:                 $r->print(&mt('All users'));
                   4744:             } elsif ($data{'scope_type'} eq 'user') {
                   4745:                 $r->print(&mt('User: [_1]',join(':',@{$data{'scope'}})));
                   4746:             } elsif ($data{'scope_type'} eq 'section') {
                   4747:                 $r->print(&mt('Section: [_1]',$data{'scope'}));
                   4748:             } elsif ($data{'scope_type'} eq 'group') {
                   4749:                 $r->print(&mt('Group: [_1]',$data{'scope'}));
                   4750:             }
                   4751:             $r->print('<br />');
                   4752:             if ($data{'realm_type'} eq 'all') {
                   4753:                 $r->print(&mt('All Resources'));
                   4754:             } elsif ($data{'realm_type'} eq 'folder') {
                   4755:                 $r->print(&mt('Folder: [_1]'),$data{'realm'});
                   4756:             } elsif ($data{'realm_type'} eq 'symb') {
                   4757:             my ($map,$resid,$url) =
                   4758:                 &Apache::lonnet::decode_symb($data{'realm'});
                   4759:             $r->print(&mt('Resource: [_1]with ID: [_2]in folder [_3]',
                   4760:                         $url.' <br />&nbsp;&nbsp;&nbsp;',
                   4761:                         $resid.' <br />&nbsp;&nbsp;&nbsp;',$map));
                   4762:             }
                   4763:             $r->print(' <br />&nbsp;&nbsp;&nbsp;'.&mt('Part: [_1]',$data{'parameter_part'}));
                   4764:             $r->print('</td></tr>');
                   4765: 
1.473     amueller 4766:         }
1.333     albertel 4767:     }
                   4768:     $r->print(&Apache::loncommon::end_data_table().'<p>'.
1.473     amueller 4769:           '<input type="submit" value="'.&mt('Delete Selected').'" />'.
1.507     www      4770:           '</p></form>');
                   4771:     &endSettingsScreen($r);
                   4772:     $r->print(&Apache::loncommon::end_page());
1.333     albertel 4773: }
                   4774: 
1.560     damieng  4775: # Overview mode, UI to shift all dates.
1.390     www      4776: sub date_shift_one {
                   4777:     my ($r) = @_;
                   4778:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   4779:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531     raeburn  4780:     my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
1.390     www      4781: 
1.414     droeschl 4782:     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=dateshift1&timebase='.$env{'form.timebase'},
1.473     amueller 4783:         text=>"Shifting Dates"});
1.390     www      4784:     my $start_page=&Apache::loncommon::start_page('Shift Dates');
                   4785:     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Shift');
1.507     www      4786:     $r->print($start_page.$breadcrumbs);
1.531     raeburn  4787:     &startSettingsScreen($r,'parmset',$crstype);
1.538     bisitz   4788:     $r->print('<form name="shiftform" method="post" action="">'.
1.390     www      4789:               '<table><tr><td>'.&mt('Currently set date:').'</td><td>'.
                   4790:               &Apache::lonlocal::locallocaltime($env{'form.timebase'}).'</td></tr>'.
                   4791:               '<tr><td>'.&mt('Shifted date:').'</td><td>'.
1.541     bisitz   4792:                     &Apache::lonhtmlcommon::date_setter('shiftform',
1.390     www      4793:                                                         'timeshifted',
                   4794:                                                         $env{'form.timebase'},,
                   4795:                                                         '').
                   4796:               '</td></tr></table>'.
                   4797:               '<input type="hidden" name="action" value="dateshift2" />'.
                   4798:               '<input type="hidden" name="timebase" value="'.$env{'form.timebase'}.'" />'.
                   4799:               '<input type="submit" value="'.&mt('Shift all dates accordingly').'" /></form>');
1.507     www      4800:     &endSettingsScreen($r);
1.390     www      4801:     $r->print(&Apache::loncommon::end_page());
                   4802: }
                   4803: 
1.560     damieng  4804: # Overview mode, UI to shift all dates (second form).
1.390     www      4805: sub date_shift_two {
                   4806:     my ($r) = @_;
                   4807:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   4808:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531     raeburn  4809:     my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
1.414     droeschl 4810:     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=dateshift1&timebase='.$env{'form.timebase'},
1.473     amueller 4811:         text=>"Shifting Dates"});
1.390     www      4812:     my $start_page=&Apache::loncommon::start_page('Shift Dates');
                   4813:     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Shift');
1.507     www      4814:     $r->print($start_page.$breadcrumbs);
1.531     raeburn  4815:     &startSettingsScreen($r,'parmset',$crstype);
1.390     www      4816:     my $timeshifted=&Apache::lonhtmlcommon::get_date_from_form('timeshifted');
1.543     bisitz   4817:     $r->print('<h2>'.&mt('Shift Dates').'</h2>'.
                   4818:               '<p>'.&mt('Shifting all dates such that [_1] becomes [_2]',
1.390     www      4819:               &Apache::lonlocal::locallocaltime($env{'form.timebase'}),
1.543     bisitz   4820:               &Apache::lonlocal::locallocaltime($timeshifted)).'</p>');
1.390     www      4821:     my $delta=$timeshifted-$env{'form.timebase'};
                   4822:     &dateshift($delta);
1.543     bisitz   4823:     $r->print(
                   4824:         &Apache::lonhtmlcommon::confirm_success(&mt('Done')).
                   4825:         '<br /><br />'.
                   4826:         &Apache::lonhtmlcommon::actionbox(
                   4827:             ['<a href="/adm/parmset">'.&mt('Content and Problem Settings').'</a>']));
1.507     www      4828:     &endSettingsScreen($r);
1.390     www      4829:     $r->print(&Apache::loncommon::end_page());
                   4830: }
                   4831: 
1.333     albertel 4832: sub parse_key {
                   4833:     my ($key) = @_;
                   4834:     my %data;
                   4835:     my ($middle,$part,$name)=
1.473     amueller 4836:     ($key=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s]+)\.(\w+)$/);
1.333     albertel 4837:     $data{'scope_type'} = 'all';
                   4838:     if ($middle=~/^\[(.*)\]/) {
1.560     damieng  4839:         $data{'scope'} = $1;
                   4840:         if ($data{'scope'}=~/^useropt\:($match_username)\:($match_domain)/) {
                   4841:             $data{'scope_type'} = 'user';
                   4842:             $data{'scope'} = [$1,$2];
                   4843:         } else {
                   4844:             #FIXME check for group scope
                   4845:             $data{'scope_type'} = 'section';
                   4846:         }
                   4847:         $middle=~s/^\[(.*)\]//;
1.333     albertel 4848:     }
                   4849:     $middle=~s/\.+$//;
                   4850:     $middle=~s/^\.+//;
                   4851:     $data{'realm_type'}='all';
                   4852:     if ($middle=~/^(.+)\_\_\_\(all\)$/) {
1.560     damieng  4853:         $data{'realm'} = $1;
                   4854:         $data{'realm_type'} = 'folder';
                   4855:         $data{'realm_title'} = &Apache::lonnet::gettitle($data{'realm'});
                   4856:         ($data{'realm_exists'}) = &Apache::lonnet::is_on_map($data{'realm'});
1.333     albertel 4857:     } elsif ($middle) {
1.560     damieng  4858:         $data{'realm'} = $middle;
                   4859:         $data{'realm_type'} = 'symb';
                   4860:         $data{'realm_title'} = &Apache::lonnet::gettitle($data{'realm'});
                   4861:         my ($map,$resid,$url) = &Apache::lonnet::decode_symb($data{'realm'});
                   4862:         $data{'realm_exists'} = &Apache::lonnet::symbverify($data{'realm'},$url);
1.333     albertel 4863:     }
1.446     bisitz   4864: 
1.333     albertel 4865:     $data{'parameter_part'} = $part;
                   4866:     $data{'parameter_name'} = $name;
                   4867: 
                   4868:     return %data;
                   4869: }
                   4870: 
1.239     raeburn  4871: 
1.416     jms      4872: sub header {
1.507     www      4873:     return &Apache::loncommon::start_page('Settings');
1.416     jms      4874: }
1.193     albertel 4875: 
                   4876: 
                   4877: 
1.560     damieng  4878: ##################################################
                   4879: # MAIN MENU
                   4880: ##################################################
                   4881: 
1.193     albertel 4882: sub print_main_menu {
                   4883:     my ($r,$parm_permission)=@_;
                   4884:     #
1.414     droeschl 4885:     $r->print(&header());
1.507     www      4886:     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Content and Problem Settings'));
1.531     raeburn  4887:     my $crstype = &Apache::loncommon::course_type();
                   4888:     my $lc_crstype = lc($crstype);
                   4889: 
                   4890:     &startSettingsScreen($r,'parmset',$crstype);
1.193     albertel 4891:     $r->print(<<ENDMAINFORMHEAD);
                   4892: <form method="post" enctype="multipart/form-data"
                   4893:       action="/adm/parmset" name="studentform">
                   4894: ENDMAINFORMHEAD
                   4895: #
1.195     albertel 4896:     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                   4897:     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
1.268     albertel 4898:     my $vgr  = &Apache::lonnet::allowed('vgr',$env{'request.course.id'});
1.366     albertel 4899:     my $mgr  = &Apache::lonnet::allowed('mgr',$env{'request.course.id'});
1.520     raeburn  4900:     my $dcm = &Apache::lonnet::allowed('dcm',$env{'request.course.id'});
                   4901:     if ((!$dcm) && ($env{'request.course.sec'} ne '')) {
                   4902:         $dcm = &Apache::lonnet::allowed('dcm',$env{'request.course.id'}.
                   4903:                                         '/'.$env{'request.course.sec'});
                   4904:     }
1.268     albertel 4905: 
1.193     albertel 4906:     my @menu =
1.507     www      4907:         ( { categorytitle=>"Content Settings for this $crstype",
1.473     amueller 4908:         items => [
                   4909:           { linktext => 'Portfolio Metadata',
                   4910:             url => '/adm/parmset?action=setrestrictmeta',
                   4911:             permission => $parm_permission,
1.477     raeburn  4912:             linktitle => "Restrict metadata for this $lc_crstype." ,
1.473     amueller 4913:             icon =>'contact-new.png'   ,
                   4914:             },
                   4915:           { linktext => 'Reset Student Access Times',
                   4916:             url => '/adm/helper/resettimes.helper',
                   4917:             permission => $mgr,
1.477     raeburn  4918:             linktitle => "Reset access times for folders/maps, resources or the $lc_crstype."  ,
1.473     amueller 4919:             icon => 'start-here.png'  ,
                   4920:             },
1.520     raeburn  4921:           { linktext => 'Blocking Communication/Resource Access',
                   4922:             url => '/adm/setblock',
                   4923:             permission => $dcm,
                   4924:             linktitle => 'Configure blocking of communication/collaboration and access to resources during an exam',
                   4925:             icon => 'comblock.png',
                   4926:             },
1.473     amueller 4927:           { linktext => 'Set Parameter Setting Default Actions',
                   4928:             url => '/adm/parmset?action=setdefaults',
                   4929:             permission => $parm_permission,
                   4930:             linktitle =>'Set default actions for parameters.'  ,
                   4931:             icon => 'folder-new.png'  ,
                   4932:             }]},
                   4933:       { categorytitle => 'New and Existing Parameter Settings for Resources',
                   4934:         items => [
                   4935:           { linktext => 'Edit Resource Parameters - Helper Mode',
                   4936:             url => '/adm/helper/parameter.helper',
                   4937:             permission => $parm_permission,
                   4938:             linktitle =>'Set/Modify resource parameters in helper mode.'  ,
                   4939:             icon => 'dialog-information.png'  ,
                   4940:             #help => 'Parameter_Helper',
                   4941:             },
                   4942:           { linktext => 'Edit Resource Parameters - Overview Mode',
                   4943:             url => '/adm/parmset?action=newoverview',
                   4944:             permission => $parm_permission,
                   4945:             linktitle =>'Set/Modify resource parameters in overview mode.'  ,
                   4946:             icon => 'edit-find.png'  ,
                   4947:             #help => 'Parameter_Overview',
                   4948:             },
                   4949:           { linktext => 'Edit Resource Parameters - Table Mode',
                   4950:             url => '/adm/parmset?action=settable',
                   4951:             permission => $parm_permission,
                   4952:             linktitle =>'Set/Modify resource parameters in table mode.'  ,
                   4953:             icon => 'edit-copy.png'  ,
                   4954:             #help => 'Table_Mode',
                   4955:             }]},
1.417     droeschl 4956:            { categorytitle => 'Existing Parameter Settings for Resources',
1.473     amueller 4957:          items => [
                   4958:           { linktext => 'Modify Resource Parameters - Overview Mode',
                   4959:             url => '/adm/parmset?action=setoverview',
                   4960:             permission => $parm_permission,
                   4961:             linktitle =>'Set/Modify existing resource parameters in overview mode.'  ,
                   4962:             icon => 'preferences-desktop-wallpaper.png'  ,
                   4963:             #help => 'Parameter_Overview',
                   4964:             },
                   4965:           { linktext => 'Change Log',
                   4966:             url => '/adm/parmset?action=parameterchangelog',
                   4967:             permission => $parm_permission,
1.477     raeburn  4968:             linktitle =>"View parameter and $lc_crstype blog posting/user notification change log."  ,
1.487     wenzelju 4969:             icon => 'document-properties.png',
1.473     amueller 4970:             }]}
1.193     albertel 4971:           );
1.414     droeschl 4972:     $r->print(&Apache::lonhtmlcommon::generate_menu(@menu));
1.539     raeburn  4973:     $r->print('</form>');
1.507     www      4974:     &endSettingsScreen($r);
1.539     raeburn  4975:     $r->print(&Apache::loncommon::end_page());
1.193     albertel 4976:     return;
                   4977: }
1.414     droeschl 4978: 
1.416     jms      4979: 
                   4980: 
1.560     damieng  4981: ##################################################
                   4982: # PORTFOLIO METADATA
                   4983: ##################################################
                   4984: 
1.252     banghart 4985: sub output_row {
1.347     banghart 4986:     my ($r, $field_name, $field_text, $added_flag) = @_;
1.252     banghart 4987:     my $output;
1.263     banghart 4988:     my $options=$env{'course.'.$env{'request.course.id'}.'.metadata.'.$field_name.'.options'};
                   4989:     my $values=$env{'course.'.$env{'request.course.id'}.'.metadata.'.$field_name.'.values'};
1.337     banghart 4990:     if (!defined($options)) {
1.254     banghart 4991:         $options = 'active,stuadd';
1.261     banghart 4992:         $values = '';
1.252     banghart 4993:     }
1.337     banghart 4994:     if (!($options =~ /deleted/)) {
                   4995:         my @options= ( ['active', 'Show to student'],
1.418     schafran 4996:                     ['stuadd', 'Provide text area for students to type metadata'],
1.351     banghart 4997:                     ['choices','Provide choices for students to select from']);
1.473     amueller 4998: #           ['onlyone','Student may select only one choice']);
1.337     banghart 4999:         if ($added_flag) {
                   5000:             push @options,['deleted', 'Delete Metadata Field'];
                   5001:         }
1.351     banghart 5002:        $output = &Apache::loncommon::start_data_table_row();
1.451     bisitz   5003:         $output .= '<td><strong>'.$field_text.':</strong></td>';
1.351     banghart 5004:         $output .= &Apache::loncommon::end_data_table_row();
1.337     banghart 5005:         foreach my $opt (@options) {
1.560     damieng  5006:             my $checked = ($options =~ m/$opt->[0]/) ? ' checked="checked" ' : '' ;
                   5007:             $output .= &Apache::loncommon::continue_data_table_row();
                   5008:             $output .= '<td>'.('&nbsp;' x 5).'<label>
                   5009:                     <input type="checkbox" name="'.
                   5010:                     $field_name.'_'.$opt->[0].'" value="yes"'.$checked.' />'.
                   5011:                     &mt($opt->[1]).'</label></td>';
                   5012:             $output .= &Apache::loncommon::end_data_table_row();
                   5013:         }
1.351     banghart 5014:         $output .= &Apache::loncommon::continue_data_table_row();
1.451     bisitz   5015:         $output .= '<td>'.('&nbsp;' x 10).'<input name="'.$field_name.'_values" type="text" value="'.$values.'" size="80" /></td>';
1.351     banghart 5016:         $output .= &Apache::loncommon::end_data_table_row();
                   5017:         my $multiple_checked;
                   5018:         my $single_checked;
                   5019:         if ($options =~ m/onlyone/) {
1.422     bisitz   5020:             $multiple_checked = '';
1.423     bisitz   5021:             $single_checked = ' checked="checked"';
1.351     banghart 5022:         } else {
1.423     bisitz   5023:             $multiple_checked = ' checked="checked"';
1.422     bisitz   5024:             $single_checked = '';
1.351     banghart 5025:         }
1.560     damieng  5026:         $output .= &Apache::loncommon::continue_data_table_row();
                   5027:         $output .= '<td>'.('&nbsp;' x 10).'
                   5028:                     <input type="radio" name="'.$field_name.'_onlyone" value="multiple"'.$multiple_checked .' />
                   5029:                     '.&mt('Student may select multiple choices from list').'</td>';
                   5030:         $output .= &Apache::loncommon::end_data_table_row();
                   5031:         $output .= &Apache::loncommon::continue_data_table_row();
                   5032:         $output .= '<td>'.('&nbsp;' x 10).'
                   5033:                     <input type="radio" name="'.$field_name.'_onlyone"  value="single"'.$single_checked.' />
                   5034:                     '.&mt('Student may select only one choice from list').'</td>';
                   5035:         $output .= &Apache::loncommon::end_data_table_row();
1.252     banghart 5036:     }
                   5037:     return ($output);
                   5038: }
1.416     jms      5039: 
                   5040: 
1.560     damieng  5041: # UI to order portfolio metadata fields.
1.340     banghart 5042: sub order_meta_fields {
                   5043:     my ($r)=@_;
                   5044:     my $idx = 1;
                   5045:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   5046:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531     raeburn  5047:     my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};;
1.341     banghart 5048:     $r->print(&Apache::loncommon::start_page('Order Metadata Fields'));
1.560     damieng  5049:     &Apache::lonhtmlcommon::add_breadcrumb(
                   5050:         {href=>'/adm/parmset?action=addmetadata',
1.473     amueller 5051:         text=>"Add Metadata Field"});
1.560     damieng  5052:     &Apache::lonhtmlcommon::add_breadcrumb(
                   5053:         {href=>"/adm/parmset?action=setrestrictmeta",
                   5054:         text=>"Restrict Metadata"},
                   5055:         {text=>"Order Metadata"});
1.345     banghart 5056:     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Order Metadata'));
1.531     raeburn  5057:     &startSettingsScreen($r,'parmset',$crstype);
1.340     banghart 5058:     if ($env{'form.storeorder'}) {
                   5059:         my $newpos = $env{'form.newpos'} - 1;
                   5060:         my $currentpos = $env{'form.currentpos'} - 1;
                   5061:         my @neworder = ();
1.548     raeburn  5062:         my @oldorder = split(/,/,$env{'course.'.$env{'request.course.id'}.'.metadata.addedorder'});
1.340     banghart 5063:         my $i;
1.341     banghart 5064:         if ($newpos > $currentpos) {
1.340     banghart 5065:         # moving stuff up
                   5066:             for ($i=0;$i<$currentpos;$i++) {
1.560     damieng  5067:                 $neworder[$i]=$oldorder[$i];
1.340     banghart 5068:             }
                   5069:             for ($i=$currentpos;$i<$newpos;$i++) {
1.560     damieng  5070:                 $neworder[$i]=$oldorder[$i+1];
1.340     banghart 5071:             }
                   5072:             $neworder[$newpos]=$oldorder[$currentpos];
                   5073:             for ($i=$newpos+1;$i<=$#oldorder;$i++) {
1.560     damieng  5074:                 $neworder[$i]=$oldorder[$i];
1.340     banghart 5075:             }
                   5076:         } else {
                   5077:         # moving stuff down
1.473     amueller 5078:             for ($i=0;$i<$newpos;$i++) {
                   5079:                 $neworder[$i]=$oldorder[$i];
                   5080:             }
                   5081:             $neworder[$newpos]=$oldorder[$currentpos];
                   5082:             for ($i=$newpos+1;$i<$currentpos+1;$i++) {
                   5083:                 $neworder[$i]=$oldorder[$i-1];
                   5084:             }
                   5085:             for ($i=$currentpos+1;$i<=$#oldorder;$i++) {
                   5086:                 $neworder[$i]=$oldorder[$i];
                   5087:             }
1.340     banghart 5088:         }
1.560     damieng  5089:         my $ordered_fields = join ",", @neworder;
1.343     banghart 5090:         my $put_result = &Apache::lonnet::put('environment',
1.560     damieng  5091:                         {'metadata.addedorder'=>$ordered_fields},$dom,$crs);
                   5092:         &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.metadata.addedorder' => $ordered_fields});
1.340     banghart 5093:     }
1.357     raeburn  5094:     my $fields = &get_added_meta_fieldnames($env{'request.course.id'});
1.341     banghart 5095:     my $ordered_fields;
1.548     raeburn  5096:     my @fields_in_order = split(/,/,$env{'course.'.$env{'request.course.id'}.'.metadata.addedorder'});
1.340     banghart 5097:     if (!@fields_in_order) {
                   5098:         # no order found, pick sorted order then create metadata.addedorder key.
1.548     raeburn  5099:         foreach my $key (sort(keys(%$fields))) {
1.340     banghart 5100:             push @fields_in_order, $key;
1.341     banghart 5101:             $ordered_fields = join ",", @fields_in_order;
1.340     banghart 5102:         }
1.341     banghart 5103:         my $put_result = &Apache::lonnet::put('environment',
1.446     bisitz   5104:                             {'metadata.addedorder'=>$ordered_fields},$dom,$crs);
                   5105:     }
1.340     banghart 5106:     $r->print('<table>');
                   5107:     my $num_fields = scalar(@fields_in_order);
                   5108:     foreach my $key (@fields_in_order) {
                   5109:         $r->print('<tr><td>');
                   5110:         $r->print('<form method="post" action="">');
1.537     bisitz   5111:         $r->print('<select name="newpos" onchange="this.form.submit()">');
1.340     banghart 5112:         for (my $i = 1;$i le $num_fields;$i ++) {
                   5113:             if ($i eq $idx) {
                   5114:                 $r->print('<option value="'.$i.'"  SELECTED>('.$i.')</option>');
                   5115:             } else {
                   5116:                 $r->print('<option value="'.$i.'">'.$i.'</option>');
                   5117:             }
                   5118:         }
                   5119:         $r->print('</select></td><td>');
                   5120:         $r->print('<input type="hidden" name="currentpos" value="'.$idx.'" />');
                   5121:         $r->print('<input type="hidden" name="storeorder" value="true" />');
                   5122:         $r->print('</form>');
                   5123:         $r->print($$fields{$key}.'</td></tr>');
                   5124:         $idx ++;
                   5125:     }
                   5126:     $r->print('</table>');
1.507     www      5127:     &endSettingsScreen($r);
1.340     banghart 5128:     return 'ok';
                   5129: }
1.416     jms      5130: 
                   5131: 
1.359     banghart 5132: sub continue {
                   5133:     my $output;
                   5134:     $output .= '<form action="" method="post">';
                   5135:     $output .= '<input type="hidden" name="action" value="setrestrictmeta" />';
                   5136:     $output .= '<input type="submit" value="Continue" />';
                   5137:     return ($output);
                   5138: }
1.416     jms      5139: 
                   5140: 
1.334     banghart 5141: sub addmetafield {
                   5142:     my ($r)=@_;
1.414     droeschl 5143:     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=addmetadata',
1.473     amueller 5144:         text=>"Add Metadata Field"});
1.334     banghart 5145:     $r->print(&Apache::loncommon::start_page('Add Metadata Field'));
                   5146:     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Add Metadata Field'));
1.335     banghart 5147:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   5148:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531     raeburn  5149:     my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
                   5150:     &startSettingsScreen($r,'parmset',$crstype);
1.339     banghart 5151:     if (exists($env{'form.undelete'})) {
1.358     banghart 5152:         my @meta_fields = &Apache::loncommon::get_env_multiple('form.undeletefield');
1.339     banghart 5153:         foreach my $meta_field(@meta_fields) {
                   5154:             my $options = $env{'course.'.$env{'request.course.id'}.'.metadata.'.$meta_field.'.options'};
                   5155:             $options =~ s/deleted//;
                   5156:             $options =~ s/,,/,/;
                   5157:             my $put_result = &Apache::lonnet::put('environment',
                   5158:                                         {'metadata.'.$meta_field.'.options'=>$options},$dom,$crs);
1.446     bisitz   5159: 
1.339     banghart 5160:             $r->print('Undeleted Metadata Field <strong>'.$env{'course.'.$env{'request.course.id'}.'.metadata.'.$meta_field.'.added'}."</strong> with result ".$put_result.'<br />');
                   5161:         }
1.359     banghart 5162:         $r->print(&continue());
1.339     banghart 5163:     } elsif (exists($env{'form.fieldname'})) {
1.335     banghart 5164:         my $meta_field = $env{'form.fieldname'};
                   5165:         my $display_field = $env{'form.fieldname'};
                   5166:         $meta_field =~ s/\W/_/g;
1.338     banghart 5167:         $meta_field =~ tr/A-Z/a-z/;
1.335     banghart 5168:         my $put_result = &Apache::lonnet::put('environment',
                   5169:                             {'metadata.'.$meta_field.'.values'=>"",
                   5170:                              'metadata.'.$meta_field.'.added'=>"$display_field",
                   5171:                              'metadata.'.$meta_field.'.options'=>""},$dom,$crs);
1.359     banghart 5172:         $r->print('Added new Metadata Field <strong>'.$env{'form.fieldname'}."</strong> with result ".$put_result.'<br />');
                   5173:         $r->print(&continue());
1.335     banghart 5174:     } else {
1.357     raeburn  5175:         my $fields = &get_deleted_meta_fieldnames($env{'request.course.id'});
1.339     banghart 5176:         if ($fields) {
                   5177:             $r->print('You may undelete previously deleted fields.<br />Check those you wish to undelete and click Undelete.<br />');
                   5178:             $r->print('<form method="post" action="">');
                   5179:             foreach my $key(keys(%$fields)) {
1.358     banghart 5180:                 $r->print('<input type="checkbox" name="undeletefield" value="'.$key.'" />'.$$fields{$key}.'<br /');
1.339     banghart 5181:             }
                   5182:             $r->print('<input type="submit" name="undelete" value="Undelete" />');
                   5183:             $r->print('</form>');
                   5184:         }
                   5185:         $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 5186:         $r->print('<input type="text" name="fieldname" /><br />');
                   5187:         $r->print('<input type="submit" value="Add Metadata Field" />');
1.334     banghart 5188:     }
1.361     albertel 5189:     $r->print('</form>');
1.507     www      5190:     &endSettingsScreen($r);
1.334     banghart 5191: }
1.416     jms      5192: 
                   5193: 
                   5194: 
1.560     damieng  5195: # Display or save portfolio metadata.
1.259     banghart 5196: sub setrestrictmeta {
1.240     banghart 5197:     my ($r)=@_;
1.242     banghart 5198:     my $next_meta;
1.244     banghart 5199:     my $output;
1.245     banghart 5200:     my $item_num;
1.246     banghart 5201:     my $put_result;
1.414     droeschl 5202:     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setrestrictmeta',
1.473     amueller 5203:         text=>"Restrict Metadata"});
1.280     albertel 5204:     $r->print(&Apache::loncommon::start_page('Restrict Metadata'));
1.298     albertel 5205:     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Restrict Metadata'));
1.240     banghart 5206:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   5207:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531     raeburn  5208:     my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
                   5209:     &startSettingsScreen($r,'parmset',$crstype);
1.259     banghart 5210:     my $key_base = $env{'course.'.$env{'request.course.id'}.'.'};
1.252     banghart 5211:     my $save_field = '';
1.259     banghart 5212:     if ($env{'form.restrictmeta'}) {
1.254     banghart 5213:         foreach my $field (sort(keys(%env))) {
1.252     banghart 5214:             if ($field=~m/^form.(.+)_(.+)$/) {
1.254     banghart 5215:                 my $options;
1.252     banghart 5216:                 my $meta_field = $1;
                   5217:                 my $meta_key = $2;
1.253     banghart 5218:                 if ($save_field ne $meta_field) {
1.252     banghart 5219:                     $save_field = $meta_field;
1.473     amueller 5220:                     if ($env{'form.'.$meta_field.'_stuadd'}) {
                   5221:                         $options.='stuadd,';
                   5222:                     }
                   5223:                     if ($env{'form.'.$meta_field.'_choices'}) {
                   5224:                         $options.='choices,';
                   5225:                     }
                   5226:                     if ($env{'form.'.$meta_field.'_onlyone'} eq 'single') {
                   5227:                         $options.='onlyone,';
                   5228:                     }
                   5229:                     if ($env{'form.'.$meta_field.'_active'}) {
                   5230:                         $options.='active,';
                   5231:                     }
                   5232:                     if ($env{'form.'.$meta_field.'_deleted'}) {
                   5233:                         $options.='deleted,';
                   5234:                     }
1.259     banghart 5235:                     my $name = $save_field;
1.560     damieng  5236:                     $put_result = &Apache::lonnet::put('environment',
                   5237:                         {'metadata.'.$meta_field.'.options'=>$options,
                   5238:                         'metadata.'.$meta_field.'.values'=>$env{'form.'.$meta_field.'_values'},
                   5239:                         },$dom,$crs);
1.252     banghart 5240:                 }
                   5241:             }
                   5242:         }
                   5243:     }
1.296     albertel 5244:     &Apache::lonnet::coursedescription($env{'request.course.id'},
1.473     amueller 5245:                        {'freshen_cache' => 1});
1.335     banghart 5246:     # Get the default metadata fields
1.258     albertel 5247:     my %metadata_fields = &Apache::lonmeta::fieldnames('portfolio');
1.335     banghart 5248:     # Now get possible added metadata fields
1.357     raeburn  5249:     my $added_metadata_fields = &get_added_meta_fieldnames($env{'request.course.id'});
1.346     banghart 5250:     my $row_alt = 1;
1.347     banghart 5251:     $output .= &Apache::loncommon::start_data_table();
1.258     albertel 5252:     foreach my $field (sort(keys(%metadata_fields))) {
1.265     banghart 5253:         if ($field ne 'courserestricted') {
1.346     banghart 5254:             $row_alt = $row_alt ? 0 : 1;
1.560     damieng  5255:             $output.= &output_row($r, $field, $metadata_fields{$field});
                   5256:         }
1.255     banghart 5257:     }
1.351     banghart 5258:     my $buttons = (<<ENDButtons);
                   5259:         <input type="submit" name="restrictmeta" value="Save" />
                   5260:         </form><br />
                   5261:         <form method="post" action="/adm/parmset?action=addmetadata" name="form1">
                   5262:         <input type="submit" name="restrictmeta" value="Add a Metadata Field" />
                   5263:         </form>
                   5264:         <br />
                   5265:         <form method="post" action="/adm/parmset?action=ordermetadata" name="form2">
                   5266:         <input type="submit" name="restrictmeta" value="Order Metadata Fields" />
                   5267: ENDButtons
1.337     banghart 5268:     my $added_flag = 1;
1.335     banghart 5269:     foreach my $field (sort(keys(%$added_metadata_fields))) {
1.346     banghart 5270:         $row_alt = $row_alt ? 0 : 1;
                   5271:         $output.= &output_row($r, $field, $$added_metadata_fields{$field},$added_flag, $row_alt);
1.335     banghart 5272:     }
1.347     banghart 5273:     $output .= &Apache::loncommon::end_data_table();
1.446     bisitz   5274:     $r->print(<<ENDenv);
1.259     banghart 5275:         <form method="post" action="/adm/parmset?action=setrestrictmeta" name="form">
1.244     banghart 5276:         $output
1.351     banghart 5277:         $buttons
1.340     banghart 5278:         </form>
1.244     banghart 5279: ENDenv
1.507     www      5280:     &endSettingsScreen($r);
1.280     albertel 5281:     $r->print(&Apache::loncommon::end_page());
1.240     banghart 5282:     return 'ok';
                   5283: }
1.416     jms      5284: 
                   5285: 
1.335     banghart 5286: sub get_added_meta_fieldnames {
1.357     raeburn  5287:     my ($cid) = @_;
1.335     banghart 5288:     my %fields;
                   5289:     foreach my $key(%env) {
1.357     raeburn  5290:         if ($key =~ m/\Q$cid\E\.metadata\.(.+)\.added$/) {
1.335     banghart 5291:             my $field_name = $1;
                   5292:             my ($display_field_name) = $env{$key};
                   5293:             $fields{$field_name} = $display_field_name;
                   5294:         }
                   5295:     }
                   5296:     return \%fields;
                   5297: }
1.416     jms      5298: 
                   5299: 
1.339     banghart 5300: sub get_deleted_meta_fieldnames {
1.357     raeburn  5301:     my ($cid) = @_;
1.339     banghart 5302:     my %fields;
                   5303:     foreach my $key(%env) {
1.357     raeburn  5304:         if ($key =~ m/\Q$cid\E\.metadata\.(.+)\.added$/) {
1.339     banghart 5305:             my $field_name = $1;
                   5306:             if ($env{'course.'.$env{'request.course.id'}.'.metadata.'.$field_name.'.options'} =~ m/deleted/) {
                   5307:                 my ($display_field_name) = $env{$key};
                   5308:                 $fields{$field_name} = $display_field_name;
                   5309:             }
                   5310:         }
                   5311:     }
                   5312:     return \%fields;
                   5313: }
1.560     damieng  5314: 
                   5315: 
                   5316: ##################################################
                   5317: # PARAMETER SETTINGS DEFAULT ACTIONS
                   5318: ##################################################
                   5319: 
                   5320: # UI to change parameter setting default actions
1.220     www      5321: sub defaultsetter {
1.280     albertel 5322:     my ($r) = @_;
                   5323: 
1.414     droeschl 5324:     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setdefaults',
1.473     amueller 5325:         text=>"Set Defaults"});
1.531     raeburn  5326:     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   5327:     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                   5328:     my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
1.446     bisitz   5329:     my $start_page =
1.531     raeburn  5330:         &Apache::loncommon::start_page('Parameter Setting Default Actions');
1.298     albertel 5331:     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Defaults');
1.507     www      5332:     $r->print($start_page.$breadcrumbs);
1.531     raeburn  5333:     &startSettingsScreen($r,'parmset',$crstype);
1.507     www      5334:     $r->print('<form method="post" action="/adm/parmset?action=setdefaults" name="defaultform">');
1.280     albertel 5335: 
1.221     www      5336:     my @ids=();
                   5337:     my %typep=();
                   5338:     my %keyp=();
                   5339:     my %allparms=();
                   5340:     my %allparts=();
                   5341:     my %allmaps=();
                   5342:     my %mapp=();
                   5343:     my %symbp=();
                   5344:     my %maptitles=();
                   5345:     my %uris=();
                   5346:     my %keyorder=&standardkeyorder();
                   5347:     my %defkeytype=();
                   5348: 
1.446     bisitz   5349:     &extractResourceInformation(\@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allmaps,
1.473     amueller 5350:                 \%mapp, \%symbp,\%maptitles,\%uris,
                   5351:                 \%keyorder,\%defkeytype);
1.224     www      5352:     if ($env{'form.storerules'}) {
1.560     damieng  5353:         my %newrules=();
                   5354:         my @delrules=();
                   5355:         my %triggers=();
                   5356:         foreach my $key (keys(%env)) {
1.225     albertel 5357:             if ($key=~/^form\.(\w+)\_action$/) {
1.560     damieng  5358:                 my $tempkey=$1;
                   5359:                 my $action=$env{$key};
1.226     www      5360:                 if ($action) {
1.560     damieng  5361:                     $newrules{$tempkey.'_action'}=$action;
                   5362:                     if ($action ne 'default') {
                   5363:                         my ($whichaction,$whichparm)=($action=~/^(.*\_)([^\_]+)$/);
                   5364:                         $triggers{$whichparm}.=$tempkey.':';
                   5365:                     }
                   5366:                     $newrules{$tempkey.'_type'}=$defkeytype{$tempkey};
                   5367:                     if (&isdateparm($defkeytype{$tempkey})) {
                   5368:                         $newrules{$tempkey.'_days'}=$env{'form.'.$tempkey.'_days'};
                   5369:                         $newrules{$tempkey.'_hours'}=$env{'form.'.$tempkey.'_hours'};
                   5370:                         $newrules{$tempkey.'_min'}=$env{'form.'.$tempkey.'_min'};
                   5371:                         $newrules{$tempkey.'_sec'}=$env{'form.'.$tempkey.'_sec'};
                   5372:                     } else {
                   5373:                         $newrules{$tempkey.'_value'}=$env{'form.'.$tempkey.'_value'};
                   5374:                         $newrules{$tempkey.'_triggervalue'}=$env{'form.'.$tempkey.'_triggervalue'};
                   5375:                     }
                   5376:                 } else {
                   5377:                     push(@delrules,$tempkey.'_action');
                   5378:                     push(@delrules,$tempkey.'_type');
                   5379:                     push(@delrules,$tempkey.'_hours');
                   5380:                     push(@delrules,$tempkey.'_min');
                   5381:                     push(@delrules,$tempkey.'_sec');
                   5382:                     push(@delrules,$tempkey.'_value');
                   5383:                 }
1.473     amueller 5384:             }
                   5385:         }
1.560     damieng  5386:         foreach my $key (keys(%allparms)) {
                   5387:             $newrules{$key.'_triggers'}=$triggers{$key};
1.473     amueller 5388:         }
1.560     damieng  5389:         &Apache::lonnet::put('parmdefactions',\%newrules,$cdom,$cnum);
                   5390:         &Apache::lonnet::del('parmdefactions',\@delrules,$cdom,$cnum);
                   5391:         &resetrulescache();
1.224     www      5392:     }
1.227     www      5393:     my %lt=&Apache::lonlocal::texthash('days' => 'Days',
1.473     amueller 5394:                        'hours' => 'Hours',
                   5395:                        'min' => 'Minutes',
                   5396:                        'sec' => 'Seconds',
                   5397:                        'yes' => 'Yes',
                   5398:                        'no' => 'No');
1.222     www      5399:     my @standardoptions=('','default');
                   5400:     my @standarddisplay=('',&mt('Default value when manually setting'));
                   5401:     my @dateoptions=('','default');
                   5402:     my @datedisplay=('',&mt('Default value when manually setting'));
                   5403:     foreach my $tempkey (&keysindisplayorder(\%allparms,\%keyorder)) {
1.560     damieng  5404:         unless ($tempkey) { next; }
                   5405:         push @standardoptions,'when_setting_'.$tempkey;
                   5406:         push @standarddisplay,&mt('Automatically set when setting ').$tempkey;
                   5407:         if (&isdateparm($defkeytype{$tempkey})) {
                   5408:             push @dateoptions,'later_than_'.$tempkey;
                   5409:             push @datedisplay,&mt('Automatically set later than ').$tempkey;
                   5410:             push @dateoptions,'earlier_than_'.$tempkey;
                   5411:             push @datedisplay,&mt('Automatically set earlier than ').$tempkey;
                   5412:         }
1.222     www      5413:     }
1.231     www      5414: $r->print(&mt('Manual setting rules apply to all interfaces.').'<br />'.
1.473     amueller 5415:       &mt('Automatic setting rules apply to table mode interfaces only.'));
1.318     albertel 5416:     $r->print("\n".&Apache::loncommon::start_data_table().
1.473     amueller 5417:           &Apache::loncommon::start_data_table_header_row().
                   5418:           "<th>".&mt('Rule for parameter').'</th><th>'.
                   5419:           &mt('Action').'</th><th>'.&mt('Value').'</th>'.
                   5420:           &Apache::loncommon::end_data_table_header_row());
1.221     www      5421:     foreach my $tempkey (&keysindisplayorder(\%allparms,\%keyorder)) {
1.560     damieng  5422:         unless ($tempkey) { next; }
                   5423:         $r->print("\n".&Apache::loncommon::start_data_table_row().
                   5424:             "<td>".$allparms{$tempkey}."\n<br />(".$tempkey.')</td><td>');
                   5425:         my $action=&rulescache($tempkey.'_action');
                   5426:         $r->print('<select name="'.$tempkey.'_action">');
                   5427:         if (&isdateparm($defkeytype{$tempkey})) {
                   5428:             for (my $i=0;$i<=$#dateoptions;$i++) {
                   5429:             if ($dateoptions[$i]=~/\_$tempkey$/) { next; }
                   5430:             $r->print("\n<option value='$dateoptions[$i]'".
                   5431:                 ($dateoptions[$i] eq $action?' selected="selected"':'').
                   5432:                 ">$datedisplay[$i]</option>");
                   5433:             }
                   5434:         } else {
                   5435:             for (my $i=0;$i<=$#standardoptions;$i++) {
                   5436:             if ($standardoptions[$i]=~/\_$tempkey$/) { next; }
                   5437:             $r->print("\n<option value='$standardoptions[$i]'".
                   5438:                 ($standardoptions[$i] eq $action?' selected="selected"':'').
                   5439:                 ">$standarddisplay[$i]</option>");
                   5440:             }
1.473     amueller 5441:         }
1.560     damieng  5442:         $r->print('</select>');
                   5443:         unless (&isdateparm($defkeytype{$tempkey})) {
                   5444:             $r->print("\n<br />".&mt('Triggering value(s) of other parameter (optional, comma-separated):').
                   5445:                 '<input type="text" size="20" name="'.$tempkey.'_triggervalue" value="'.&rulescache($tempkey.'_triggervalue').'" />');
1.473     amueller 5446:         }
1.560     damieng  5447:         $r->print("\n</td><td>\n");
1.222     www      5448: 
1.221     www      5449:         if (&isdateparm($defkeytype{$tempkey})) {
1.560     damieng  5450:             my $days=&rulescache($tempkey.'_days');
                   5451:             my $hours=&rulescache($tempkey.'_hours');
                   5452:             my $min=&rulescache($tempkey.'_min');
                   5453:             my $sec=&rulescache($tempkey.'_sec');
                   5454:             $r->print(<<ENDINPUTDATE);
                   5455:     <input name="$tempkey\_days" type="text" size="4" value="$days" />$lt{'days'}<br />
                   5456:     <input name="$tempkey\_hours" type="text" size="4" value="$hours" />$lt{'hours'}<br />
                   5457:     <input name="$tempkey\_min" type="text" size="4" value="$min" />$lt{'min'}<br />
                   5458:     <input name="$tempkey\_sec" type="text" size="4" value="$sec" />$lt{'sec'}
                   5459:     ENDINPUTDATE
                   5460:         } elsif ($defkeytype{$tempkey} eq 'string_yesno') {
                   5461:                 my $yeschecked='';
                   5462:                 my $nochecked='';
                   5463:                 if (&rulescache($tempkey.'_value') eq 'yes') { $yeschecked=' checked="checked"'; }
                   5464:                 if (&rulescache($tempkey.'_value') eq 'no') { $nochecked=' checked="checked"'; }
                   5465: 
                   5466:             $r->print(<<ENDYESNO);
                   5467:     <label><input type="radio" name="$tempkey\_value" value="yes"$yeschecked /> $lt{'yes'}</label><br />
                   5468:     <label><input type="radio" name="$tempkey\_value" value="no"$nochecked /> $lt{'no'}</label>
                   5469:     ENDYESNO
1.221     www      5470:         } else {
1.560     damieng  5471:             $r->print('<input type="text" size="20" name="'.$tempkey.'_value" value="'.&rulescache($tempkey.'_value').'" />');
                   5472:         }
1.318     albertel 5473:         $r->print('</td>'.&Apache::loncommon::end_data_table_row());
1.221     www      5474:     }
1.318     albertel 5475:     $r->print(&Apache::loncommon::end_data_table().
1.473     amueller 5476:           "\n".'<input type="submit" name="storerules" value="'.
1.507     www      5477:           &mt('Save').'" /></form>'."\n");
                   5478:     &endSettingsScreen($r);
                   5479:     $r->print(&Apache::loncommon::end_page());
1.220     www      5480:     return;
                   5481: }
1.193     albertel 5482: 
1.560     damieng  5483: ##################################################
                   5484: # PARAMETER CHANGES LOG
                   5485: ##################################################
                   5486: 
1.290     www      5487: sub components {
1.330     albertel 5488:     my ($key,$uname,$udom,$exeuser,$exedomain,$typeflag)=@_;
                   5489: 
                   5490:     if ($typeflag) {
1.560     damieng  5491:         $key=~s/\.type$//;
1.290     www      5492:     }
1.330     albertel 5493: 
                   5494:     my ($middle,$part,$name)=
1.560     damieng  5495:         ($key=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s]+)\.(\w+)$/);
1.291     www      5496:     my $issection;
1.330     albertel 5497: 
1.290     www      5498:     my $section=&mt('All Students');
                   5499:     if ($middle=~/^\[(.*)\]/) {
1.560     damieng  5500:         $issection=$1;
                   5501:         $section=&mt('Group/Section').': '.$issection;
                   5502:         $middle=~s/^\[(.*)\]//;
1.290     www      5503:     }
                   5504:     $middle=~s/\.+$//;
                   5505:     $middle=~s/^\.+//;
1.291     www      5506:     if ($uname) {
1.560     damieng  5507:         $section=&mt('User').": ".&Apache::loncommon::plainname($uname,$udom);
                   5508:         $issection='';
1.291     www      5509:     }
1.316     albertel 5510:     my $realm='<span class="LC_parm_scope_all">'.&mt('All Resources').'</span>';
1.446     bisitz   5511:     my $realmdescription=&mt('all resources');
1.556     raeburn  5512:     if ($middle=~/^(.+)\_\_\_\((all|rec)\)$/) {
                   5513:         my $mapurl = $1;
                   5514:         my $maplevel = $2;
                   5515:         my $leveltitle = &mt('Folder/Map');
                   5516:         if ($maplevel eq 'rec') {
                   5517:             $leveltitle = &mt('Recursive');
                   5518:         }
1.560     damieng  5519:         $realm='<span class="LC_parm_scope_folder">'.$leveltitle.
                   5520:             ': '.&Apache::lonnet::gettitle($mapurl).' <span class="LC_parm_folder"><br />('.
                   5521:             $mapurl.')</span></span>';
                   5522:         $realmdescription=&mt('folder').' '.&Apache::lonnet::gettitle($mapurl);
                   5523:     } elsif ($middle) {
                   5524:         my ($map,$id,$url)=&Apache::lonnet::decode_symb($middle);
                   5525:         $realm='<span class="LC_parm_scope_resource">'.&mt('Resource').
                   5526:             ': '.&Apache::lonnet::gettitle($middle).' <br /><span class="LC_parm_symb">('.$url.
                   5527:             ' in '.$map.' id: '.$id.')</span></span>';
                   5528:         $realmdescription=&mt('resource').' '.&Apache::lonnet::gettitle($middle);
1.290     www      5529:     }
1.291     www      5530:     my $what=$part.'.'.$name;
1.330     albertel 5531:     return ($realm,$section,$name,$part,
1.473     amueller 5532:         $what,$middle,$uname,$udom,$issection,$realmdescription);
1.290     www      5533: }
1.293     www      5534: 
1.328     albertel 5535: my %standard_parms;
1.469     raeburn  5536: my %standard_parms_types;
1.416     jms      5537: 
1.328     albertel 5538: sub load_parameter_names {
                   5539:     open(my $config,"<$Apache::lonnet::perlvar{'lonTabDir'}/packages.tab");
                   5540:     while (my $configline=<$config>) {
1.560     damieng  5541:         if ($configline !~ /\S/ || $configline=~/^\#/) { next; }
                   5542:         chomp($configline);
                   5543:         my ($short,$plain)=split(/:/,$configline);
                   5544:         my (undef,$name,$type)=split(/\&/,$short,3);
                   5545:         if ($type eq 'display') {
                   5546:             $standard_parms{$name} = $plain;
1.469     raeburn  5547:         } elsif ($type eq 'type') {
1.560     damieng  5548:                 $standard_parms_types{$name} = $plain;
1.469     raeburn  5549:         }
1.328     albertel 5550:     }
                   5551:     close($config);
                   5552:     $standard_parms{'int_pos'}      = 'Positive Integer';
                   5553:     $standard_parms{'int_zero_pos'} = 'Positive Integer or Zero';
                   5554: }
                   5555: 
1.292     www      5556: sub standard_parameter_names {
                   5557:     my ($name)=@_;
1.328     albertel 5558:     if (!%standard_parms) {
1.560     damieng  5559:         &load_parameter_names();
1.328     albertel 5560:     }
1.292     www      5561:     if ($standard_parms{$name}) {
1.560     damieng  5562:         return $standard_parms{$name};
1.446     bisitz   5563:     } else {
1.560     damieng  5564:         return $name;
1.292     www      5565:     }
                   5566: }
1.290     www      5567: 
1.469     raeburn  5568: sub standard_parameter_types {
                   5569:     my ($name)=@_;
                   5570:     if (!%standard_parms_types) {
                   5571:         &load_parameter_names();
                   5572:     }
                   5573:     if ($standard_parms_types{$name}) {
                   5574:         return $standard_parms_types{$name};
                   5575:     }
                   5576:     return;
                   5577: }
1.309     www      5578: 
1.557     raeburn  5579: sub standard_parameter_levels {
                   5580:     my ($name)=@_;
                   5581:     my %levels = (
                   5582:                     'resourcelevel'   => 'a single resource',
                   5583:                     'maplevel'        => 'the enclosing map/folder', 
                   5584:                     'maplevelrecurse' => 'the enclosing map/folder (recursive into sub-folders)',
                   5585:                     'courselevel'     => 'the general (course) level',
                   5586:                  );
                   5587:     if ($levels{$name}) {
                   5588:         return $levels{$name};
                   5589:     }
                   5590:     return;
                   5591: }
                   5592: 
1.560     damieng  5593: # Display log for parameter changes, blog postings, user notification changes.
1.285     albertel 5594: sub parm_change_log {
1.284     www      5595:     my ($r)=@_;
1.531     raeburn  5596:     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   5597:     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                   5598:     my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'}
1.414     droeschl 5599:     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=settable',
1.473     amueller 5600:     text=>"Parameter Change Log"});
1.522     raeburn  5601:     my $js = '<script type="text/javascript">'."\n".
                   5602:              '// <![CDATA['."\n".
                   5603:              &Apache::loncommon::display_filter_js('parmslog')."\n".
                   5604:              '// ]]>'."\n".
                   5605:              '</script>'."\n";
                   5606:     $r->print(&Apache::loncommon::start_page('Parameter Change Log',$js));
1.327     albertel 5607:     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Parameter Change Log'));
1.531     raeburn  5608:     &startSettingsScreen($r,'parmset',$crstype);
                   5609:     my %parmlog=&Apache::lonnet::dump('nohist_parameterlog',$cdom,$cnum);
1.311     albertel 5610: 
1.301     www      5611:     if ((keys(%parmlog))[0]=~/^error\:/) { undef(%parmlog); }
1.311     albertel 5612: 
1.522     raeburn  5613:     $r->print('<div class="LC_left_float">'.
                   5614:               '<fieldset><legend>'.&mt('Display of Changes').'</legend>'.
                   5615:               '<form action="/adm/parmset?action=parameterchangelog"
1.327     albertel 5616:                      method="post" name="parameterlog">');
1.446     bisitz   5617: 
1.311     albertel 5618:     my %saveable_parameters = ('show' => 'scalar',);
                   5619:     &Apache::loncommon::store_course_settings('parameter_log',
                   5620:                                               \%saveable_parameters);
                   5621:     &Apache::loncommon::restore_course_settings('parameter_log',
                   5622:                                                 \%saveable_parameters);
1.522     raeburn  5623:     $r->print(&Apache::loncommon::display_filter('parmslog').'&nbsp;'."\n".
                   5624:               '<input type="submit" value="'.&mt('Display').'" />'.
                   5625:               '</form></fieldset></div><br clear="all" />');
1.301     www      5626: 
1.531     raeburn  5627:     my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom);
1.301     www      5628:     $r->print(&Apache::loncommon::start_data_table().&Apache::loncommon::start_data_table_header_row().
1.473     amueller 5629:           '<th>'.&mt('Time').'</th><th>'.&mt('User').'</th><th>'.&mt('Extent').'</th><th>'.&mt('Users').'</th><th>'.
                   5630:           &mt('Parameter').'</th><th>'.&mt('Part').'</th><th>'.&mt('New Value').'</th><th>'.&mt('Announce').'</th>'.
                   5631:           &Apache::loncommon::end_data_table_header_row());
1.309     www      5632:     my $shown=0;
1.349     www      5633:     my $folder='';
                   5634:     if ($env{'form.displayfilter'} eq 'currentfolder') {
1.560     damieng  5635:         my $last='';
                   5636:         if (tie(my %hash,'GDBM_File',$env{'request.course.fn'}.'_symb.db',
                   5637:                 &GDBM_READER(),0640)) {
                   5638:             $last=$hash{'last_known'};
                   5639:             untie(%hash);
                   5640:         }
                   5641:         if ($last) { ($folder) = &Apache::lonnet::decode_symb($last); }
                   5642:     }
                   5643:     foreach my $id (sort {
                   5644:                 if ($parmlog{$b}{'exe_time'} ne $parmlog{$a}{'exe_time'}) {
                   5645:                     return $parmlog{$b}{'exe_time'} <=>$parmlog{$a}{'exe_time'}
                   5646:                 }
                   5647:                 my $aid = (split('00000',$a))[-1];
                   5648:                 my $bid = (split('00000',$b))[-1];
                   5649:                 return $bid<=>$aid;
1.473     amueller 5650:             } (keys(%parmlog))) {
1.294     www      5651:         my @changes=keys(%{$parmlog{$id}{'logentry'}});
1.560     damieng  5652:         my $count = 0;
                   5653:         my $time =
                   5654:             &Apache::lonlocal::locallocaltime($parmlog{$id}{'exe_time'});
                   5655:         my $plainname =
                   5656:             &Apache::loncommon::plainname($parmlog{$id}{'exe_uname'},
                   5657:                         $parmlog{$id}{'exe_udom'});
                   5658:         my $about_me_link =
                   5659:             &Apache::loncommon::aboutmewrapper($plainname,
                   5660:                             $parmlog{$id}{'exe_uname'},
                   5661:                             $parmlog{$id}{'exe_udom'});
                   5662:         my $send_msg_link='';
                   5663:         if ((($parmlog{$id}{'exe_uname'} ne $env{'user.name'})
                   5664:             || ($parmlog{$id}{'exe_udom'} ne $env{'user.domain'}))) {
                   5665:             $send_msg_link ='<br />'.
                   5666:             &Apache::loncommon::messagewrapper(&mt('Send message'),
                   5667:                             $parmlog{$id}{'exe_uname'},
                   5668:                             $parmlog{$id}{'exe_udom'});
                   5669:         }
                   5670:         my $row_start=&Apache::loncommon::start_data_table_row();
                   5671:         my $makenewrow=0;
                   5672:         my %istype=();
                   5673:         my $output;
                   5674:         foreach my $changed (reverse(sort(@changes))) {
                   5675:                 my $value=$parmlog{$id}{'logentry'}{$changed};
                   5676:             my $typeflag = ($changed =~/\.type$/ &&
                   5677:                     !exists($parmlog{$id}{'logentry'}{$changed.'.type'}));
1.330     albertel 5678:             my ($realm,$section,$parmname,$part,$what,$middle,$uname,$udom,$issection,$realmdescription)=
1.560     damieng  5679:                 &components($changed,$parmlog{$id}{'uname'},$parmlog{$id}{'udom'},undef,undef,$typeflag);
                   5680:             if ($env{'request.course.sec'} ne '') {
                   5681:                 next if (($issection ne '') && ($issection ne $env{'request.course.sec'}));
                   5682:                 if ($uname ne '') {
                   5683:                     my $stusection = &Apache::lonnet::getsection($uname,$udom,$env{'request.course.id'});
                   5684:                     next if (($stusection ne '-1') && ($stusection ne $env{'request.course.sec'})); 
                   5685:                 }
                   5686:             }
                   5687:             if ($env{'form.displayfilter'} eq 'currentfolder') {
                   5688:                 if ($folder) {
                   5689:                     if ($middle!~/^\Q$folder\E/) { next; }
                   5690:                 }
                   5691:             }
                   5692:             if ($typeflag) {
                   5693:                 $istype{$parmname}=$value;
                   5694:                 if (!$env{'form.includetypes'}) { next; }
                   5695:             }
                   5696:             $count++;
                   5697:             if ($makenewrow) {
                   5698:                 $output .= $row_start;
                   5699:             } else {
                   5700:                 $makenewrow=1;
                   5701:             }
1.470     raeburn  5702:             my $parmitem = &standard_parameter_names($parmname);
1.560     damieng  5703:             $output .='<td>'.$realm.'</td><td>'.$section.'</td><td>'.
                   5704:                 &mt($parmitem).'</td><td>'.
                   5705:                 ($part?&mt('Part: [_1]',$part):&mt('All Parts')).'</td><td>';
                   5706:             my $stillactive=0;
                   5707:             if ($parmlog{$id}{'delflag'}) {
                   5708:                 $output .= &mt('Deleted');
                   5709:             } else {
                   5710:                 if ($typeflag) {
1.470     raeburn  5711:                     my $parmitem = &standard_parameter_names($value); 
                   5712:                     $parmitem = &mt($parmitem);
1.560     damieng  5713:                     $output .= &mt('Type: [_1]',$parmitem);
                   5714:                 } else {
                   5715:                     my ($level,@all)=&parmval_by_symb($what,$middle,
                   5716:                         &Apache::lonnet::metadata($middle,$what),
                   5717:                         $uname,$udom,$issection,$issection,$courseopt);
1.469     raeburn  5718:                     my $showvalue = $value;
                   5719:                     if ($istype{$parmname} eq '') {
                   5720:                         my $type = &standard_parameter_types($parmname);
                   5721:                         if ($type ne '') {
                   5722:                             if (&isdateparm($type)) {
                   5723:                                 $showvalue =
                   5724:                                     &Apache::lonlocal::locallocaltime($value);
                   5725:                             }
                   5726:                         }
                   5727:                     } else {
1.560     damieng  5728:                         if (&isdateparm($istype{$parmname})) {
                   5729:                             $showvalue = &Apache::lonlocal::locallocaltime($value);
                   5730:                         }
1.469     raeburn  5731:                     }
                   5732:                     $output .= $showvalue;
1.560     damieng  5733:                     if ($value ne $all[$level]) {
                   5734:                         $output .= '<br /><span class="LC_warning">'.&mt('Not active anymore').'</span>';
                   5735:                     } else {
                   5736:                         $stillactive=1;
                   5737:                     }
                   5738:                 }
1.473     amueller 5739:             }
1.560     damieng  5740:             $output .= '</td><td>';
                   5741:                 
                   5742:             if ($stillactive) {
1.470     raeburn  5743:                 my $parmitem = &standard_parameter_names($parmname);
                   5744:                 $parmitem = &mt($parmitem);
1.560     damieng  5745:                 my $title=&mt('Changed [_1]',$parmitem);
1.471     raeburn  5746:                 my $description=&mt('Changed [_1] for [_2] to [_3]',
1.560     damieng  5747:                     $parmitem,$realmdescription,
1.473     amueller 5748:                     (&isdateparm($istype{$parmname})?&Apache::lonlocal::locallocaltime($value):$value));
1.560     damieng  5749:                 if (($uname) && ($udom)) {
                   5750:                     $output .=
                   5751:                     &Apache::loncommon::messagewrapper('Notify User',
                   5752:                                     $uname,$udom,$title,
                   5753:                                     $description);
                   5754:                 } else {
                   5755:                     $output .=
                   5756:                     &Apache::lonrss::course_blog_link($id,$title,
                   5757:                                     $description);
                   5758:                 }
                   5759:             }
                   5760:             $output .= '</td>'.&Apache::loncommon::end_data_table_row();
1.473     amueller 5761:         }
1.560     damieng  5762:         if ($env{'form.displayfilter'} eq 'containing') {
                   5763:             my $wholeentry=$about_me_link.':'.
                   5764:             $parmlog{$id}{'exe_uname'}.':'.$parmlog{$id}{'exe_udom'}.':'.
                   5765:             $output;
                   5766:             if ($wholeentry!~/\Q$env{'form.containingphrase'}\E/i) { next; }
1.473     amueller 5767:         }
1.349     www      5768:         if ($count) {
1.560     damieng  5769:             $r->print($row_start.'<td rowspan="'.$count.'">'.$time.'</td>
                   5770:                         <td rowspan="'.$count.'">'.$about_me_link.
                   5771:             '<br /><tt>'.$parmlog{$id}{'exe_uname'}.
                   5772:                         ':'.$parmlog{$id}{'exe_udom'}.'</tt>'.
                   5773:             $send_msg_link.'</td>'.$output);
                   5774:             $shown++;
                   5775:         }
                   5776:         if (!($env{'form.show'} eq &mt('all')
                   5777:             || $shown<=$env{'form.show'})) { last; }
1.286     www      5778:     }
1.301     www      5779:     $r->print(&Apache::loncommon::end_data_table());
1.507     www      5780:     &endSettingsScreen($r);
1.284     www      5781:     $r->print(&Apache::loncommon::end_page());
                   5782: }
                   5783: 
1.560     damieng  5784: ##################################################
                   5785: # MISC !
                   5786: ##################################################
                   5787: 
                   5788: # Used by table UI
1.437     raeburn  5789: sub update_slots {
                   5790:     my ($slot_name,$cdom,$cnum,$symb,$uname,$udom) = @_;
                   5791:     my %slot=&Apache::lonnet::get_slot($slot_name);
                   5792:     if (!keys(%slot)) {
                   5793:         return 'error: slot does not exist';
                   5794:     }
                   5795:     my $max=$slot{'maxspace'};
                   5796:     if (!defined($max)) { $max=99999; }
                   5797: 
                   5798:     my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
                   5799:                                        "^$slot_name\0");
                   5800:     my ($tmp)=%consumed;
                   5801:     if ($tmp=~/^error: 2 / ) {
                   5802:         return 'error: unable to determine current slot status';
                   5803:     }
                   5804:     my $last=0;
                   5805:     foreach my $key (keys(%consumed)) {
                   5806:         my $num=(split('\0',$key))[1];
                   5807:         if ($num > $last) { $last=$num; }
                   5808:         if ($consumed{$key}->{'name'} eq $uname.':'.$udom) {
                   5809:             return 'ok';
                   5810:         }
                   5811:     }
                   5812: 
                   5813:     if (scalar(keys(%consumed)) >= $max) {
                   5814:         return 'error: no space left in slot';
                   5815:     }
                   5816:     my $wanted=$last+1;
                   5817: 
                   5818:     my %reservation=('name'      => $uname.':'.$udom,
                   5819:                      'timestamp' => time,
                   5820:                      'symb'      => $symb);
                   5821: 
                   5822:     my $success=&Apache::lonnet::newput('slot_reservations',
                   5823:                                         {"$slot_name\0$wanted" =>
                   5824:                                              \%reservation},
                   5825:                                         $cdom, $cnum);
1.438     raeburn  5826:     if ($success eq 'ok') {
                   5827:         my %storehash = (
                   5828:                           symb    => $symb,
                   5829:                           slot    => $slot_name,
                   5830:                           action  => 'reserve',
                   5831:                           context => 'parameter',
                   5832:                         );
1.526     raeburn  5833:         &Apache::lonnet::write_log('course','slotreservationslog',\%storehash,
1.524     raeburn  5834:                                    '',$uname,$udom,$cnum,$cdom);
1.438     raeburn  5835: 
1.526     raeburn  5836:         &Apache::lonnet::write_log('course',$cdom.'_'.$cnum.'_slotlog',\%storehash,
1.524     raeburn  5837:                                    '',$uname,$udom,$uname,$udom);
1.438     raeburn  5838:     }
1.437     raeburn  5839:     return $success;
                   5840: }
                   5841: 
1.560     damieng  5842: # Used by table UI
1.437     raeburn  5843: sub delete_slots {
                   5844:     my ($slot_name,$cdom,$cnum,$uname,$udom,$symb) = @_;
                   5845:     my $delresult;
                   5846:     my %consumed = &Apache::lonnet::dump('slot_reservations',$cdom,
                   5847:                                          $cnum, "^$slot_name\0");
                   5848:     if (&Apache::lonnet::error(%consumed)) {
                   5849:         return 'error: unable to determine current slot status';
                   5850:     }
                   5851:     my ($tmp)=%consumed;
                   5852:     if ($tmp=~/^error: 2 /) {
                   5853:         return 'error: unable to determine current slot status';
                   5854:     }
                   5855:     foreach my $key (keys(%consumed)) {
                   5856:         if ($consumed{$key}->{'name'} eq $uname.':'.$udom) {
                   5857:             my $num=(split('\0',$key))[1];
                   5858:             my $entry = $slot_name.'\0'.$num;
                   5859:             $delresult = &Apache::lonnet::del('slot_reservations',[$entry],
                   5860:                                               $cdom,$cnum);
                   5861:             if ($delresult eq 'ok') {
                   5862:                 my %storehash = (
                   5863:                                   symb    => $symb,
                   5864:                                   slot    => $slot_name,
                   5865:                                   action  => 'release',
                   5866:                                   context => 'parameter',
                   5867:                                 );
1.526     raeburn  5868:                 &Apache::lonnet::write_log('course','slotreservationslog',\%storehash,
1.524     raeburn  5869:                                            1,$uname,$udom,$cnum,$cdom);
1.526     raeburn  5870:                 &Apache::lonnet::write_log('course',$cdom.'_'.$cnum.'_slotlog',\%storehash,
1.524     raeburn  5871:                                            1,$uname,$udom,$uname,$udom);
1.437     raeburn  5872:             }
                   5873:         }
                   5874:     }
                   5875:     return $delresult;
                   5876: }
                   5877: 
1.560     damieng  5878: # Used by handler
1.355     albertel 5879: sub check_for_course_info {
                   5880:     my $navmap = Apache::lonnavmaps::navmap->new();
                   5881:     return 1 if ($navmap);
                   5882:     return 0;
                   5883: }
                   5884: 
1.514     raeburn  5885: sub parameter_release_vars { 
1.504     raeburn  5886:    my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   5887:    my $chome = $env{'course.'.$env{'request.course.id'}.'.home'};
                   5888:    my $chostname = &Apache::lonnet::hostname($chome);
                   5889:    my ($cmajor,$cminor) = 
                   5890:        split(/\./,&Apache::lonnet::get_server_loncaparev($cdom,$chome));
                   5891:    return ($chostname,$cmajor,$cminor);
                   5892: }
                   5893: 
1.514     raeburn  5894: sub parameter_releasecheck {
1.557     raeburn  5895:     my ($name,$value,$valmatch,$namematch,$needsrelease,$cmajor,$cminor) = @_;
1.504     raeburn  5896:     my $needsnewer;
                   5897:     my ($needsmajor,$needsminor) = split(/\./,$needsrelease);
                   5898:     if (($cmajor < $needsmajor) || 
                   5899:         ($cmajor == $needsmajor && $cminor < $needsminor)) {
                   5900:         $needsnewer = 1;
1.557     raeburn  5901:     } elsif ($name) {
                   5902:         if ($valmatch) {
                   5903:             &Apache::lonnet::update_released_required($Apache::lonnet::needsrelease{'parameter:'.$name.'::'.$valmatch.':'});
                   5904:         } elsif ($value) { 
                   5905:             &Apache::lonnet::update_released_required($Apache::lonnet::needsrelease{'parameter:'.$name.':'.$value.'::'});
                   5906:         }
                   5907:     } elsif ($namematch) {
                   5908:         &Apache::lonnet::update_released_required($Apache::lonnet::needsrelease{'parameter::::'.$namematch});
1.504     raeburn  5909:     }
                   5910:     return $needsnewer;
                   5911: }
                   5912: 
1.560     damieng  5913: ##################################################
                   5914: # HANDLER
                   5915: ##################################################
                   5916: 
                   5917: # Main handler for lonparmset.
                   5918: # Sub called based on request parameters action and command:
                   5919: # no command or action: print_main_menu
                   5920: # command 'set': assessparms (direct access to table mode for a resource)
                   5921: #                (this can also be accessed simply with the symb parameter)
                   5922: # action 'setoverview': overview (display all existing parameter settings)
                   5923: # action 'addmetadata': addmetafield (called to add a portfolio metadata field)
                   5924: # action 'ordermetadata': order_meta_fields (called to order portfolio metadata fields)
                   5925: # action 'setrestrictmeta': setrestrictmeta (display or save portfolio metadata)
                   5926: # action 'newoverview': newoverview (overview mode)
                   5927: # action 'setdefaults': defaultsetter (UI to change parameter setting default actions)
                   5928: # action 'settable': assessparms (table mode)
                   5929: # action 'parameterchangelog': parm_change_log (display log for parameter changes,
                   5930: #                              blog postings, user notification changes)
                   5931: # action 'cleanparameters': clean_parameters (unused)
                   5932: # action 'dateshift1': date_shift_one (overview mode, shift all dates)
                   5933: # action 'dateshift2': date_shift_two (overview mode, shift all dates)
1.30      www      5934: sub handler {
1.43      albertel 5935:     my $r=shift;
1.30      www      5936: 
1.376     albertel 5937:     &reset_caches();
                   5938: 
1.414     droeschl 5939:     &Apache::loncommon::content_type($r,'text/html');
                   5940:     $r->send_http_header;
                   5941:     return OK if $r->header_only;
                   5942: 
1.193     albertel 5943:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.473     amueller 5944:                         ['action','state',
1.205     www      5945:                                              'pres_marker',
                   5946:                                              'pres_value',
1.206     www      5947:                                              'pres_type',
1.506     www      5948:                                              'filter','part',
1.390     www      5949:                                              'udom','uname','symb','serial','timebase']);
1.131     www      5950: 
1.83      bowersj2 5951: 
1.193     albertel 5952:     &Apache::lonhtmlcommon::clear_breadcrumbs();
1.194     albertel 5953:     &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/parmset",
1.507     www      5954:                         text=>"Content and Problem Settings",
1.473     amueller 5955:                         faq=>10,
                   5956:                         bug=>'Instructor Interface',
1.442     droeschl 5957:                                             help =>
                   5958:                                             'Parameter_Manager,Course_Environment,Parameter_Helper,Parameter_Overview,Table_Mode'});
1.203     www      5959: 
1.30      www      5960: # ----------------------------------------------------- Needs to be in a course
1.194     albertel 5961:     my $parm_permission =
1.473     amueller 5962:     (&Apache::lonnet::allowed('opa',$env{'request.course.id'}) ||
                   5963:      &Apache::lonnet::allowed('opa',$env{'request.course.id'}.'/'.
                   5964:                   $env{'request.course.sec'}));
1.355     albertel 5965:     my $exists = &check_for_course_info();
                   5966: 
                   5967:     if ($env{'request.course.id'} &&  $parm_permission && $exists) {
1.193     albertel 5968:         #
                   5969:         # Main switch on form.action and form.state, as appropriate
                   5970:         #
                   5971:         # Check first if coming from someone else headed directly for
                   5972:         #  the table mode
                   5973:         if ((($env{'form.command'} eq 'set') && ($env{'form.url'})
1.560     damieng  5974:                 && (!$env{'form.dis'})) || ($env{'form.symb'})) {
                   5975:             &assessparms($r);
1.193     albertel 5976:         } elsif (! exists($env{'form.action'})) {
                   5977:             &print_main_menu($r,$parm_permission);
1.414     droeschl 5978:         } elsif ($env{'form.action'} eq 'setoverview') {
1.560     damieng  5979:             &overview($r);
                   5980:         } elsif ($env{'form.action'} eq 'addmetadata') {
                   5981:             &addmetafield($r);
                   5982:         } elsif ($env{'form.action'} eq 'ordermetadata') {
                   5983:             &order_meta_fields($r);
1.414     droeschl 5984:         } elsif ($env{'form.action'} eq 'setrestrictmeta') {
1.560     damieng  5985:             &setrestrictmeta($r);
1.414     droeschl 5986:         } elsif ($env{'form.action'} eq 'newoverview') {
1.560     damieng  5987:             &newoverview($r);
1.414     droeschl 5988:         } elsif ($env{'form.action'} eq 'setdefaults') {
1.560     damieng  5989:             &defaultsetter($r);
                   5990:         } elsif ($env{'form.action'} eq 'settable') {
                   5991:             &assessparms($r);
1.414     droeschl 5992:         } elsif ($env{'form.action'} eq 'parameterchangelog') {
1.560     damieng  5993:             &parm_change_log($r);
1.414     droeschl 5994:         } elsif ($env{'form.action'} eq 'cleanparameters') {
1.560     damieng  5995:             &clean_parameters($r);
1.414     droeschl 5996:         } elsif ($env{'form.action'} eq 'dateshift1') {
1.390     www      5997:             &date_shift_one($r);
1.414     droeschl 5998:         } elsif ($env{'form.action'} eq 'dateshift2') {
1.390     www      5999:             &date_shift_two($r);
1.446     bisitz   6000:         }
1.43      albertel 6001:     } else {
1.1       www      6002: # ----------------------------- Not in a course, or not allowed to modify parms
1.560     damieng  6003:         if ($exists) {
                   6004:             $env{'user.error.msg'}=
                   6005:             "/adm/parmset:opa:0:0:Cannot modify assessment parameters";
                   6006:         } else {
                   6007:             $env{'user.error.msg'}=
                   6008:             "/adm/parmset::0:1:Course environment gone, reinitialize the course";
                   6009:         }
                   6010:         return HTTP_NOT_ACCEPTABLE;
1.43      albertel 6011:     }
1.376     albertel 6012:     &reset_caches();
                   6013: 
1.43      albertel 6014:     return OK;
1.1       www      6015: }
                   6016: 
                   6017: 1;
                   6018: __END__
                   6019: 
                   6020: 

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